[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Mar 12 09:07:54 PDT 2025
labath wrote:
> > Define "target".
>
> "target" == the thing to be debugged. Eg.., `lldb <target>` or (after starting lldb, you'd do `target create <target>`).
Okay. So far, so good.
>
> > Define "loading a target". When a process does an execve is it still the same target (as far as the rest of lldb is concerned, it is, even though it starts executing a different binary)?
>
> I think by "loading" i mean the time it takes from "target create" command till when lldb command prompt is ready to accept the next command. (Admitted, in this implementation, it's not quite measuring that since that's a bit more tricky to instrument, so I settled to the closest thing, which was around initting the main executable).
This is where it gets tricky. I know you want that, but I don't think that *all* you want (if it was, you may not even need this patch since it's kind of implicitly measured by the command interpreter telemetry). I think you also want to handle cases where the target is created through SB API. If *that* was all you wanted, then the best place to instrument might be something like `TargetList::CreateTarget`. However, there is also the case of attaching, in which case you first create a [target without an executable](https://github.com/llvm/llvm-project/blob/665299eb3e7a142199e2c22eb294c5e01ef1655d/lldb/source/Commands/CommandObjectProcess.cpp#L334) and later set the executable [once you've attached to the running process](https://github.com/llvm/llvm-project/blob/665299eb3e7a142199e2c22eb294c5e01ef1655d/lldb/source/Commands/CommandObjectProcess.cpp#L361). There are also other cases (loading a core file (`target create --core`), connecting to a remote debug server (`process connect`)), which look like "attaching" in some ways, but go through slightly different paths.
This is why I suggested way back to focus on SetExecutableModule, as that is (one) place where all of these paths converge, and it covers the most expensive part of the operation. I don't think it's the only way to capture all this information, but I still think it's *a* way to do it. However, it's definitely not the same as "loading/creating a target".
>
> Can you clarify your definition of "target" ? :) You're saying a "target" could have _different_ main-executable ("different binary")?? How would that use case look?
I can give you at least three:
1. execve
```
$ head *.c
==> ping.c <==
int main() { execlp("./pong", "pong", 0); }
==> pong.c <==
int main() { execlp("./ping", "ping", 0); }
$ lldb ./ping
(lldb) target create "./ping"
Current executable set to '/tmp/ping' (x86_64).
(lldb) process launch --stop-at-entry
Process 14214 stopped
* thread #1, name = 'ping', stop reason = signal SIGSTOP
frame #0: 0x00007ffff7fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
-> 0x7ffff7fe2bc0 <+0>: movq %rsp, %rdi
0x7ffff7fe2bc3 <+3>: callq 0x7ffff7fe38c0 ; _dl_start
ld-linux-x86-64.so.2`_dl_start_user:
0x7ffff7fe2bc8 <+0>: movq %rax, %r12
0x7ffff7fe2bcb <+3>: movq %rsp, %r13
Process 14214 launched: '/tmp/ping' (x86_64)
(lldb) target list
Current targets:
* target #0: /tmp/ping ( arch=x86_64-pc-linux-gnu, platform=host, pid=14214, state=stopped )
### We are executing "ping" now
(lldb) c
Process 14214 resuming
Process 14214 stopped
* thread #1, name = 'pong', stop reason = exec
frame #0: 0x00007ffff7fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
-> 0x7ffff7fe2bc0 <+0>: movq %rsp, %rdi
0x7ffff7fe2bc3 <+3>: callq 0x7ffff7fe38c0 ; _dl_start
ld-linux-x86-64.so.2`_dl_start_user:
0x7ffff7fe2bc8 <+0>: movq %rax, %r12
0x7ffff7fe2bcb <+3>: movq %rsp, %r13
(lldb) target list
Current targets:
* target #0: /tmp/pong ( arch=x86_64-pc-linux-gnu, platform=host, pid=14214, state=stopped )
# Same target, same pid, but a different executable -- SetExecutableModule was called to switch the new image
(lldb) c
Process 14214 resuming
Process 14214 stopped
* thread #1, name = 'ping', stop reason = exec
frame #0: 0x00007ffff7fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
-> 0x7ffff7fe2bc0 <+0>: movq %rsp, %rdi
0x7ffff7fe2bc3 <+3>: callq 0x7ffff7fe38c0 ; _dl_start
ld-linux-x86-64.so.2`_dl_start_user:
0x7ffff7fe2bc8 <+0>: movq %rax, %r12
0x7ffff7fe2bcb <+3>: movq %rsp, %r13
(lldb) target list
Current targets:
* target #0: /tmp/ping ( arch=x86_64-pc-linux-gnu, platform=host, pid=14214, state=stopped )
# Still the same target, but now we're back to the first binary => Another SetExecutableModule call
```
2. Guessing the wrong binary when attaching:
```
$ lldb /bin/ls
(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
# One SetExecutableModule call here
(lldb) process attach -p 14329
Process 14329 stopped
* thread #1, name = 'cat', stop reason = signal SIGSTOP
frame #0: 0x00007f337699c1d1 libc.so.6`read + 17
libc.so.6`read:
-> 0x7f337699c1d1 <+17>: cmpq $-0x1000, %rax ; imm = 0xF000
0x7f337699c1d7 <+23>: ja 0x7f337699c230 ; <+112>
0x7f337699c1d9 <+25>: retq
0x7f337699c1da <+26>: nopw (%rax,%rax)
warning: Executable module changed from "/bin/ls" to "/bin/cat".
# And another one here
```
3. Bare metal debugging where you don't actually have an image to debug (or you just don't know/have access to that image). It's too fiddly to set up now, but in this case you can have a target (and a process), but no executable image (no SetExecutableModule calls)
Neither of these scenarios is particularly common, so I don't think they'll skew the data if you present them as "creating a target". And in a way they're correct, since in e.g., the execve case, you actually have to reparse all of the debug info for the new image so, in a sense, you are creating a new target. However, I think we should be very explicit in the code about what we are doing.
https://github.com/llvm/llvm-project/pull/127834
More information about the lldb-commits
mailing list