[lldb-dev] strange behaviour at lldb cmd line
Greg Clayton
gclayton at apple.com
Tue Jul 1 09:58:56 PDT 2014
> On Jun 30, 2014, at 10:50 PM, Matthew Gardiner <mg11 at csr.com> wrote:
>
> Greg Clayton wrote:
>> As soon as we attach with any GDB server, we expect one of two things:
>> 1 - a process and all its threads are stopped. the $? packet should respond with any thread that has a stop reason _or_ if no threads have a stop reason, then report a $T packet for the first thread. You can probably respond with $T00 if there is no real signal or reason the thread stopped. Some debuggers like to respond with $T05 (SIGTRAP), but I would rather we don't lie and report a bogus SIGTRAP signal and tell the truth ($T00 or no signal).
>> 2 - there is no process which means qProcessInfo respond with an invalid value or error, or for backward compatibility qC responds with an invalid value. This lets us know we don't have a process and no $? should be issued.
>
> Hi Greg,
>
> I appreciate this question may be slightly off-topic, but you mentioned that on attaching to a GDB server you expect "a process and all it's threads are stopped" (or no process).
>
> Does the concept of a non-invasive attach exist in lldb? By that I mean can you attach to a process without stopping it.
It does, just not with GDB remote. The GDB remote protocol has a very simple design: send a packet then wait for a response and the protocol can do nothing else unless interrupted (by sending a CTRL+C byte (0x03)).
So we would have to issue a command like "launch process" (the 'A' packet) and we get a response ("OK"). Now the process is assumed to be stopped as far as I know since the only way to make the process run is to issue a continue packet ("c" or "vCont:c") or a step packet ("s" or "vCont:s"). When we send these packets we wait for a response ("$TSS;..." where SS is a hex signal number followed by key value pairs.
So there is no real feature in the protocol that allows for running without first sending some form of a run packet (continue or step).
>
> We have this feature in our current debugger, in additional to permitting memory and register reads for certain areas of our chips, it may useful to a developer to inspect whether a device is "still running".
Yep, this can all be done by your custom lldb_process::Process subclass. With the internal LLDB API, we have no problem saying a process is running immediately after an attach, you would simply send a eStateLaunching event followed by a eStateRunning event. We might have to tweak a few things in LLDB to make sure this works, but it is possible.
But if you create a target and then you set breakpoints:
(lldb) target create /bin/ls
(lldb) b malloc
(lldb) b free
Then you launch:
(lldb) process launch
Do you really want LLDB to try and set the "malloc" and "free" breakpoints while your process is running? This will make you potentially miss the first N breakpoints hits if your process doesn't start up stopped.
>
> I've also observed that the Microsoft Visual Studio debugger also permits attach onto a running process, without it's interruption.
On most systems, even though attaching says it doesn't do anything, the process often will briefly be stopped. I believe all unix variants will stop with a SIGSTOP or SIGTRAP when you call ptrace() with the attach command.
>
> Is such a feature achievable using lldb via it's "target" or remoting commands?
We have also had requests for attaching to a running process, but the debugger is going to want to stop right away and try and set breakpoints before continuing to ensure the breakpoints can be hit.
So we can easily modify LLDB to do this kind of thing if this is important, but the GDB remote protocol isn't a great target to make that work with. If we somehow taught the GDB remote protocol to not return from the 'A' packet which launches a process, the only thing we can do is interrupt the 'A' packet in order to send the "set breakpoint" packet. So it would go like:
(lldb) process attach ...
send: send attach packet
wait for response which doesn't come back since we want /bin/ls to run
Now LLDB wants to send a breakpoint packet to set the breakpoints for "malloc" and "free" but it can't since GDB remote can only send one packet at a time so we must interrupt:
send: 0x03 (interrupt)
recv: stop reply packet from interrupt
send: set breakpoint at malloc packet
recv: reply for breakpoint packet
send: continue
send: 0x03 (interrupt)
recv: stop reply packet from interrupt
send: set breakpoint at free packet
recv: reply for breakpoint packet
send: continue
So now we have stopped the target multiple times because we wanted to send the breakpoint packets while the target is running, instead of just once right after we attach when the process is stopped.
So to sum up: yes this is possible with LLDB, but the ProcessGDBRemote is not a great candidate for this change due to its design.
Greg
More information about the lldb-dev
mailing list