[lldb-dev] LLDB use of G/g packets

Greg Clayton gclayton at apple.com
Tue Feb 12 09:58:53 PST 2013


On Feb 12, 2013, at 7:19 AM, Benjamin Kemper <kemperbenny at gmail.com> wrote:

> Greg,
> 
> First of all thanks for the highly informative answers!
> 
> Regarding the 'kill' command that was sent, I have no idea also why it happend, but somewhere during the work day (after a few hours of going through LLDB code) it stopped happening... 
> 
> So now LLDB reads all the register values correctly using the `p packets, and regarding the expedited registers I believe I already pass them with the stop reply, see example:
> <lldb.process.gdb-remote.async> <  78> read packet: $T0b06:cce2f16cff7f0000;07:28df8e52ff7f0000;10:0000000000000000;thread:707;#15
> 
> I hoped that once LLDB will get all the registers it will be able to construct the stack frame but it fails to do so. I thought maybe I'm missing the qShlibInfoAddr so I implemented it also but that didn't help also. 

Have you implemented the qHostInfo packet?

send packet: $qHostInfo#00
read packet: $cputype:16777223;cpusubtype:3;ostype:macosx;watchpoint_exceptions_received:after;vendor:apple;endian:little;ptrsize:8;#00

Maybe we just don't know the target triple (specified by "ostype", "vendor" and here the cpu type + subtype) that we are debugging? You can get around this by specifying a full triple when you make your target:

(lldb) target create --arch x86_64-apple-macosx <EXE>

But it is always better to specify it exactly through the qHostInfo if you can.

> 
> The command I didn't implement yet is "qThreadStopInfo", could this be the reason why the stack trace is not constructed or am I missing something else?

No, that wouldn't do it. It could be because you didn't fully specify your generic registers in the responses to the qRegisterInfo packets. It could be due to an unknown target triple that made no dynamic loader plug-in be selected. If you can send me a full transcript of all gdb-remote packets offline, I will take a look and see what I can figure out. 

> Also, to implement the "qShlibInfoAddr" packet I've used the following snippet:
> struct dyld_all_image_infos* getImageInfosFromKernel
> ()
> {
> 	task_dyld_info_data_t task_dyld_info;
> 	mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
>     
>     
> if
>  ( task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count) ) {
> 		FAIL(
> "all_image_infos: task_info() failed"
> );
> 		exit(0);
> 	}
> 	
> return (struct
>  dyld_all_image_infos*)(uintptr_t)task_dyld_info.all_image_info_addr;
> }
> 
> Does it get the required address for the result packet?

Yes, but you wouldn't want to exit(0) if you failed to get the info right? Just return an invalid address.

A few questions for you: what are you trying to debug? What arch? It sounds like this is for a user space MacOSX program? The triple specified when creating the target and/or from the qHostInfo will help determine which shared libraries are loaded and where they are loaded. This will then allow LLDB to resolve "load" addresses back into "file" relative addresses so we can backtrace. 
> 
> Thanks in advance,
> Benjamin.
> 
> 
> On Mon, Feb 11, 2013 at 8:33 PM, Greg Clayton <gclayton at apple.com> wrote:
> 
> On Feb 10, 2013, at 6:58 AM, Benjamin Kemper <kemperbenny at gmail.com> wrote:
> 
> > I noticed something that I've missed when sending the previous Email. Looking at the logs, I see LLDB sending "kill" command for no reason:
> > <lldb.driver.main-thread> <  18> send packet: $m1039ede00,200#86
> >   1 <lldb.driver.main-thread> <   1> read packet: +
> >   0 <lldb.driver.main-thread> <1028> read packet: $4b4c5752000000000000000000000000c04e0000014e0000004e000000000000000000000000000010de9e030100000014de9e030100000018de9e030100000020
> >   1 <lldb.driver.main-thread> <   1> send packet: +
> >   2 <lldb.driver.main-thread> <  18> send packet: $m1038d4200,200#21
> >   3 <lldb.driver.main-thread> <   1> read packet: +
> >   4 <lldb.driver.main-thread> <1028> read packet: $e97bf4ffff6666666666662e0f1f8400000000009090909090909090909090909090909090909090909090909090909090909090909090909090909090909090e9
> >   5 <lldb.driver.main-thread> <   1> send packet: +
> >   6 <lldb.driver.main-thread> <  21> send packet: $Z0,7fff5fc0d6e5,1#de
> >   7 <lldb.driver.main-thread> <   1> read packet: +
> >   8 <lldb.driver.main-thread> <   6> read packet: $OK#9a
> >   9 <lldb.driver.main-thread> <   1> send packet: +
> >  10 <lldb.driver.main-thread> <  16> send packet: $qfThreadInfo#bb
> >  11 <lldb.driver.main-thread> <   1> read packet: +
> >  12 <lldb.driver.main-thread> <   8> read packet: $m707#0b
> >  13 <lldb.driver.main-thread> <   1> send packet: +
> >  14 <lldb.driver.main-thread> <  16> send packet: $qsThreadInfo#c8
> >  15 <lldb.driver.main-thread> <   1> read packet: +
> >  16 <lldb.driver.main-thread> <   5> read packet: $l#6c
> >  17 <lldb.driver.main-thread> <   1> send packet: +
> >  18 <lldb.driver.main-thread> <  18> send packet: $z0,1005f00d7,1#5a
> >  19 <lldb.driver.main-thread> <   1> read packet: +
> >  20 <lldb.driver.main-thread> <   6> read packet: $OK#9a
> >  21 <lldb.driver.main-thread> <   1> send packet: +
> >  22 <lldb.driver.main-thread> <  21> send packet: $z0,7fff5fc0d6e5,1#fe
> >  23 <lldb.driver.main-thread> <   1> read packet: +
> >  24 <lldb.driver.main-thread> <   6> read packet: $OK#9a
> >  25 <lldb.driver.main-thread> <   1> send packet: +
> >  26 <lldb.driver.main-thread> <   5> send packet: $k#6b
> >  27 <lldb.driver.main-thread> <   1> read packet: +
> >  28 <lldb.driver.main-thread> <   6> read packet: $OK#9a
> >  29 <lldb.driver.main-thread> <   1> send packet: +
> >  30    6> send packet: $p2#a2
> >  31 <lldb.driver.main-thread> <   1> read packet: +
> >  32 <lldb.driver.main-thread> <   4> read packet: $#00
> >  33 <lldb.driver.main-thread> <   1> send packet: +
> >  34 <lldb.driver.main-thread> <   6> send packet: $p3#a3
> >
> > Here are my commands in the lldb console:
> > ➜  build  lldb /bin/ls
> > Current executable set to '/bin/ls' (x86_64).
> > (lldb) log enable -f /tmp/packets.txt  gdb-remote packets
> > (lldb) process connect -p gdb-remote connect://localhost:58985
> > Process 1799 stopped
> > * thread #1: tid = 0x0707, , stop reason = signal SIGINT
> >     frame #0:
> > (lldb)
> >
> > Why might LLDB send the 'kill' command without "permission"?
> 
> You will need to debug the LLDB sources to see why this isn't being sent. I know of no reason why this should be happening, so this is probably a bug.
> 
> >
> > The weird thing is that after it sends the kill command, it then start requesting for register values using the '$p' commands...
> >
> > Any ideas why this is happening?
> >
> 
> No, none at all. You will need to debug this. The only place the "k" packet is sent is from inside:
> 
> ProcessGDBRemote::DoDestroy ()
> 
> There is logging that can be enabled. Add the "process" category to the "gdb-remote" logging and use the "--stack" option to print out a backtrace:
> 
> (lldb) log enable --stack -f /tmp/process.txt gdb-remote process
> 
> You should then see a stack backtrace to see who is calling DoDestroy()...
> 
> >
> >
> > On Sun, Feb 10, 2013 at 3:19 PM, Benjamin Kemper <kemperbenny at gmail.com> wrote:
> > Hi,
> >
> > I'm implementing a debugger backend that implements the gdb remote protocol and adding extensions to support LLDB also.
> >
> > I've added support for the qRegisterInfo packet and I've noticed in the logs that LLDB uses the p/P packets instead of the G/g packets.
> >
> > Is there a special reason why it uses multiple packets instead of one?
> >
> > Maybe I didn't implement enough "information" packets and LLDB doesn't know how to read g/G packets? If so, what packets are missing?
> >
> > Thanks,
> > Benjamin.
> >
> > _______________________________________________
> > lldb-dev mailing list
> > lldb-dev at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 
> 





More information about the lldb-dev mailing list