For example:
$ cat a.c
int main() { return 0; }
$ clang -static a.c -o a.out
$ lldb a.out -o "b _start" -o "r"
(lldb) target create "a.out"
Current executable set to '/tmp/a.out' (x86_64).
(lldb) b _start
Breakpoint 1: where = a.out`_start, address = 0x0000000000401630
(lldb) r
Process 3302100 launched: '/usr/local/google/home/zequanwu/workspace/tmp/a.out' (x86_64)
Process 3302100 exited with status = 0 (0x00000000)
By comparing the gdb remote logging with lldb a.out -o "log enable gdb-remote packets" -o "process launch --stop-at-entry"
which does stop at _start, the one with b _start
has the following extra logging at the end:
lldb < 111> send packet: $vRun;2f7573722f6c6f63616c2f676f6f676c652f686f6d652f7a657175616e77752f776f726b73706163652f746d702f612e6f7574#4f
lldb < 617> read packet: $T13thread:p3263b9.3263b9;name:a.out;threads:3263b9;thread-pcs:0000000000401630;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:0000000000000000;04:0000000000000000;05:0000000000000000;06:0000000000000000;07:80d5ffffff7f0000;08:0000000000000000;09:0000000000000000;0a:0000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:0000000000000000;10:3016400000000000;11:0002000000000000;12:3300000000000000;13:0000000000000000;14:0000000000000000;15:2b00000000000000;16:0000000000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000;reason:signal;#0b
lldb < 16> send packet: $qProcessInfo#dc
lldb < 182> read packet: $pid:3263b9;parent-pid:326398;real-uid:9d619;real-gid:15f53;effective-uid:9d619;effective-gid:15f53;triple:7838365f36342d2d6c696e75782d676e75;ostype:linux;endian:little;ptrsize:8;#a3
lldb < 5> send packet: $?#3f
lldb < 617> read packet: $T13thread:p3263b9.3263b9;name:a.out;threads:3263b9;thread-pcs:0000000000401630;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:0000000000000000;04:0000000000000000;05:0000000000000000;06:0000000000000000;07:80d5ffffff7f0000;08:0000000000000000;09:0000000000000000;0a:0000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:0000000000000000;10:3016400000000000;11:0002000000000000;12:3300000000000000;13:0000000000000000;14:0000000000000000;15:2b00000000000000;16:0000000000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000;reason:signal;#0b
(the process firstly stopped at _start which is 0x401630 with stop reason being signal)
...
lldb < 15> send packet: $Z0,401630,1#41
lldb < 6> read packet: $OK#9a
lldb < 25> send packet: $qThreadStopInfo3263b9#64
lldb < 617> read packet: $T13thread:p3263b9.3263b9;name:a.out;threads:3263b9;thread-pcs:0000000000401630;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:0000000000000000;04:0000000000000000;05:0000000000000000;06:0000000000000000;07:80d5ffffff7f0000;08:0000000000000000;09:0000000000000000;0a:0000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:0000000000000000;10:3016400000000000;11:0002000000000000;12:3300000000000000;13:0000000000000000;14:0000000000000000;15:2b00000000000000;16:0000000000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000;reason:signal;#0b
lldb < 15> send packet: $z0,401630,1#61
lldb < 6> read packet: $OK#9a
b-remote.async> < 26> send packet: $vCont;s:p3263b9.3263b9#62
b-remote.async> < 616> read packet: $T05thread:p3263b9.3263b9;name:a.out;threads:3263b9;thread-pcs:0000000000401632;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:0000000000000000;04:0000000000000000;05:0000000000000000;06:0000000000000000;07:80d5ffffff7f0000;08:0000000000000000;09:0000000000000000;0a:0000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:0000000000000000;10:3216400000000000;11:4602000000000000;12:3300000000000000;13:0000000000000000;14:0000000000000000;15:2b00000000000000;16:0000000000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000;reason:trace;#ab
intern-state < 15> send packet: $Z0,401630,1#41
intern-state < 6> read packet: $OK#9a
b-remote.async> < 22> send packet: $vCont;c:p3263b9.-1#47
b-remote.async> < 22> read packet: $W00;process:3263b9#94
Process 3302329 launched: '/tmp/a.out' (x86_64)
Process 3302329 exited with status = 0 (0x00000000)
(lldb) exit
It looks like because itâs using step-over breakpoint thread plan if it finds a breakpoint with the same address as current thread $pc address: llvm-project/lldb/source/Target/Thread.cpp at d8f1e5d2894f7f4edc2e85e63def456c7f430f34 ¡ llvm/llvm-project ¡ GitHub
If I change that line to push_step_over_bp_plan = GetStopReason() != eStopReasonSignal;
to stop it from using step-over breakpoint plan if stopped by signal, itâs now able to break to _start. But it causes behaviour change (if the thread stopped at signal, it requires two n
commands to move $pc to next instruction) on in the following example:
$ cat signal.cpp
#include <csignal>
namespace {
volatile std::sig_atomic_t gSignalStatus;
}
void signal_handler(int signal) {
gSignalStatus = signal;
}
int main() {
// Install a signal handler
std::signal(SIGINT, signal_handler);
std::raise(SIGINT);
}
$ clang++ -static -g signal.cpp -o signal.static
$ lldb signal.static -o "log enable gdb-remote packets" -o "b main" -o "r" -o "b -a 0x404f1c" -o "c" -o "n"
...
Process 3305968 resuming
Process 3305968 stopped
* thread #1, name = 'signal.static', stop reason = signal SIGINT
frame #0: 0x0000000000404f1c signal.static`__pthread_kill_implementation.constprop.0 + 252
signal.static`__pthread_kill_implementation.constprop.0:
-> 0x404f1c <+252>: movl %eax, %ebx
0x404f1e <+254>: negl %ebx
0x404f20 <+256>: cmpl $0xfffff000, %eax ; imm = 0xFFFFF000
0x404f25 <+261>: movl $0x0, %eax
(lldb) n
b-remote.async> < 26> send packet: $vCont;s:p3271f0.3271f0#56
b-remote.async> < 629> read packet: $T05thread:p3271f0.3271f0;name:signal.static;threads:3271f0;thread-pcs:0000000000404f1c;00:0000000000000000;01:f071320000000000;02:1c4f400000000000;03:0200000000000000;04:f071320000000000;05:f071320000000000;06:b0d3ffffff7f0000;07:60d3ffffff7f0000;08:00d3ffffff7f0000;09:1c00000000000000;0a:0800000000000000;0b:4602000000000000;0c:78d5ffffff7f0000;0d:0200000000000000;0e:0100000000000000;0f:0100000000000000;10:1c4f400000000000;11:4602000000000000;12:3300000000000000;13:0000000000000000;14:0000000000000000;15:2b00000000000000;16:80734a0000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000;reason:breakpoint;#01
intern-state < 21> send packet: $x7fffffffd200,200#2d
intern-state < 516> read packet: $00000000000000006728470000000000e0d3ffffff7f000050d3ffffff7f000048d3ffffff7f00003dc2a0010000000008804a00000000000100000000000000000000000000000000f52994343bdd840000000000000000984040000000000060174000000000000200000000000000000000000000000000000000000000000000000000000000672847000000000098834a000000000000be490000000000e07f4a0000000000538f306800000000d8d3ffffff7f000010ea420000000000000000000000000000be4900000000000000000000000000000000000000000000000000000000000000001000000000000000000000000048d3ffffff7f000000000000000000000000000000000000040000000000000000d3fff7ff7f0000e07f4a000000000078d2ffffff7f000074d2ffffff7f0000000000000000000000000000000000006728470000000000e0d3ffffff7f00000e4f40000000000048d3ffffff7f000000f52994343bdd8408804a00000000000200000000000000b0d3ffffff7f000078d5ffffff7f0000e8bd490000000000024140000000000088d5ffffff7f00009f174000000000000100000000000000641c40000000000000114000000000008017400000000000711540000100000078d5ffffff7f000088d5ffffff7f0000b5c7b90063d96e7a78d5ffffff7f0000e8bd490000000000#ec
lldb < 16> send packet: $jThreadsInfo#c1
lldb < 163> read packet: $[{"name":"signal.static","reason":"breakpoint","registers":{"16":"1c4f400000000000","6":"b0d3ffffff7f0000","7":"60d3ffffff7f0000"}],"signal":5,"tid":3305968}]]#66
lldb < 15> send packet: $x404e00,200#93
lldb < 518> read packet: $0000004883c4085b5d415c415d415e415fc3c3662e0f1f8400000000000f1f0041554189f5415455534883ec1864488b042528000000488944240831c064483b3c25100000000f84b40000004989e44889fb31ff41ba080000004c89e2488d356c370700b80e0000000f0531c0488dab04090000ba01000000f00fb155000f85ac00000080bb0109000000744b31db31c087450083f8010f8fa300000041ba0800000031d24c89e6bf02000000b80e0000000f05488b44240864482b0425280000000f85850000004883c41889d85b5d415c415dc30f1f008b9bd0020000e8edb800004489ea89c789deb8ea0000000f053d00f0ffff769589c3f7dbeb916690b8ba0000000f0589c3e8c2b800004489ea89de89c7b8ea0000000f0589c3f7db3d00f0ffffb8000000000f46d8eb85904889efe8a8fcffffe947ffffff0f1f004889efe848fdffffe950ffffffe88ec7000066662e0f1f8400000000000f1f00e9bbfeffff66662e0f1f8400000000008d46e083f8017608e9a3feffff0f1f00b816000000c3662e0f1f84000000000064488b042510000000c3660f1f440000488b07c705dba10900010000004889059ca10900c366662e0f1f840000000000488b07c705bba10900010000008905ada10900c366662e0f1f84000000000090488b07c7059ba109000100000048890554a10900c366662e0f1f840000000000#3e
Process 3305968 stopped
* thread #1, name = 'signal.static', stop reason = breakpoint 2.1
frame #0: 0x0000000000404f1c signal.static`__pthread_kill_implementation.constprop.0 + 252
signal.static`__pthread_kill_implementation.constprop.0:
-> 0x404f1c <+252>: movl %eax, %ebx
0x404f1e <+254>: negl %ebx
0x404f20 <+256>: cmpl $0xfffff000, %eax ; imm = 0xFFFFF000
0x404f25 <+261>: movl $0x0, %eax
(The first `n` doesn't move $pc because it's also a breakpoint address)
...
@jingham Do you have any thought on this?