[Lldb-commits] [PATCH] D74398: [lldb-server] jThreadsInfo returns stack memory

Jason Molenda via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Sat Mar 21 22:25:34 PDT 2020


jasonmolenda added a comment.

In D74398#1935431 <https://reviews.llvm.org/D74398#1935431>, @jasonmolenda wrote:

> In D74398#1935043 <https://reviews.llvm.org/D74398#1935043>, @jarin wrote:
>
> > Regarding the packet savings - there are still things that worry me.
> >
> > First of all, when lldb CLI stops on a breakpoint, it will first unwind top of the stack of each thread as part of ThreadList::ShouldStop. This sends lots of "x" packets to lldb-server and only then issues jThreadInfo, which then replies with the stack memory uselessly (with my patch). I am yet to investigate why the CLI does that.
>
>
> I haven't looked into this, but this sound like the difference between a "private stop" and a "public stop".  When you do a source-level "next" command, lldb will put breakpoints on branches/function calls, run to those, then instruction step those instructions, etc.  Each time it stops at these breakpoints or instruction-steps.  Each of these stops are called private stops - the UI layer (lldb command line driver or the SB API driver) never hear about these.  When we've completed executing the instructions for that source line, then we declare this to be a "public stop" - this is when lldb driver or SB API driver, and the user, are notified that execution has stopped.


To give a quick example with some random binary I had sitting around,

  4   	int main()
  5   	{

-> 6   	    std::vector<uint64_t> a;

  7   	    a.push_back (0x0000000100000000);

(lldb) tar mod dump line-table a.cc
Line table for /tmp/a.cc in `a.out
0x0000000100001220: /tmp/a.cc:5
0x000000010000122f: /tmp/a.cc:6:27
0x0000000100001245: /tmp/a.cc:7:18
0x0000000100001251: /tmp/a.cc:7:7

(lldb) dis -s 0x000000010000122f  -e 0x100001245
a.out`main:
->  0x10000122f <+15>: movq   %rax, %rdi

  0x100001232 <+18>: movq   %rax, -0x68(%rbp)
  0x100001236 <+22>: callq  0x100001350               ; std::__1::vector<unsigned long long, std::__1::allocator<unsigned long long> >::vector at vector:497
  0x10000123b <+27>: movabsq $0x100000000, %rax        ; imm = 0x100000000 

(lldb)

this source-level step will take 5 stops.  first go to the CALLQ, then instruction-step in, then set a breakpoint on the return address and continue, then stepi to the first instruction of line 7.  Let's look at what llvm does after it's instruction-stepped into the CALLQ,

<  18> send packet: $Z0,10000123b,1#fc
 <   6> read packet: $OK#00
 <   5> send packet: $c#63
 < 624> read packet: $T05thread:5ada71;threads:5ada71;thread-pcs:10000123b;00:58fabfeffe7f0000;01:0000000000000000;02:80fbbfeffe7f0000;03:90fabfeffe7f0000;04:58fabfeffe7f0000;05:58fabfeffe7f0000;06:60fabfeffe7f0000;07:e0f9bfeffe7f0000;08:0000000000000000;09:0000000000000000;0a:0000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:0000000000000000;10:3b12000001000000;11:0202000000000000;12:2b00000000000000;13:0000000000000000;14:0000000000000000;metype:6;mecount:2;medata:2;medata:0;memory:0x7ffeefbffa60=70fabfeffe7f0000fdd7f765ff7f0000;memory:0x7ffeefbffa70=00000000000000000100000000000000;#00
 <  18> send packet: $z0,10000123b,1#1c
 <   6> read packet: $OK#00
 <  18> send packet: $vCont;s:5ada71#b5
 < 624> read packet: $T05thread:5ada71;threads:5ada71;thread-pcs:100001245;00:0000000001000000;01:0000000000000000;02:80fbbfeffe7f0000;03:90fabfeffe7f0000;04:58fabfeffe7f0000;05:58fabfeffe7f0000;06:60fabfeffe7f0000;07:e0f9bfeffe7f0000;08:0000000000000000;09:0000000000000000;0a:0000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:0000000000000000;10:4512000001000000;11:0202000000000000;12:2b00000000000000;13:0000000000000000;14:0000000000000000;metype:6;mecount:2;medata:1;medata:0;memory:0x7ffeefbffa60=70fabfeffe7f0000fdd7f765ff7f0000;memory:0x7ffeefbffa70=00000000000000000100000000000000;#00
 <  16> send packet: $jThreadsInfo#c1
 < 889> read packet: $[{"tid":5954161,"metype":6,"medata":[1,0],"reason":"exception","qaddr":4295843648,"associated_with_dispatch_queue":true,"dispatch_queue_t":140735606695552,"qname":"com.apple.main-thread","qkind":"serial","qserialnum":1,"registers":{"0":"0000000001000000","1":"0000000000000000","[...]

So we set a breakpoint and continued to it to get out of the function call, then we cleared the breakpoint, stepi'ed to get to the first instruction of line 7 and now we've got a public stop and we issue a jThreadsInfo to get more expensive / exhaustive information about all threads, not just the thread that hit the breakpoint.

You can see debugserver providing enough of the stack memory in the memory: field in the questionmark (T05) packet so that lldb can walk the stack one frame and be sure of where it is.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74398/new/

https://reviews.llvm.org/D74398





More information about the lldb-commits mailing list