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@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 <gclay...@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@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 <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> 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> 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> 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> 
>>>>> 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
>>>>> 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
>>
>
> _______________________________________________
> lldb-dev mailing list
> lldb-dev@lists.llvm.org
> 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

Reply via email to