The selected thread should be getting set. You didn’t include the code for _send_paused_notification so I don’t know what that does, but if SBProcess::GetSelectedThread wasn’t returning a thread with a valid stop reason, then there’s some bug somewhere. That’s all done in generic code, however, so I’m not sure how that would happen.
Jim > On Mar 18, 2016, at 5:23 PM, Jeffrey Tan <jeffrey.fu...@gmail.com> 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 <jing...@apple.com > <mailto:jing...@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.fu...@gmail.com >> <mailto:jeffrey.fu...@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 <jing...@apple.com >> <mailto:jing...@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@lists.llvm.org <mailto:lldb-dev@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.fu...@gmail.com >>> <mailto:jeffrey.fu...@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@lists.llvm.org <mailto:lldb-dev@lists.llvm.org> >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev >>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev> >> >> > >
_______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev