gdb-remote command broken in TOT

Hi all,

I have just synced up to the top-of-tree for llvm, clang and lldb, and rebuilt for 64-bit linux. I've found that the implementation of the command "gdb-remote localhost:<port>", is now broken

./lldb ~/src/play/c/simp/simp-x64
Traceback (most recent call last):
   File "<string>", line 1, in <module>
ImportError: No module named lldb.embedded_interpreter
Current executable set to '/home/mg11/src/play/c/simp/simp-x64' (x86_64).
(lldb) gdb-remote localhost:7778
Process 0 connected

error: Process 0 is currently being debugged, kill the process before connecting.
(lldb) bt
error: invalid thread

It seems the client-side is not collecting the process and thread information correctly from the server. The GDB-RSP (server=7778) is as follows:

127.000.000.001.43138-127.000.000.001.07778: +
127.000.000.001.43138-127.000.000.001.07778: $QStartNoAckMode#b0
127.000.000.001.07778-127.000.000.001.43138: +
127.000.000.001.07778-127.000.000.001.43138: $OK#9a
127.000.000.001.43138-127.000.000.001.07778: +
127.000.000.001.43138-127.000.000.001.07778: $QThreadSuffixSupported#e4
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $QListThreadsInStopReply#21
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qHostInfo#9b
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $vCont?#49
127.000.000.001.07778-127.000.000.001.43138: $vCont;c;C;s;S;t;r#be
127.000.000.001.43138-127.000.000.001.07778: $qVAttachOrWaitSupported#38
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00

This functionality was working (almost) properly about a month ago. Here is a run using that binary and a trace.

./lldb ~/src/play/c/simp/simp-x64
Traceback (most recent call last):
   File "<string>", line 1, in <module>
ImportError: No module named lldb.embedded_interpreter
Current executable set to '/home/mg11/src/play/c/simp/simp-x64' (x86_64).
(lldb) gdb-remote localhost:7778
Process 13723 stopped
* thread #1: tid = 13723, , stop reason = signal SIGTRAP
     frame #0:

127.000.000.001.43202-127.000.000.001.07778: +
127.000.000.001.43202-127.000.000.001.07778: $QStartNoAckMode#b0
127.000.000.001.07778-127.000.000.001.43202: +
127.000.000.001.07778-127.000.000.001.43202: $OK#9a
127.000.000.001.43202-127.000.000.001.07778: +
127.000.000.001.43202-127.000.000.001.07778: $QThreadSuffixSupported#e4
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $QListThreadsInStopReply#21
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qHostInfo#9b
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $vCont?#49
127.000.000.001.07778-127.000.000.001.43202: $vCont;c;C;s;S;t;r#be
127.000.000.001.43202-127.000.000.001.07778: $qVAttachOrWaitSupported#38
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qC#b4
127.000.000.001.07778-127.000.000.001.43202: $QC359b#97
127.000.000.001.43202-127.000.000.001.07778: $?#3f
127.000.000.001.07778-127.000.000.001.43202: $T0506:0*,;07:a0e1f*"7f0* ;10:f011a075360*";thread:359b;core:5;#d9
127.000.000.001.43202-127.000.000.001.07778: $qRegisterInfo0#72
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $p0#a0
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qRegisterInfo0#72
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qShlibInfoAddr#6a
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qfThreadInfo#bb
127.000.000.001.07778-127.000.000.001.43202: $m359b#70
127.000.000.001.43202-127.000.000.001.07778: $qsThreadInfo#c8
127.000.000.001.07778-127.000.000.001.43202: $l#6c

Part of the problem, it seems, is that the new build does not send "qC" (get current thread id).

Is there anyone currently working in this area? Or is it a bug I should start to look at?

thanks
Matthew Gardiner

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Matthew Gardiner wrote:

Hi all,

I have just synced up to the top-of-tree for llvm, clang and lldb, and rebuilt for 64-bit linux. I've found that the implementation of the command "gdb-remote localhost:<port>", is now broken

./lldb ~/src/play/c/simp/simp-x64
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named lldb.embedded_interpreter
Current executable set to '/home/mg11/src/play/c/simp/simp-x64' (x86_64).
(lldb) gdb-remote localhost:7778
Process 0 connected

error: Process 0 is currently being debugged, kill the process before connecting.
(lldb) bt
error: invalid thread

It seems the client-side is not collecting the process and thread information correctly from the server. The GDB-RSP (server=7778) is as follows:

127.000.000.001.43138-127.000.000.001.07778: +
127.000.000.001.43138-127.000.000.001.07778: $QStartNoAckMode#b0
127.000.000.001.07778-127.000.000.001.43138: +
127.000.000.001.07778-127.000.000.001.43138: $OK#9a
127.000.000.001.43138-127.000.000.001.07778: +
127.000.000.001.43138-127.000.000.001.07778: $QThreadSuffixSupported#e4
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $QListThreadsInStopReply#21
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qHostInfo#9b
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $vCont?#49
127.000.000.001.07778-127.000.000.001.43138: $vCont;c;C;s;S;t;r#be
127.000.000.001.43138-127.000.000.001.07778: $qVAttachOrWaitSupported#38
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00

This functionality was working (almost) properly about a month ago. Here is a run using that binary and a trace.

./lldb ~/src/play/c/simp/simp-x64
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named lldb.embedded_interpreter
Current executable set to '/home/mg11/src/play/c/simp/simp-x64' (x86_64).
(lldb) gdb-remote localhost:7778
Process 13723 stopped
* thread #1: tid = 13723, , stop reason = signal SIGTRAP
    frame #0:

127.000.000.001.43202-127.000.000.001.07778: +
127.000.000.001.43202-127.000.000.001.07778: $QStartNoAckMode#b0
127.000.000.001.07778-127.000.000.001.43202: +
127.000.000.001.07778-127.000.000.001.43202: $OK#9a
127.000.000.001.43202-127.000.000.001.07778: +
127.000.000.001.43202-127.000.000.001.07778: $QThreadSuffixSupported#e4
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $QListThreadsInStopReply#21
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qHostInfo#9b
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $vCont?#49
127.000.000.001.07778-127.000.000.001.43202: $vCont;c;C;s;S;t;r#be
127.000.000.001.43202-127.000.000.001.07778: $qVAttachOrWaitSupported#38
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qC#b4
127.000.000.001.07778-127.000.000.001.43202: $QC359b#97
127.000.000.001.43202-127.000.000.001.07778: $?#3f
127.000.000.001.07778-127.000.000.001.43202: $T0506:0*,;07:a0e1f*"7f0* ;10:f011a075360*";thread:359b;core:5;#d9
127.000.000.001.43202-127.000.000.001.07778: $qRegisterInfo0#72
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $p0#a0
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qRegisterInfo0#72
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qShlibInfoAddr#6a
127.000.000.001.07778-127.000.000.001.43202: $#00
127.000.000.001.43202-127.000.000.001.07778: $qfThreadInfo#bb
127.000.000.001.07778-127.000.000.001.43202: $m359b#70
127.000.000.001.43202-127.000.000.001.07778: $qsThreadInfo#c8
127.000.000.001.07778-127.000.000.001.43202: $l#6c

Part of the problem, it seems, is that the new build does not send "qC" (get current thread id).

Is there anyone currently working in this area? Or is it a bug I should start to look at?

thanks
Matthew Gardiner

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

To report this email as spam click https://www.mailcontrol.com/sr/1WqnrEJPKhrGX2PQPOmvUmkxeMeR4!FmImKX97+QpHjLCq2QeVly7xayiF08kgVBnOaHevKbN4oYNBM7q0TQEQ== .

I've had a quick look at some code, and it looks like somewhere between the call to ConnectToDebugserver and m_gdb_comm.GetCurrentProcessID we omit to send the "qC" request, and that seems to result in GetCurrentProcessID == LLDB_INVALID_PROCESS_ID.

Is this omission by design or is it a bug?

The code I ended up looking at is below:

ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
{
     Error error (WillLaunchOrAttach ());

     if (error.Fail())
         return error;

     error = ConnectToDebugserver (remote_url);

     if (error.Fail())
         return error;
     StartAsyncThread ();

     lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
     if (pid == LLDB_INVALID_PROCESS_ID)
     {
         // We don't have a valid process ID, so note that we are connected
         // and could now request to launch or attach, or get remote process
         // listings...
         SetPrivateState (eStateConnected);
     }
     else
     {
         // We have a valid process
         SetID (pid);
         GetThreadList();
         if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
         {
             if (!m_target.GetArchitecture().IsValid())

thanks
Matt

Is this omission by design or is it a bug?

I've now found that GDBRemoteCommunicationClient::GetCurrentProcessID() has been reworked recently, and that it what has caused the breakage I've witnessed.

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

This is a change I made.

qC is supposed to return the thread id, not the process id.

qProcessInfo is being used now to collect the process id. We added a fallback so that if the process info request fails, on Apple/iOS we fall back to the older qC (which, as indicated before, used to return the process id erroneously, see the gdb remote documentation).

Let me know what path you’re not getting the getting process info when you would expect it. I’ve got some protocol tests on it in test/tools/lldb-gdbserver where it runs with a @debugserver_test (on MacOSX) and @llgs_test (on the llgs branch here). Sounds like we’re maybe missing a case somewhere.

Is the context that you’re launching new inferior or an attaching to existing inferior?

Thanks!

-Todd

Okay, looking back at your packet log:

127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00

Couple options here:

  1. implement qProcessInfo in your custom remote monitor. The only key-value pair we’re looking for in this case is the pid:{process-id} pair as far as retrieving the process id goes. If you’re in control of the remote, this will be your fastest option for getting a resolution.

  2. we find the gdbremote command present in the stock gdbremote protocol set that gives us the process id (and this is not $qC) and fall back to that if qProcessInfo is not supported.

I’ll look for #2. Probably best for you to implement $qProcessInfo if it’s an option for you. RNBRemote.cpp has the handler for it in debugserver and GDBRemoteCommunicationServer.cpp has it for llgs in that other branch from the prior email (soon to go upstream).

Hope that helps!

-Todd

I’ll look for #2.

I just scanned through the gdbremote protocol docs here. I may have missed it, but searching process-id, “process id”, and pid in the packets and didn’t see any way to query for the process id using just what was documented.

It looks possible to get the data indirectly if multiprocess extensions are enabled and supported by both the stub and the client, in which case some stop replies can contain the process:{pid} key/value. Seems like implementing qProcessInfo is the easier way to go here though since the multiprocess extensions seem to change behavior of several of the other packets.

-Todd

-Todd

LLDB was incorrectly using the "qC" packet to get the process info. From your old working log:

127.000.000.001.43202-127.000.000.001.07778: $qC#b4
127.000.000.001.07778-127.000.000.001.43202: $QC359b#97

It now uses the qProcessInfo packet:

127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00

You should add support for this packet. Here is a sample:

send packet: $qProcessInfo#00
read packet: $pid:42a8;parent-pid:42bf;real-uid:ecf;real-gid:b;effective-uid:ecf;effective-gid:b;cputype:7;cpusubtype:3;ostype:macosx;vendor:apple;endian:little;ptrsize:4;#00

Omit and key value pairs that don't make sense for your target (parent-pid, real-uid, real-gid, effective-uid, effective-gid, cputype, cpusubtype), but do try to at least add the following key/value pairs:

pid
triple (with values like: x86_64-apple-macosx, i386-unknown-unknown (for raw binary debugging with no OS like a bare board))
endian
ptrsize

You can omit the "vendor" and "ostype" if you supply the triple.

Todd Fiala wrote:

Okay, looking back at your packet log:

127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00

Couple options here:

1. implement qProcessInfo in your custom remote monitor. The only key-value pair we're looking for in this case is the pid:{process-id} pair as far as retrieving the process id goes. If you're in control of the remote, this will be your fastest option for getting a resolution.

Thanks Todd,

I'm on my way to implement qProcessInfo in my stub.

The real problem is that, the log I sent was between lldb and the linux gdbserver from FC20. And so now lldb is no longer compatible with the older reference implementation of gdbserver. Is this intentional?

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Todd Fiala wrote:

> I'll look for #2.

I just scanned through the gdbremote protocol docs here <https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#Packets>. I may have missed it, but searching process-id, "process id", and pid in the packets and didn't see any way to query for the process id using just what was documented.

Yeah, I had a look through my docs. Looks as the old gdb people make no hard distinction better threads and processes. I think that qC is asking "give me the id of what stopped and I assuming that pids and thread-ids come from the same number pool". Well that's my guess, at least...

It looks possible to get the data indirectly if multiprocess extensions are enabled and supported by both the stub and the client, in which case some stop replies can contain the process:{pid} key/value. Seems like implementing qProcessInfo is the easier way to go here though since the multiprocess extensions seem to change behavior of several of the other packets.

Sure, I'm on my way with qProcessInfo (for my stub)...

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Greg Clayton wrote:

LLDB was incorrectly using the "qC" packet to get the process info. From your old working log:

127.000.000.001.43202-127.000.000.001.07778: $qC#b4
127.000.000.001.07778-127.000.000.001.43202: $QC359b#97

It now uses the qProcessInfo packet:

127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00
127.000.000.001.43138-127.000.000.001.07778: $qProcessInfo#dc
127.000.000.001.07778-127.000.000.001.43138: $#00

You should add support for this packet. Here is a sample:

send packet: $qProcessInfo#00
read packet: $pid:42a8;parent-pid:42bf;real-uid:ecf;real-gid:b;effective-uid:ecf;effective-gid:b;cputype:7;cpusubtype:3;ostype:macosx;vendor:apple;endian:little;ptrsize:4;#00

Omit and key value pairs that don't make sense for your target (parent-pid, real-uid, real-gid, effective-uid, effective-gid, cputype, cpusubtype), but do try to at least add the following key/value pairs:

pid
triple (with values like: x86_64-apple-macosx, i386-unknown-unknown (for raw binary debugging with no OS like a bare board))
endian
ptrsize

You can omit the "vendor" and "ostype" if you supply the triple.

Thanks for this Greg, I'm on my way with implementing this in my stub.

The problem, which I've previously iterated to Todd, is that now lldb's gdb-remote command is incompatible with the stock GNU gdbserver, as it knows only of qC and not of qProcessInfo.

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Todd Fiala wrote:

This is a change I made.

qC is supposed to return the thread id, not the process id.

qProcessInfo is being used now to collect the process id. We added a fallback so that if the process info request fails, on Apple/iOS we fall back to the older qC (which, as indicated before, used to return the process id erroneously, see the gdb remote documentation).

After doing a bit more analysis, I see that you added a fallback such that if the process info request fails, we fall back to traditional gdbserver qC. This is completely reasonable, and permits our custom stubs to support qProcessInfo.

However is there any real need to restrict the fallback case to just Apple/iOS? that is:

     const llvm::Triple &triple = GetProcessArchitecture().GetTriple();
     if ((triple.getVendor() == llvm::Triple::Apple) &&
         (triple.getOS() == llvm::Triple::IOS))
     {

Surely, all stubs which fail to implement qProcessInfo should be permitted to fallback to qC?

I've just commented out the above "if" in my working copy, and now the initial "gdb-remote host:port" works again - in so far as the current inferior process number is reported rather than 0. (Admittedly other things don't quite work as desired later on in the debug-session, e.g. "next". But presumably an Apple/iOS stub would either fail similarly, or work as expected due to some localised conditional treatment, (i.e. "if apple then...")).

So, to continue to interoperate with traditional gdbserver implementations can we let all older stubs continue to fallback to qC?

thanks
Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Hey Matthew,

However is there any real need to restrict the fallback case to just Apple/iOS?

Keep in mind that qC in gdbserver does implement the protocol correctly and returns the thread id, not the proc id. On Linux the first thread happens to get a thread id that is identical to the proc id. So when launching an exe, the active thread id returned just happens to be the proc id as well out of happy coincidence. This is not true on other OSes and not guaranteed true when attaching to a Linux process if the active thread is not the first thread. Given that lldb was not caching the proc id until my change last week, it means that lldb using qC against a gdbserver (or gdb remote protocol implementing qC per spec) is definitely getting the buggy behavior I was fixing (i.e. different proc ids throughout the life of the process when running against a multi-threaded inferior, and entirely invalid results for proc id when run on OSes where the thread ids have no correlation to the proc id, as on MacOSX).

Thus, reverting to using qC when qProcessInfo isn’t implemented is really just reverting to buggy and inconsistent behavior, although it may allow lldb to run where it can’t now (and could before) and the proc id reported just happens to be right some of the time.

I think the real fix here may be if $qProcessInfo isn’t present, then we probably need to settle for not assuming we can get the process id, and just make sure lldb can handle running without it in that case.

Greg, any thoughts on that?

-Todd

On Tuesday, May 13, 2014, Matthew Gardiner <mg11@csr.com> wrote:e thread if returned

Hey Matthew,

> However is there any real need to restrict the fallback case to just Apple/iOS?

Keep in mind that qC in gdbserver does implement the protocol correctly and returns the thread id, not the proc id. On Linux the first thread happens to get a thread id that is identical to the proc id. So when launching an exe, the active thread id returned just happens to be the proc id as well out of happy coincidence. This is not true on other OSes and not guaranteed true when attaching to a Linux process if the active thread is not the first thread. Given that lldb was not caching the proc id until my change last week, it means that lldb using qC against a gdbserver (or gdb remote protocol implementing qC per spec) is definitely getting the buggy behavior I was fixing (i.e. different proc ids throughout the life of the process when running against a multi-threaded inferior, and entirely invalid results for proc id when run on OSes where the thread ids have no correlation to the proc id, as on MacOSX).

Thus, reverting to using qC when qProcessInfo isn't implemented is really just reverting to buggy and inconsistent behavior, although it may allow lldb to run where it can't now (and could before) and the proc id reported just happens to be right some of the time.

I would revert this. The pid isn't really all that important, we just need to know that we are talking to something valid or not. We assume zero is invalid.

I think the real fix here may be if $qProcessInfo isn't present, then we probably need to settle for not assuming we can get the process id, and just make sure lldb can handle running without it in that case.

Greg, any thoughts on that?

I would revert to getting the pid from qC. Lame, but it would make us more backward compatible. Leave a note in the code saying we really prefer stubs to implement the qProcessInfo packet.

You realize that qC’s response is not stable as a pseudo pid, right? So anything that asks for it, thinks they have it, and then asks again for it can get a different result depending on what the gdb remote thinks is the current thread.

I’d offer we consider falling back to qC and not limiting it to iOS over reverting this entirely, unless you strongly object. Or we can simply do exactly what you said - which is check if we’re attached to something - by grabbing the qC result and just not storing it as a process id (i.e. essentially create a GDBRemoteCommunicationClient::HasProcess (), which happens to be implemented in terms of checking qProcessInfo, then qC, for anything).

Just some thoughts.

-Todd

I should rephrase since we need context here:

  1. TOT lldb <=> current debugserver/llgs

Will use qProcessInfo and get the process id.

  1. TOT lldb <=> older debugserver

Will use qProcessINfo and get the process id.

  1. TOT lldb <=> gdbserver

Will fail to get the process id from qProcessInfo, will not ask for qC because it’s not Apple/iOS. That will trigger lldb to think its not attached properly.

– two fixes here:
3.1 - fall back to qC as we would in the Apple/iOS case, and realize we wont’ really have the real PID, which we don’t really care about for the remote setup case,
3.2 - rework and add a “do I have a process on the remote end” predicate, and rework attach logic to just ask this new question which doesn’t promise a process id.

  1. old lldb <=> TOT debugserver

Asks for qC, gets same behavior as it did before - gets a thread id, treats it as a process id, connection works.

So we really only have case 3 that is an issue, which is what Matthew hit since he has a different gdbremote.

Since I believe that is the only case we’re trying to fix here, I’d be in favor of doing the simple fix of allowing $qC for a fake process id not limited to Apple/iOS.

That’s my take. I’m happy to check that change in if this seems reasonable.

-Todd

You realize that qC's response is not stable as a pseudo pid, right? So anything that asks for it, thinks they have it, and then asks again for it can get a different result depending on what the gdb remote thinks is the current thread.

Yes I realize.

I'd offer we consider falling back to qC and not limiting it to iOS

Agreed, don't limit to iOS. We just really need a pid that is not zero to indicate we have a valid process. We should always try qProcessInfo first and any new GDB servers we make or people work on should support that.

over reverting this entirely, unless you strongly object. *Or* we can simply do exactly what you said - which is check if we're attached to something - by grabbing the qC result and just not storing it as a process id (i.e. essentially create a GDBRemoteCommunicationClient::HasProcess (), which happens to be implemented in terms of checking qProcessInfo, then qC, for anything).

Yes, I don't like giving false info to the user either, but I would like to maintain backward compatibility.

I should rephrase since we need context here:

1. TOT lldb <=> current debugserver/llgs

Will use qProcessInfo and get the process id.

2. TOT lldb <=> older debugserver

Will use qProcessINfo and get the process id.

3. TOT lldb <=> gdbserver

Will fail to get the process id from qProcessInfo, will not ask for qC because it's not Apple/iOS. That will trigger lldb to think its not attached properly.

-- two fixes here:
3.1 - fall back to qC as we would in the Apple/iOS case, and realize we wont' really have the real PID, which we don't really care about for the remote setup case,
3.2 - rework and add a "do I have a process on the remote end" predicate, and rework attach logic to just ask this new question which doesn't promise a process id.

I vote for 3.1 where we don't limit to iOS.

4. old lldb <=> TOT debugserver

Asks for qC, gets same behavior as it did before - gets a thread id, treats it as a process id, connection works.

Yes.

So we really only have case 3 that is an issue, which is what Matthew hit since he has a different gdbremote.

Since I believe that is the only case we're trying to fix here, I'd be in favor of doing the simple fix of allowing $qC for a fake process id not limited to Apple/iOS.

Agreed.

Ok - I’m testing that change now (which corresponds to that 3.1 solution in the other fork of the thread).

Will have it in shortly.

Thanks!

And of course, Matthew, sorry for breaking you there.

This change is in at r208741.