update: lldb-gdbserver on x86_64 linux

Hi all,

I’m finally getting some cycles to put on lldb-gdbserver for x86_64 linux.

I created a dummy looping exe (never exits), ran lldb_gdbserver against it in a terminal on my (local) x86_64 Ubuntu 12.04, turned on all logging, and attached from the (local) x86_64 Ubuntu 12.04 with top of tree as of yesterday. My only diffs at the moment are enabling lldb-gdbserver to build under linux and x86_64, and commenting out an assert that doesn’t seem to make sense that always hits when starting up lldb-gdbserver.

See below for the communication transcript when attaching from the (local) lldb via the gdb-remote command. It pretty much defines my next several steps in terms of just getting lldb-gdbserver up and running on linux x86_64. I include this since I recall a few people were thinking of getting lldb-gdbserver up and running, and I didn’t want to duplicate any applicable work that may have been implemented already in other branches.

In the stream below, lgs is an abbreviation for lldb-gdbserver.

The log is from running a simple program that loops and never

stops, using lldb-gdbserver on a linux x86_64 platform.

lgs receives an ack in response to (presumably) something not

recorded in the log.

< 1> read packet: +

lgs receives a request to disable ack mode. Since we’re

communicating over reliable TCP, this is accepted. This will

eliminate the future ‘+/-’ responses between lgs and lldb.

< 19> read packet: $QStartNoAckMode#b0
< 1> send packet: +
< 6> send packet: $OK#9a
< 1> read packet: +

Query if lgs supports adding a thread suffix to g/G (read/write all

general registers) and p/P (read/write specified general register).

< 26> read packet: $QThreadSuffixSupported#e4

Here lgs says “No, I can’t do that.” Bad answer - needs to be

implemented for efficiency. TODO: Implement.

< 4> send packet: $#00

This message first appeared with this change list:

http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20120409/005460.html

Documentation is missing.

< 27> read packet: $QListThreadsInStopReply#21

Here lgs says “No, I can’t do that.” Bad answer. TODO: Implement and document.

< 4> send packet: $#00

lldb requests info about the remote machine

< 13> read packet: $qHostInfo#9b

lgs reports the system triple: “x86_64–linux-gnu”, where arch is

x86_64, vendor probably should say ubuntu (but is empty), and os

probably should be linux (instead of linux-gnu, where the extra dash

is potentially a parsing issue and I would avoid).

TODO:

1. modify the triple to provide the distribution in vendor (e.g.

ubuntu, fedora, etc. as reported by “Distributor ID:” on

‘lsb_release -a’, or via the DISTRIB_ID= line of /etc/os-release.

Use ‘android’ for linux (e.g. arm-android-linux).

2. add a dist_version. Set to match the distribution version. For

ubuntu, you’d get 12.04, 13.10, etc. android you’d get 4.2, 4.3,

4.4.2, etc. os_version is still fine to be kernel version.

3. fix qHostInfo docs to include os_version and hostname keys.

< 218> send packet:
$triple:7838365f36342d2d6c696e75782d676e75;ptrsize:8;cputype:16777223;cpusubtype:3;watchpoint_exceptions_received:after;endian:little;os_version:3.2.5;hostname:686f73742e6578616d706c652e636f6d;#b4

lldb is asking whether vCont is supported, and if so, which vCont

actions are supported.

< 10> read packet: $vCont?#49

lgs responds that it doesn’t support vCont at all. This is an error

on multi-threaded platforms. TODO: add support for vCont.

< 4> send packet: $#00

lldb asks an undocumented question. Looking at code now. Checks to

see if vAttachOrWait is supported. This is a command that allows for

attaching to a given process name, or waiting for it to start and

then attaching.

< 27> read packet: $qVAttachOrWaitSupported#38

lgs replies that it doesn’t support it. Bad answer. TODO: implement.

< 4> send packet: $#00

lldb asks for the thread id of the current thread.

< 6> read packet: $qC#b4

lgs responds with thread id 0. This might be right.

< 7> send packet: $QC0#c4

lldb asks for the process info of the current process.

< 16> read packet: $qProcessInfo#dc

lgs says “I know nothing.” Bad answer. TODO: implement

< 4> send packet: $#00

I’ll start digging into these. I’ll flip on building of lldb-gdbserver for x86_64 as soon as I have it doing anything more than just the above.

This is actually the process ID (yes the GDB remote docs are not clear on this) of the process that lldb-gdbserver is controlling. Returning 0 means there is no process yet and LLDB till treat it as you are connected, but not yet debugging anything. So return the PID to this then you will get a '?' packet for a stop reply where you will tell LLDB why you stopped. You should respond with "$T11" which is hex 0x11 which is SIGSTOP, or SIGINT.

I think you are being generous, Greg :wink:

I believe that the triple (which is actually a triple here!) is
correct/acceptable. At the very least, within the context of LLVM's
handling, the triple is valid (though, I believe that GNU tools will also
handle it correctly). The "extra" dash is there for clarity.

The triple is parsed as the following tuple (yes, a triple contains four
parts, contrary to the name):
<arch>-<vendor>-<os>-<environment>.

As such, the triple is parsed as a x86_64 linux host with a GNU
environment. IIRC, llvm::Triple will treat x86_64-linux-gnu as an
equivalent triple (and will internally canonicalise it to
x86_64--linux-gnu).

Thanks, Saleem.

We ended up having a few more conversations about the triple and I have left it alone. Instead I have added a distribution_id (and soon a distribution version) which ArchSpec and qHostInfo optionally handle. Linux distributions will fill this in with results from lsb_release if present. Android later will return ‘android’ here with the dist version set to the android release.

I still don’t understand the value of the vendor in the triple if it’s never set (or nearly always pc) in the case of linux kernel systems as widely varied as Android and Ubuntu, but the distribution additions will work well enough for us and won’t disturb the ecosystem. :slight_smile:

-Todd

Hi all,

I'm finally getting some cycles to put on lldb-gdbserver for x86_64 linux.

I created a dummy looping exe (never exits), ran lldb_gdbserver against it
in a terminal on my (local) x86_64 Ubuntu 12.04, turned on all logging, and
attached from the (local) x86_64 Ubuntu 12.04 with top of tree as of
yesterday. My only diffs at the moment are enabling lldb-gdbserver to build
under linux and x86_64, and commenting out an assert that doesn't seem to
make sense that always hits when starting up lldb-gdbserver.

This is the assert (g_swig_init_callback != NULL) in
ScriptInterpreterPython.cpp? After removing that and adding the
subdirectory to tools/CMakeLists.txt I can build and run
lldb-gdbserver on FreeBSD, and a basic sanity test works fine (e.g.,
target create /bin/ls, b main, run, c).

...
I'll start digging into these. I'll flip on building of lldb-gdbserver for
x86_64 as soon as I have it doing anything more than just the above.

I'd be happy to have it added to the default build now (or once the
assert is sorted out) - I don't see a downside beyond a trivial amount
of extra build time.

I don’t see a problem with that. There is a ton of basic functionality not working there yet but will be coming online soonish. I was limiting it to just Linux x86_64 to simplify the initial bring-up, but now that I have a FreeBSD VM, this is probably a good sanity check to make sure I won’t have too much work to bring it up in other environments.

So feel free to turn it on for FreeBSD.

This is the assert (g_swig_init_callback != NULL) in
ScriptInterpreterPython.cpp?

Nah - it’s an issue with the current default Host process launching on Linux (and maybe FreeBSD?) that doesn’t seem to be able to launch a process in a stopped state. So there’s an assert in the posix launch that verifies the launch flag doesn’t ask for starting the process in a stopped state. (Not so helpful for a debugger, eh? :wink: ). I think this problem will go away when I start bridging over to launching processes correctly soon here. For the moment you’ll see that Linux masks out the launch flag for launch in a debugged state. Obviously we do this right for local debugging, so I’ll be adjusting this code soon.

Interesting. I ran into a different assert when I first tried it:

$ bin/lldb-gdbserver 1234
Assertion failed: (g_swig_init_callback != NULL), function
InitializePrivate, file
../tools/lldb/source/Interpreter/ScriptInterpreterPython.cpp, line
2539.
Abort trap (core dumped)

I just avoided the g_swig_init_callback() call for now to test this
out and it seems to work fine.

$ bin/lldb-gdbserver 1234
using the default platform: host
Listening for a connection on 1234...
Connection established.
  <some debugging>
error: lost connection
lldb-gdbserver exiting...