diff options
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 91 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 13 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadList.cpp | 18 | 
3 files changed, 121 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 26aa4564281..f0087ec4200 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -119,7 +119,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :      m_packet_timeout (1),      m_max_memory_size (512),      m_waiting_for_attach (false), -    m_local_debugserver (true) +    m_local_debugserver (true), +    m_thread_observation_bps()  {  } @@ -2279,3 +2280,91 @@ ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &match      }  } + +bool +ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton, +                             lldb_private::StoppointCallbackContext *context, +                             lldb::user_id_t break_id, +                             lldb::user_id_t break_loc_id) +{ +    // I don't think I have to do anything here, just make sure I notice the new thread when it starts to  +    // run so I can stop it if that's what I want to do. +    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); +    if (log) +        log->Printf("Hit New Thread Notification breakpoint."); +    return false; +} + + +bool +ProcessGDBRemote::StartNoticingNewThreads() +{ +    static const char *bp_names[] = +    { +        "start_wqthread", +        "_pthread_start", +        NULL +    }; +     +    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); +    size_t num_bps = m_thread_observation_bps.size(); +    if (num_bps != 0) +    { +        for (int i = 0; i < num_bps; i++) +        { +            lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]); +            if (break_sp) +            { +                if (log) +                    log->Printf("Enabled noticing new thread breakpoint."); +                break_sp->SetEnabled(true); +            } +        } +    } +    else  +    { +        for (int i = 0; bp_names[i] != NULL; i++) +        { +            Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, bp_names[i], eFunctionNameTypeFull, true).get(); +            if (breakpoint) +            { +                if (log) +                     log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]); +                m_thread_observation_bps.push_back(breakpoint->GetID()); +                breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true); +            } +            else +            { +                if (log) +                    log->Printf("Failed to create new thread notification breakpoint."); +                return false; +            } +        } +    } + +    return true; +} + +bool +ProcessGDBRemote::StopNoticingNewThreads() +{    +    size_t num_bps = m_thread_observation_bps.size(); +    if (num_bps != 0) +    { +        for (int i = 0; i < num_bps; i++) +        { +            LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); +             +            lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]); +            if (break_sp) +            { +                if (log) +                    log->Printf ("Disabling new thread notification breakpoint."); +                break_sp->SetEnabled(false); +            } +        } +    } +    return true; +} +     + diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 74905d0e646..ebb4cca23d4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -216,6 +216,12 @@ public:      virtual lldb_private::DynamicLoader *      GetDynamicLoader (); +     +    virtual bool +    StartNoticingNewThreads();     + +    virtual bool +    StopNoticingNewThreads();      protected:      friend class ThreadGDBRemote; @@ -336,6 +342,7 @@ protected:      size_t m_max_memory_size;       // The maximum number of bytes to read/write when reading and writing memory      bool m_waiting_for_attach;      bool m_local_debugserver;  // Is the debugserver process we are talking to local or on another machine. +    std::vector<lldb::user_id_t>  m_thread_observation_bps;      void      ResetGDBRemoteState (); @@ -379,6 +386,12 @@ private:      //------------------------------------------------------------------      // For ProcessGDBRemote only      //------------------------------------------------------------------ +    static bool +    NewThreadNotifyBreakpointHit (void *baton, +                         lldb_private::StoppointCallbackContext *context, +                         lldb::user_id_t break_id, +                         lldb::user_id_t break_loc_id); +      DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);  }; diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index e5056326b1c..fa1758b54da 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -352,6 +352,10 @@ ThreadList::RefreshStateAfterStop ()      Mutex::Locker locker(m_threads_mutex);      m_process->UpdateThreadListIfNeeded(); +     +    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); +    if (log) +        log->Printf ("Turning off notification of new threads while single stepping a thread.");      collection::iterator pos, end = m_threads.end();      for (pos = m_threads.begin(); pos != end; ++pos) @@ -403,6 +407,20 @@ ThreadList::WillResume ()          }      }    +    if (wants_solo_run) +    { +        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); +        if (log) +            log->Printf ("Turning on notification of new threads while single stepping a thread."); +        m_process->StartNoticingNewThreads(); +    } +    else +    { +        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); +        if (log) +            log->Printf ("Turning off notification of new threads while single stepping a thread."); +        m_process->StopNoticingNewThreads(); +    }      // Give all the threads that are likely to run a last chance to set up their state before we      // negotiate who is actually going to get a chance to run...  | 

