Ticket #9221: 0001-Fix-9221.patch

File 0001-Fix-9221.patch, 5.3 KB (added by anevilyak, 7 years ago)
  • src/apps/debugger/controllers/TeamDebugger.cpp

    From 25c2d5616eb5065a69043bbf3e78817f6870a15f Mon Sep 17 00:00:00 2001
    From: Rene Gollent <anevilyak@gmail.com>
    Date: Wed, 28 Nov 2012 19:11:50 -0500
    Subject: [PATCH] Fix #9221.
    
    - When an image creation notification is received, the thread
      that provoked it needs to be suspended until the debugger has
      finished loading the image's debug information. Otherwise, if that
      image had a breakpoint in it, it was possible that the thread would
      execute past the code where the breakpoint should be before the
      debugger had a chance to actually install it.
    
    - Only update breakpoints when debug info loading has actually finished.
    ---
     src/apps/debugger/controllers/TeamDebugger.cpp |  106 +++++++++++++++++++++++-
     src/apps/debugger/controllers/TeamDebugger.h   |    7 ++
     2 files changed, 110 insertions(+), 3 deletions(-)
    
    diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp
    index 923f3d3..6d84455 100644
    a b struct TeamDebugger::ImageHandlerHashDefinition { 
    130130};
    131131
    132132
     133// #pragma mark - ImageInfoPendingThread
     134
     135
     136struct TeamDebugger::ImageInfoPendingThread {
     137public:
     138    ImageInfoPendingThread(image_id image, thread_id thread)
     139        :
     140        fImage(image),
     141        fThread(thread)
     142    {
     143    }
     144
     145    ~ImageInfoPendingThread()
     146    {
     147    }
     148
     149    image_id ImageID() const
     150    {
     151        return fImage;
     152    }
     153
     154    thread_id ThreadID() const
     155    {
     156        return fThread;
     157    }
     158
     159private:
     160    image_id        fImage;
     161    thread_id       fThread;
     162
     163public:
     164    ImageInfoPendingThread*
     165                    fNext;
     166};
     167
     168
     169// #pragma mark - ImageHandlerHashDefinition
     170
     171
     172struct TeamDebugger::ImageInfoPendingThreadHashDefinition {
     173    typedef image_id        KeyType;
     174    typedef ImageInfoPendingThread
     175                            ValueType;
     176
     177    size_t HashKey(image_id key) const
     178    {
     179        return (size_t)key;
     180    }
     181
     182    size_t Hash(const ImageInfoPendingThread* value) const
     183    {
     184        return HashKey(value->ImageID());
     185    }
     186
     187    bool Compare(image_id key, const ImageInfoPendingThread* value) const
     188    {
     189        return value->ImageID() == key;
     190    }
     191
     192    ImageInfoPendingThread*& GetLink(ImageInfoPendingThread* value) const
     193    {
     194        return value->fNext;
     195    }
     196};
     197
     198
    133199// #pragma mark - TeamDebugger
    134200
    135201
    TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface, 
    142208    fTeam(NULL),
    143209    fTeamID(-1),
    144210    fImageHandlers(NULL),
     211    fImageInfoPendingThreads(NULL),
    145212    fDebuggerInterface(NULL),
    146213    fFileManager(NULL),
    147214    fWorker(NULL),
    TeamDebugger::~TeamDebugger() 
    204271
    205272    delete fImageHandlers;
    206273
     274    if (fImageInfoPendingThreads != NULL) {
     275        ImageInfoPendingThread* thread = fImageInfoPendingThreads->Clear(true);
     276        while (thread != NULL) {
     277            ImageInfoPendingThread* next = thread->fNext;
     278            delete thread;
     279            thread = next;
     280        }
     281    }
     282    delete fImageInfoPendingThreads;
     283
    207284    delete fBreakpointManager;
    208285    delete fWatchpointManager;
    209286    delete fMemoryBlockManager;
    TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) 
    295372    if (error != B_OK)
    296373        return error;
    297374
     375    fImageInfoPendingThreads = new(std::nothrow) ImageInfoPendingThreadTable;
     376    if (fImageInfoPendingThreads == NULL)
     377        return B_NO_MEMORY;
     378
    298379    // create our worker
    299380    fWorker = new(std::nothrow) Worker;
    300381    if (fWorker == NULL)
    TeamDebugger::_HandleImageCreated(ImageCreatedEvent* event) 
    12091290{
    12101291    AutoLocker< ::Team> locker(fTeam);
    12111292    _AddImage(event->GetImageInfo());
    1212     return false;
     1293
     1294    ImageInfoPendingThread* info = new(std::nothrow) ImageInfoPendingThread(
     1295        event->GetImageInfo().ImageID(), event->Thread());
     1296    if (info == NULL)
     1297        return false;
     1298
     1299    fImageInfoPendingThreads->Insert(info);
     1300    return true;
    12131301}
    12141302
    12151303
    TeamDebugger::_HandleImageDebugInfoChanged(image_id imageID) 
    12491337
    12501338    locker.Unlock();
    12511339
    1252     // update breakpoints in the image
    1253     fBreakpointManager->UpdateImageBreakpoints(image);
     1340    image_debug_info_state state = image->ImageDebugInfoState();
     1341    if (state == IMAGE_DEBUG_INFO_LOADED
     1342        || state == IMAGE_DEBUG_INFO_UNAVAILABLE) {
     1343        // update breakpoints in the image
     1344        fBreakpointManager->UpdateImageBreakpoints(image);
     1345
     1346        ImageInfoPendingThread* thread =  fImageInfoPendingThreads
     1347            ->Lookup(imageID);
     1348        if (thread != NULL) {
     1349            fDebuggerInterface->ContinueThread(thread->ThreadID());
     1350            fImageInfoPendingThreads->Remove(thread);
     1351            delete thread;
     1352        }
     1353    }
    12541354}
    12551355
    12561356
  • src/apps/debugger/controllers/TeamDebugger.h

    diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h
    index 378038b..a605718 100644
    a b private: 
    103103private:
    104104    struct ImageHandler;
    105105    struct ImageHandlerHashDefinition;
     106    struct ImageInfoPendingThread;
     107    struct ImageInfoPendingThreadHashDefinition;
     108
    106109    typedef BOpenHashTable<ImageHandlerHashDefinition> ImageHandlerTable;
     110    typedef BOpenHashTable<ImageInfoPendingThreadHashDefinition>
     111        ImageInfoPendingThreadTable;
    107112
    108113private:
    109114    static  status_t            _DebugEventListenerEntry(void* data);
    private: 
    166171            ThreadHandlerTable  fThreadHandlers;
    167172                                    // protected by the team lock
    168173            ImageHandlerTable*  fImageHandlers;
     174            ImageInfoPendingThreadTable*
     175                                fImageInfoPendingThreads;
    169176            DebuggerInterface*  fDebuggerInterface;
    170177            TeamDebugInfo*      fTeamDebugInfo;
    171178            FileManager*        fFileManager;