[lldb-dev] Weird stop stack while hitting breakpoint

Pavel Labath via lldb-dev lldb-dev at lists.llvm.org
Fri Apr 8 04:32:36 PDT 2016


Ok, so the reason for this behavior seems to be that the process hits
two breakpoints simultaneously:
- the breakpoint you have set and you are expecting to hit
- an internal shared library breakpoint we use to get notified of new
shared libraries

* thread #1: tid = 33390, 0x00007ff7dcd9f970
ld-linux-x86-64.so.2`_dl_debug_state, name = 'a.out', stop reason =
shared-library-event
  * frame #0: 0x00007ff7dcd9f970 ld-linux-x86-64.so.2`_dl_debug_state
    frame #1: 0x00007ff7dcda3b05
ld-linux-x86-64.so.2`___lldb_unnamed_symbol90$$ld-linux-x86-64.so.2 +
357
    frame #2: 0x00007ff7dcd9eff4
ld-linux-x86-64.so.2`___lldb_unnamed_symbol59$$ld-linux-x86-64.so.2 +
116
    frame #3: 0x00007ff7dcda33bb
ld-linux-x86-64.so.2`___lldb_unnamed_symbol88$$ld-linux-x86-64.so.2 +
171
    frame #4: 0x00007ff7dc5de0f2
libc.so.6`do_dlopen(ptr=0x00007ffed953c6f0) + 66 at dl-libc.c:87
    frame #5: 0x00007ff7dcd9eff4
ld-linux-x86-64.so.2`___lldb_unnamed_symbol59$$ld-linux-x86-64.so.2 +
116
    frame #6: 0x00007ff7dc5de1b2 libc.so.6`__GI___libc_dlopen_mode +
47 at dl-libc.c:46
    frame #7: 0x00007ff7dc5de183
libc.so.6`__GI___libc_dlopen_mode(name=<unavailable>,
mode=<unavailable>) + 35 at dl-libc.c:163
    frame #8: 0x00007ff7dc87da43 libpthread.so.0`pthread_cancel_init +
35 at unwind-forcedunwind.c:52
    frame #9: 0x00007ff7dc87dc0c
libpthread.so.0`_Unwind_ForcedUnwind(exc=0x00007ff7dcf8ddf0,
stop=(libpthread.so.0`unwind_stop at unwind.c:44),
stop_argument=0x00007ffed953c7f0) + 60 at unwind-forcedunwind.c:129
    frame #10: 0x00007ff7dc87bd40
libpthread.so.0`__GI___pthread_unwind(buf=<unavailable>) + 64 at
unwind.c:129
    frame #11: 0x00007ff7dc876535 libpthread.so.0`__pthread_exit + 37
at pthreadP.h:280
    frame #12: 0x00007ff7dc87651d
libpthread.so.0`__pthread_exit(value=<unavailable>) + 13 at
pthread_exit.c:29
    frame #13: 0x0000000000400b00 a.out`main + 186
    frame #14: 0x00007ff7dc4c9ec5
libc.so.6`__libc_start_main(main=(a.out`main), argc=1,
argv=0x00007ffed953c8a8, init=<unavailable>, fini=<unavailable>,
rtld_fini=<unavailable>, stack_end=0x00007ffed953c898) + 245 at
libc-start.c:287
    frame #15: 0x0000000000400939 a.out`_start + 41

  thread #2: tid = 35166, 0x00000000004009fd a.out`PrintHello(void*),
name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x00000000004009fd a.out`PrintHello(void*)
    frame #1: 0x00007ff7dc875182
libpthread.so.0`start_thread(arg=0x00007ff7dbf8b700) + 194 at
pthread_create.c:312
    frame #2: 0x00007ff7dc5a247d libc.so.6`__clone + 109 at clone.S:111


These internal breakpoints are normally ignored, but I can certainly
imagine that if you hit them concurrently with a regular breakpoint,
the thread-selecting machinery will get confused. I don't have time to
look into this more right now, but I'll get to it eventually if
someone doesn't beat me to it...


PS: Your inferior is quite strange. I am not sure you are allowed to
exit the main thread via pthread_exit(), especially when you still
have non-detached threads running...

pl


On 21 March 2016 at 05:03, Jeffrey Tan <jeffrey.fudan at gmail.com> wrote:
> Thanks guys. I tried our IDE against a sample multithreading program on Mac,
> it correctly switches selected thread to the worker thread that triggers
> breakpoint, while on Linux(CentOS release 6.7) it failed to do that. Repro
> code:
>
> =========================Output=========================
> Launch result: success
> <Listener> Listening Thread ID: 139749072582400
> running_signal wait
> stopped_signal wait
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Target event: ModulesLoaded
> Non stopping event: <lldb.SBEvent; proxy of <Swig Object of type
> 'lldb::SBEvent *' at 0x7f19e0975990> >
> Process event: StateChanged, Running
> Stop reason: 1
> Process event: Stdout, Running
> Stop reason: 1
> Stdout:
> main() : creating thread, 0
> Process event: StateChanged, Stopped
> after wait_for_process_run_then_stop
> frame #0: 0x00007fcb7259ceb0 ld-linux-x86-64.so.2`__GI__dl_debug_state
> frame #1: 0x00007fcb725a0c53 ld-linux-x86-64.so.2`dl_open_worker + 499
> frame #2: 0x00007fcb7259c286 ld-linux-x86-64.so.2`_dl_catch_error + 102
> frame #3: 0x00007fcb725a063a ld-linux-x86-64.so.2`_dl_open + 186
> frame #4: 0x00007fcb71963c60 libc.so.6`do_dlopen + 64
> frame #5: 0x00007fcb7259c286 ld-linux-x86-64.so.2`_dl_catch_error + 102
> frame #6: 0x00007fcb71963db7 libc.so.6`__GI___libc_dlopen_mode + 71
> frame #7: 0x00007fcb71be0eec libpthread.so.0`pthread_cancel_init + 76
> frame #8: 0x00007fcb71be104c libpthread.so.0`_Unwind_ForcedUnwind + 60
> frame #9: 0x00007fcb71bdef60 libpthread.so.0`__GI___pthread_unwind + 64
> frame #10: 0x00007fcb71bd9175 libpthread.so.0`__pthread_exit + 37
> frame #11: 0x0000000000400ac0 threads`main + 195 at threads.cpp:31
> frame #12: 0x00007fcb7185bd5d libc.so.6`__libc_start_main + 253
> frame #13: 0x00000000004008f9 threads
> <Listener> Exiting listener thread
>
> =========================Inferior=========================
> #include <iostream>
> #include <cstdlib>
> #include <pthread.h>
>
> using namespace std;
>
> #define NUM_THREADS     1
>
> void *PrintHello(void *threadid)
> {
>    long tid;
>    tid = (long)threadid;
>    cout << "Hello World! Thread ID, " << tid << endl;
>    pthread_exit(NULL);
> }
>
> int main ()
> {
>    pthread_t threads[NUM_THREADS];
>    int rc;
>    int i;
>    for( i=0; i < NUM_THREADS; i++ ){
>       cout << "main() : creating thread, " << i << endl;
>       rc = pthread_create(&threads[i], NULL,
>                           PrintHello, (void *)i);
>       if (rc){
>          cout << "Error:unable to create thread," << rc << endl;
>          exit(-1);
>       }
>    }
>    pthread_exit(NULL);
> }
>
> =========================LLDB python automation
> code=========================
> main.py
>
> # Should be first for LLDB package to be added to search path.
> from find_lldb import lldb
> import sys
> import os
> import time
> from sys import stdin, stdout
> from event_thread import LLDBListenerThread
> import threading
>
> def wait_for_process_run_then_stop(running_signal, stopped_signal):
>     print 'running_signal wait'
>     running_signal.wait()
>     running_signal.clear()
>     print 'stopped_signal wait'
>     stopped_signal.wait()
>     stopped_signal.clear()
>
> def do_test():
>     debugger = lldb.SBDebugger.Create()
>     debugger.SetAsync(True)
>     executable_path = '~/personal/cpp/temp/threads'
>     target = debugger.CreateTargetWithFileAndArch(executable_path,
> lldb.LLDB_ARCH_DEFAULT)
>     target.BreakpointCreateByName('PrintHello')
>
>     listener = lldb.SBListener('Event Listener')
>     error = lldb.SBError()
>     process = target.Launch (listener,
>                              None,      # argv
>                              None,      # envp
>                              None,      # stdin_path
>                              None,      # stdout_path
>                              None,      # stderr_path
>                              None,      # working directory
>                              0,         # launch flags
>                              False,     # Stop at entry
>                              error)     # error
>     print 'Launch result: %s' % str(error)
>
>     running_signal = threading.Event()
>     stopped_signal = threading.Event()
>     running_signal.set()
>     event_thread = LLDBListenerThread(debugger, running_signal,
> stopped_signal)
>     event_thread.start()
>
>     wait_for_process_run_then_stop(running_signal, stopped_signal)
>
>     print 'after wait_for_process_run_then_stop'
>     activeThread = process.GetSelectedThread()
>     for frame in activeThread.frames:
>         print frame
>
>     event_thread.should_quit = True
>     event_thread.join()
>
>     lldb.SBDebugger.Destroy(debugger)
>     return debugger
>
> def main():
>     debugger = do_test()
>
> if __name__ == '__main__':
>     main()
>
>
> ===========event_thread.py============
>
> import lldb
> from threading import Thread
> from sys import stdout
> import thread
> import threading
>
> target_event_type_to_name_map = {
>     lldb.SBTarget.eBroadcastBitBreakpointChanged: 'BreakpointChanged',
>     lldb.SBTarget.eBroadcastBitWatchpointChanged: 'WatchpointChanged',
>     lldb.SBTarget.eBroadcastBitModulesLoaded: 'ModulesLoaded',
>     lldb.SBTarget.eBroadcastBitModulesUnloaded: 'ModulesUnloaded',
>     lldb.SBTarget.eBroadcastBitSymbolsLoaded: 'SymbolsLoaded',
> }
>
> process_event_type_to_name_map = {
>     lldb.SBProcess.eBroadcastBitStateChanged: 'StateChanged',
>     lldb.SBProcess.eBroadcastBitSTDOUT: 'Stdout',
>     lldb.SBProcess.eBroadcastBitSTDERR: 'Stderr',
>     lldb.SBProcess.eBroadcastBitInterrupt: 'Interupt',
> }
>
> breakpoint_event_type_to_name_map = {
>     lldb.eBreakpointEventTypeAdded: 'Added',
>     lldb.eBreakpointEventTypeCommandChanged: 'Command Changed',
>     lldb.eBreakpointEventTypeConditionChanged: 'Condition Changed',
>     lldb.eBreakpointEventTypeDisabled: 'Disabled',
>     lldb.eBreakpointEventTypeEnabled: 'Enabled',
>     lldb.eBreakpointEventTypeIgnoreChanged: 'Ignore Changed',
>     lldb.eBreakpointEventTypeInvalidType: 'Invalid Type',
>     lldb.eBreakpointEventTypeLocationsAdded: 'Location Added',
>     lldb.eBreakpointEventTypeLocationsRemoved: 'Location Removed',
>     lldb.eBreakpointEventTypeLocationsResolved: 'Location Resolved',
>     lldb.eBreakpointEventTypeRemoved: 'Removed',
>     lldb.eBreakpointEventTypeThreadChanged: 'Thread Changed',
> }
>
> process_state_name_map = {
>     lldb.eStateRunning: 'Running',
>     lldb.eStateStepping: 'Stepping',
>     lldb.eStateAttaching: 'Attaching',
>     lldb.eStateConnected: 'Connected',
>     lldb.eStateCrashed: 'Crashed',
>     lldb.eStateDetached: 'Detached',
>     lldb.eStateExited: 'Exited',
>     lldb.eStateInvalid: 'Invalid',
>     lldb.eStateLaunching: 'Launching',
>     lldb.eStateStopped: 'Stopped',
>     lldb.eStateSuspended: 'Suspended',
>     lldb.eStateUnloaded: 'Unloaded',
> }
>
>
> class LLDBListenerThread(Thread):
>     should_quit = False
>
>     def __init__(self, debugger, running_signal=None, stopped_sigal=None):
>       Thread.__init__(self)
>       self._running_signal = running_signal
>       self._stopped_sigal = stopped_sigal
>       process = debugger.GetSelectedTarget().process
>       self.listener = debugger.GetListener()
>       self._add_listener_to_process(process)
>       self._add_listener_to_target(process.target)
>
>       '''self.listener.StartListeningForEventClass(debugger,
> lldb.SBTarget.GetBroadcasterClassName(),
>         lldb.SBTarget.eBroadcastBitBreakpointChanged |
>         lldb.SBTarget.eBroadcastBitWatchpointChanged |
>         lldb.SBTarget.eBroadcastBitModulesLoaded |
>         lldb.SBTarget.eBroadcastBitModulesUnloaded |
>         lldb.SBTarget.eBroadcastBitSymbolsLoaded)
>       self.listener.StartListeningForEventClass(debugger,
> lldb.SBProcess.GetBroadcasterClassName(),
>         lldb.SBProcess.eBroadcastBitStateChanged |
>         lldb.SBProcess.eBroadcastBitSTDOUT |
>         lldb.SBProcess.eBroadcastBitSTDERR |
>         lldb.SBProcess.eBroadcastBitInterrupt)'''
>       '''self.listener.StartListeningForEventClass(debugger,
> lldb.SBThread.GetBroadcasterClassName(),
>         lldb.SBThread.eBroadcastBitStackChanged |
> lldb.SBThread.eBroadcastBitThreadSuspended |
>         lldb.SBThread.eBroadcastBitThreadResumed |
> lldb.SBThread.eBroadcastBitSelectedFrameChanged |
> lldb.SBThread.eBroadcastBitThreadSelected)'''
>
>     def _add_listener_to_target(self, target):
>         # Listen for breakpoint/watchpoint events
> (Added/Removed/Disabled/etc).
>         broadcaster = target.GetBroadcaster()
>         mask = lldb.SBTarget.eBroadcastBitBreakpointChanged |
> lldb.SBTarget.eBroadcastBitWatchpointChanged |
> lldb.SBTarget.eBroadcastBitModulesLoaded
>         broadcaster.AddListener(self.listener, mask)
>
>     def _add_listener_to_process(self, process):
>         # Listen for process events (Start/Stop/Interrupt/etc).
>         broadcaster = process.GetBroadcaster()
>         mask = lldb.SBProcess.eBroadcastBitStateChanged |
> lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR |
> lldb.SBProcess.eBroadcastBitInterrupt
>         broadcaster.AddListener(self.listener, mask)
>
>     def run(self):
>         print '<Listener> Listening Thread ID: %d' % thread.get_ident()
>         while not self.should_quit:
>             event = lldb.SBEvent()
>             if self.listener.WaitForEvent(1, event):
>                 if lldb.SBTarget.EventIsTargetEvent(event):
>                     self._handle_target_event(event)
>                 elif lldb.SBProcess.EventIsProcessEvent(event):
>                     self._handle_process_event(event)
>                 elif lldb.SBBreakpoint.EventIsBreakpointEvent(event):
>                     self._handle_breakpoint_event(event)
>                 elif lldb.SBThread.EventIsThreadEvent(event):
>                     self._handle_thread_event(event)
>                 else:
>                     self._handle_unknown_event(event)
>         print '<Listener> Exiting listener thread'
>
>     def _handle_target_event(self, event):
>         event_type = event.GetType()
>         print 'Target event: %s' % target_event_type_to_name_map[event_type]
>
>     def _handle_process_event(self, event):
>         if lldb.SBProcess.GetRestartedFromEvent(event):
>             print 'Non stopping event: %s' % str(event)
>             return
>         process = lldb.SBProcess.GetProcessFromEvent(event)
>         event_type = event.GetType()
>         print 'Process event: %s, %s' %
> (process_event_type_to_name_map[event_type],
> process_state_name_map[process.state])
>         if process.state == lldb.eStateExited:
>             self.should_quit = True
>         elif process.state == lldb.eStateStopped:
>             if self._stopped_sigal:
>                 self._stopped_sigal.set()
>         else:
>             if self._running_signal:
>                 self._running_signal.set()
>
>         thread = process.selected_thread
>         print 'Stop reason: %d' % thread.GetStopReason()
>         if event_type == lldb.SBProcess.eBroadcastBitSTDOUT:
>             print 'Stdout:'
>             while True:
>                 output = process.GetSTDOUT(1024)
>                 if output is None or len(output) == 0:
>                     break
>                 stdout.write(output)
>
>     def _handle_breakpoint_event(self, event):
>         breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
>         event_type =
> lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event)
>         print 'Breakpoint event: [%s] %s ' % (
>             breakpoint_event_type_to_name_map[event_type],
>             self._get_description_from_object(breakpoint))
>
>     def _handle_unknown_event(self, event):
>         print('Unknown event: %d %s %s' % (
>             event.GetType(),
>             lldb.SBEvent.GetCStringFromEvent(event),
>             self._get_description_from_object(event)))
>
>     def _get_description_from_object(self, lldb_object):
>         description_stream = lldb.SBStream()
>         lldb_object.GetDescription(description_stream)
>         return description_stream.GetData()
>
>
>
>
>
> On Sun, Mar 20, 2016 at 7:10 AM, Pavel Labath <labath at google.com> wrote:
>>
>> If you send me a small repro case, I can try to look at why is Linux
>> different here.
>>
>> On 19 March 2016 at 00:46, Jim Ingham via lldb-dev
>> <lldb-dev at lists.llvm.org> wrote:
>> > All this logic is handled in Process::HandleProcessStateChangedEvent
>> > (see around line 1215 in Process.cpp)  You shouldn’t have to reimplement the
>> > logic for setting the selected thread unless you don’t like our heuristics.
>> > Note, that’s in generic code, so I don’t know why it wouldn’t be working
>> > right on Linux.
>> >
>> > Jim
>> >
>> >> On Mar 18, 2016, at 5:38 PM, Greg Clayton <gclayton at apple.com> wrote:
>> >>
>> >> It is really up to the IDE to decide this so the logic belongs in your
>> >> IDE. We do things as follows:
>> >>
>> >> If no thread was selected before, display the first thread that has a
>> >> stop reason other than none. If no threads have stop reasons, select the
>> >> first thread. If a thread was selected before, then see if that same thread
>> >> is stopped with a reason the next time you stop and select that one,
>> >> regardless if it is the first thread with a stop reason. The idea is, if you
>> >> were stepping or doing something in a thread, and then stop again, you don't
>> >> want the IDE changing away from your current thread if this thread has a
>> >> stop reason. If this thread doesn't have a stop reason, then select the
>> >> first one that does. If not threads have stop reasons, then display the same
>> >> thread as before.
>> >>
>> >>> On Mar 18, 2016, at 5:23 PM, Jeffrey Tan via lldb-dev
>> >>> <lldb-dev at lists.llvm.org> wrote:
>> >>>
>> >>> Thanks for the info. I understand the multiple threads stopping at the
>> >>> same time issue. But I would think we should at least pick one stopped
>> >>> thread and set it as selected thread instead of some random thread with stop
>> >>> reason None. Also, in my repro case, there is only one thread that has stop
>> >>> reason, so the heuristics should be pretty trivial to set selected thread to
>> >>> that one.
>> >>> I have workaround this issue with the suggestion but I think there is
>> >>> a bug(on Linux) here.
>> >>>
>> >>> On Fri, Mar 18, 2016 at 4:40 PM, Jim Ingham <jingham at apple.com> wrote:
>> >>> On many platforms (OS X for sure) there’s no guarantee that when you
>> >>> stop you will only have hit one breakpoint on one thread.  On OS X in
>> >>> multithreaded programs, it is not at all uncommon to have many threads hit
>> >>> breakpoint(s) by the the time the stop gets reported.  So you just have to
>> >>> iterate over all the threads and see what their stop reasons are.  Note that
>> >>> it isn’t just breakpoints, you might have been stepping on thread A, and
>> >>> when you stop, thread A will have stopped with “plan complete” for the step
>> >>> operation, and thread B for some other breakpoint.
>> >>>
>> >>> So when you get a stop event you have to iterate over the threads and
>> >>> see why they have stopped.
>> >>>
>> >>> LLDB will set one of the threads as the selected thread, using some
>> >>> heuristics (if you were stepping on thread A & threads A & B stopped with
>> >>> breakpoints, thread A will be the selected thread, etc…)  So you could just
>> >>> show the selected thread, but really you want to figure out what all the
>> >>> threads are doing.
>> >>>
>> >>> Jim
>> >>>
>> >>>> On Mar 18, 2016, at 4:25 PM, Jeffrey Tan <jeffrey.fudan at gmail.com>
>> >>>> wrote:
>> >>>>
>> >>>>
>> >>>> Hmm, interesting, I got the stop reason from the
>> >>>> lldb.SBProcess.GetProcessFromEvent(event).GetSelectedThread().GetStopReason().
>> >>>> Is that thread not the one that stopped? But you are right, the breakpoint
>> >>>> hits in another thread:
>> >>>>
>> >>>> thread #87: tid = 1006769, 0x000000000042eacd
>> >>>> biggrep_master_server_async`facebook::biggrep::BigGrepMasterAsync::future_find(this=0x00007f3ea2d74fd0,
>> >>>> corpus=error: summary string parsing error, needle=error: summary string
>> >>>> parsing error, options=0x00007f3e899fc7e0) + 51 at
>> >>>> BigGrepMasterAsync.cpp:171, name = 'BigGrep-pri3-32', stop reason =
>> >>>> breakpoint 1.1
>> >>>>
>> >>>> How do I know which thread hits the breakpoint?
>> >>>>
>> >>>> Jeffrey
>> >>>>
>> >>>>
>> >>>> On Fri, Mar 18, 2016 at 4:12 PM, Jim Ingham <jingham at apple.com>
>> >>>> wrote:
>> >>>> You only show one thread in your example.  Did another thread have a
>> >>>> valid stop reason?  lldb shouldn’t be stopping for no reason anywhere…
>> >>>>
>> >>>> Jim
>> >>>>
>> >>>>> On Mar 18, 2016, at 4:08 PM, Jeffrey Tan via lldb-dev
>> >>>>> <lldb-dev at lists.llvm.org> wrote:
>> >>>>>
>> >>>>> Btw: the breakpoint I set is:
>> >>>>> "b BigGrepMasterAsync.cpp:171" which is not in any of the stopped
>> >>>>> stack frames.
>> >>>>>
>> >>>>> On Fri, Mar 18, 2016 at 3:47 PM, Jeffrey Tan
>> >>>>> <jeffrey.fudan at gmail.com> wrote:
>> >>>>> Hi,
>> >>>>>
>> >>>>> Our IDE(wrapping lldb using python) works fine on Linux for simple
>> >>>>> hello world cases. While trying a real world case, I found whenever we set a
>> >>>>> source line breakpoint, then trigger the code path, lldb will send a stopped
>> >>>>> state process event, with thread.GetStopReason() being None and with weird
>> >>>>> callstack. Any ideas why do I get this stop stack(code is listed at the
>> >>>>> end)? I have verified that if I do not set breakpoint and trigger the same
>> >>>>> code path does not cause this stop event to generate.
>> >>>>>
>> >>>>> bt
>> >>>>> * thread #1: tid = 952490, 0x00007fd7cb2daa83
>> >>>>> libc.so.6`__GI_epoll_wait + 51, name = 'biggrep_master_'
>> >>>>>  * frame #0: 0x00007fd7cb2daa83 libc.so.6`__GI_epoll_wait + 51
>> >>>>>    frame #1: 0x000000000271189f
>> >>>>> biggrep_master_server_async`epoll_dispatch(base=0x00007fd7ca970800,
>> >>>>> arg=0x00007fd7ca62c1e0, tv=<unavailable>) + 127 at epoll.c:315
>> >>>>>    frame #2: 0x000000000270f6d1
>> >>>>> biggrep_master_server_async`event_base_loop(base=0x00007fd7ca970800,
>> >>>>> flags=<unavailable>) + 225 at event.c:524
>> >>>>>    frame #3: 0x00000000025f9378
>> >>>>> biggrep_master_server_async`folly::EventBase::loopBody(this=0x00007fd7ca945180,
>> >>>>> flags=0) + 834 at EventBase.cpp:335
>> >>>>>    frame #4: 0x00000000025f900b
>> >>>>> biggrep_master_server_async`folly::EventBase::loop(this=0x00007fd7ca945180)
>> >>>>> + 29 at EventBase.cpp:287
>> >>>>>    frame #5: 0x00000000025fa053
>> >>>>> biggrep_master_server_async`folly::EventBase::loopForever(this=0x00007fd7ca945180)
>> >>>>> + 109 at EventBase.cpp:435
>> >>>>>    frame #6: 0x0000000001e24b72
>> >>>>> biggrep_master_server_async`apache::thrift::ThriftServer::serve(this=0x00007fd7ca96d710)
>> >>>>> + 110 at ThriftServer.cpp:365
>> >>>>>    frame #7: 0x00000000004906bc
>> >>>>> biggrep_master_server_async`facebook::services::ServiceFramework::startFramework(this=0x00007ffc06776140,
>> >>>>> waitUntilStop=true) + 1942 at ServiceFramework.cpp:885
>> >>>>>    frame #8: 0x000000000048fe6d
>> >>>>> biggrep_master_server_async`facebook::services::ServiceFramework::go(this=0x00007ffc06776140,
>> >>>>> waitUntilStop=true) + 35 at ServiceFramework.cpp:775
>> >>>>>    frame #9: 0x00000000004219a7
>> >>>>> biggrep_master_server_async`main(argc=1, argv=0x00007ffc067769d8) + 2306 at
>> >>>>> BigGrepMasterServerAsync.cpp:134
>> >>>>>    frame #10: 0x00007fd7cb1ed0f6 libc.so.6`__libc_start_main + 246
>> >>>>>    frame #11: 0x0000000000420bfc biggrep_master_server_async`_start
>> >>>>> + 41 at start.S:122
>> >>>>>
>> >>>>> Here is the code snippet of handling code:
>> >>>>> def _handle_process_event(self, event):
>> >>>>>        # Ignore non-stopping events.
>> >>>>>        if lldb.SBProcess.GetRestartedFromEvent(event):
>> >>>>>            log_debug('Non stopping event: %s' % str(event))
>> >>>>>            return
>> >>>>>
>> >>>>>        process = lldb.SBProcess.GetProcessFromEvent(event)
>> >>>>>        if process.state == lldb.eStateStopped:
>> >>>>>            self._send_paused_notification(process)
>> >>>>>        elif process.state == lldb.eStateExited:
>> >>>>>            exit_message = 'Process(%d) exited with: %u' % (
>> >>>>>                    process.GetProcessID(),
>> >>>>>                    process.GetExitStatus())
>> >>>>>            if process.GetExitDescription():
>> >>>>>                exit_message += (', ' + process.GetExitDescription())
>> >>>>>            self._send_user_output('log', exit_message)
>> >>>>>            self.should_quit = True
>> >>>>>        else:
>> >>>>>            self._send_notification('Debugger.resumed', None)
>> >>>>>
>> >>>>>        event_type = event.GetType()
>> >>>>>        if event_type == lldb.SBProcess.eBroadcastBitSTDOUT:
>> >>>>>            # Read stdout from inferior.
>> >>>>>            process_output = ''
>> >>>>>            while True:
>> >>>>>                output_part = process.GetSTDOUT(1024)
>> >>>>>                if not output_part or len(output_part) == 0:
>> >>>>>                    break
>> >>>>>                process_output += output_part
>> >>>>>            self._send_user_output('log', process_output)
>> >>>>>
>> >>>>> _______________________________________________
>> >>>>> lldb-dev mailing list
>> >>>>> lldb-dev at lists.llvm.org
>> >>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>> >>>>
>> >>>>
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> lldb-dev mailing list
>> >>> lldb-dev at lists.llvm.org
>> >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>> >>
>> >
>> > _______________________________________________
>> > lldb-dev mailing list
>> > lldb-dev at lists.llvm.org
>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>
>


More information about the lldb-dev mailing list