labath wrote:
I think there may be a problem with this patch (and that the windows fix maybe
just papers over the issue).
Let me illustrate what I mean this with the following packet log. I'm sorry for
the length -- I tried to remove the really boring parts, but I didn't want to
leave out too much context. The most interesting lines are marked with `<===`.
```
lldb < 1> send packet: +
lldb < 19> send packet: $QStartNoAckMode#b0
lldb < 1> read packet: +
lldb < 6> read packet: $OK#9a
lldb < 1> send packet: +
lldb < 104> send packet:
$qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events
+;vfork-events+;swbreak+;hwbreak+#cd
lldb < 278> read packet:
$PacketSize=131072;QStartNoAckMode+;qEcho+;native-signals+;QThreadSu
ffixSupported+;QListThreadsInStopReply+;qXfer:features:read+;QNonStop+;jMultiBreakpoint+;QPassSignals+;qX
fer:auxv:read+;qXfer:libraries-svr4:read+;qXfer:siginfo:read+;multiprocess+;fork-events+;vfork-events+#6c
lldb < 26> send packet: $QThreadSuffixSupported#e4
lldb < 6> read packet: $OK#9a
lldb < 27> send packet: $QListThreadsInStopReply#21
lldb < 6> read packet: $OK#9a
lldb < 13> send packet: $qHostInfo#9b
lldb < 338> read packet:
$triple:7838365f36342d2d6c696e75782d676e75;ptrsize:8;distribution_id
:67656e746f6f;watchpoint_exceptions_received:after;endian:little;os_version:6.18.18;os_build:362e31382e31
382d67656e746f6f;os_kernel:233120534d5020505245454d50545f44594e414d494320546875204170722020322030393a3131
3a303320434553542032303236;hostname:756e696d617472697830;#f6
<snip>
lldb < 29> send packet: $vRun;2f746d702f612e6f7574#f3
lldb < 611> read packet:
$T13thread:pe3f8.e3f8;name:a.out;threads:e3f8;thread-pcs:00000000004
027c0;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:0000000000000000;04:0000000000000000
;05:0000000000000000;06:0000000000000000;07:f0d8ffffff7f0000;08:0000000000000000;09:0000000000000000;0a:0
000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:000000
0000000000;10:c027400000000000;11:0202000000000000;12:3300000000000000;13:0000000000000000;14:00000000000
00000;15:2b00000000000000;16:0000000000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000
;reason:signal;#09
lldb < 16> send packet: $qProcessInfo#dc
lldb < 170> read packet:
$pid:e3f8;parent-pid:e3f2;real-uid:3e8;real-gid:3e8;effective-uid:3e
8;effective-gid:3e8;triple:7838365f36342d2d6c696e75782d676e75;ostype:linux;endian:little;ptrsize:8;#bf
<snip>
lldb < 23> send packet: $qThreadStopInfoe3f8#31
lldb < 611> read packet:
$T13thread:pe3f8.e3f8;name:a.out;threads:e3f8;thread-pcs:00000000004
027c0;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:0000000000000000;04:0000000000000000
;05:0000000000000000;06:0000000000000000;07:f0d8ffffff7f0000;08:0000000000000000;09:0000000000000000;0a:0
000000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0000000000000000;0f:000000
0000000000;10:c027400000000000;11:0202000000000000;12:3300000000000000;13:0000000000000000;14:00000000000
00000;15:2b00000000000000;16:0000000000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000
;reason:signal;#09
lldb < 15> send packet: $Z0,4137f0,1#78
lldb < 6> read packet: $OK#9a
lldb < 15> send packet: $Z0,40290c,1#75
lldb < 6> read packet: $OK#9a
b-remote.async> < 20> send packet: $vCont;c:pe3f8.-1#14
Process 58360 launched: '/tmp/a.out' (x86_64)
b-remote.async> < 615> read packet:
$T05thread:pe3f8.e3f8;name:a.out;threads:e3f8;thread-pcs:00000000004
0290c;00:10d8ffffff7f0000;01:08d9ffffff7f0000;02:1101000000000000;03:08d9ffffff7f0000;04:0100000000000000
;05:f8d8ffffff7f0000;06:e0d7ffffff7f0000;07:e0d7ffffff7f0000;08:0001000000000000;09:0400000000000000;0a:8
0914a0000000000;0b:0f00000000000000;0c:f8d8ffffff7f0000;0d:0200000000000000;0e:604d4a0000000000;0f:020000
0000000000;10:0c29400000000000;11:4602000000000000;12:3300000000000000;13:0000000000000000;14:00000000000
00000;15:2b00000000000000;16:c0134b0000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000
;reason:breakpoint;#60
<snip>
Process 58360 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x000000000040290c a.out`main at a.c:3:28
1 int call_me() { return 47; }
2
-> 3 int main() { return call_me(); }
(lldb) expr -- call_me()
lldb < 14> send packet: $_M1000,rwx#fa
lldb < 20> read packet: $00007ffff7ff6000#58
lldb < 13> send packet: $_M1000,rw#82
lldb < 20> read packet: $00007ffff7ff5000#57
lldb < 13> send packet: $_M1000,rx#83
lldb < 20> read packet: $00007ffff7ff4000#56
lldb < 12> send packet: $_M1000,r#0b
lldb < 20> read packet: $00007ffff7ff3000#55
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5000#ab
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 22> send packet: $M7ffff7ff5000,1:00#db
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff4000#aa
lldb < 55> read packet:
$start:7ffff7ff4000;size:1000;permissions:rx;flags:;#c7
lldb < 97> send packet:
$M7ffff7ff4000,26:f30f1efa554889e55350488b1f48897df048b8f52840000000
0000ffd089034883c4085b5dc3#b5
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3000#a9
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 22> send packet: $M7ffff7ff3000,1:00#d9
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3010#aa
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 379> send packet:
$M7ffff7ff3010,b3:00245f5f6c6c64625f66756e633a3a3078313a307835383a5f
5a3763616c6c5f6d6576005f5a3132245f5f6c6c64625f657870725076002e72656c612e6c74657874002e74657874002e636f6d6
d656e74005f5a47565a3132245f5f6c6c64625f657870725076453139245f5f6c6c64625f657870725f726573756c74002e6c6273
73002e6e6f74652e474e552d737461636b00245f5f6c6c64625f6d6f64756c65002e737472746162002e73796d74616200#d9
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff4040#ae
lldb < 55> read packet:
$start:7ffff7ff4000;size:1000;permissions:rx;flags:;#c7
lldb < 22> send packet: $M7ffff7ff4040,1:00#de
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff30d0#dd
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 69> send packet:
$M7ffff7ff30d0,18:130000000000000001000000040000000000000000000000#e
e
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff30f0#df
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 71> send packet:
$M7ffff7ff30f0,19:00636c616e672076657273696f6e2032332e302e3067697400
#34
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3110#ab
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 22> send packet: $M7ffff7ff3110,1:00#db
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3120#ac
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 261> send packet:
$M7ffff7ff3120,78:00000000000000000000000000000000000000000000000094
0000000400f1ff0000000000000000000000000000000052000000010005000000000000000000010000000000000024000000120
0030000000000000000002600000000000000010000001000000000000000000000000000000000000000#92
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5020#ad
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 34> send packet: $M7ffff7ff5020,7:00000000000000#23
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5020#ad
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 28> send packet: $M7ffff7ff5020,4:00000000#00
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5010#ac
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 36> send packet: $M7ffff7ff5010,8:2050fff7ff7f0000#dc
lldb < 6> read packet: $OK#9a
lldb < 35> send packet: $QSaveRegisterState;thread:e3f8;#84
lldb < 5> read packet: $1#31
lldb < 36> send packet: $P4=1050fff7ff7f0000;thread:e3f8;#77
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7fffffffd758#1d
lldb < 76> read packet:
$start:7ffffffdd000;size:22000;permissions:rw;flags:;name:5b73746163
6b5d;#d9
lldb < 36> send packet: $M7fffffffd758,8:c027400000000000#34
lldb < 6> read packet: $OK#9a
lldb < 36> send packet: $P7=58d7ffffff7f0000;thread:e3f8;#eb
lldb < 6> read packet: $OK#9a
lldb < 37> send packet: $P10=0040fff7ff7f0000;thread:e3f8;#a2
lldb < 6> read packet: $OK#9a
lldb < 15> send packet: $Z0,4027c0,1#73 #
<========= ENTRY BKTP SET
lldb < 6> read packet: $OK#9a
lldb < 20> send packet: $p10;thread:e3f8;#2f
lldb < 20> read packet: $0040fff7ff7f0000#56
b-remote.async> < 20> send packet: $vCont;c:pe3f8.-1#14
b-remote.async> < 615> read packet:
$T05thread:pe3f8.e3f8;name:a.out;threads:e3f8;thread-pcs:00000000004
027c0;00:2f00000000000000;01:08d9ffffff7f0000;02:1101000000000000;03:08d9ffffff7f0000;04:1050fff7ff7f0000
;05:f8d8ffffff7f0000;06:e0d7ffffff7f0000;07:60d7ffffff7f0000;08:0001000000000000;09:0400000000000000;0a:8
0914a0000000000;0b:0f00000000000000;0c:f8d8ffffff7f0000;0d:0200000000000000;0e:604d4a0000000000;0f:020000
0000000000;10:c027400000000000;11:0602000000000000;12:3300000000000000;13:0000000000000000;14:00000000000
00000;15:2b00000000000000;16:c0134b0000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000
;reason:breakpoint;#fa
<snip>
intern-state < 40> send packet: $QRestoreRegisterState:1;thread:e3f8;#44
intern-state < 6> read packet: $OK#9a
<snip>
(int) $0 = 47
(lldb) expr -- call_me()
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5000#ab
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 22> send packet: $M7ffff7ff5000,1:00#db
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff4000#aa
lldb < 55> read packet:
$start:7ffff7ff4000;size:1000;permissions:rx;flags:;#c7
lldb < 97> send packet:
$M7ffff7ff4000,26:f30f1efa554889e55350488b1f48897df048b8f52840000000
0000ffd089034883c4085b5dc3#b5
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3000#a9
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 22> send packet: $M7ffff7ff3000,1:00#d9
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3010#aa
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 379> send packet:
$M7ffff7ff3010,b3:00245f5f6c6c64625f66756e633a3a3078313a307835383a5f
5a3763616c6c5f6d6576005f5a3132245f5f6c6c64625f657870725076002e72656c612e6c74657874002e74657874002e636f6d6
d656e74005f5a47565a3132245f5f6c6c64625f657870725076453139245f5f6c6c64625f657870725f726573756c74002e6c6273
73002e6e6f74652e474e552d737461636b00245f5f6c6c64625f6d6f64756c65002e737472746162002e73796d74616200#d9
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff4040#ae
lldb < 55> read packet:
$start:7ffff7ff4000;size:1000;permissions:rx;flags:;#c7
lldb < 22> send packet: $M7ffff7ff4040,1:00#de
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff30d0#dd
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 69> send packet:
$M7ffff7ff30d0,18:130000000000000001000000040000000000000000000000#e
e
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff30f0#df
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 71> send packet:
$M7ffff7ff30f0,19:00636c616e672076657273696f6e2032332e302e3067697400
#34
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3110#ab
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 22> send packet: $M7ffff7ff3110,1:00#db
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff3120#ac
lldb < 54> read packet:
$start:7ffff7ff3000;size:1000;permissions:r;flags:;#4e
lldb < 261> send packet:
$M7ffff7ff3120,78:00000000000000000000000000000000000000000000000094
0000000400f1ff0000000000000000000000000000000052000000010005000000000000000000010000000000000024000000120
0030000000000000000002600000000000000010000001000000000000000000000000000000000000000#92
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5020#ad
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 34> send packet: $M7ffff7ff5020,7:00000000000000#23
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5020#ad
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 28> send packet: $M7ffff7ff5020,4:00000000#00
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7ffff7ff5010#ac
lldb < 55> read packet:
$start:7ffff7ff5000;size:1000;permissions:rw;flags:;#c7
lldb < 36> send packet: $M7ffff7ff5010,8:2050fff7ff7f0000#dc
lldb < 6> read packet: $OK#9a
lldb < 35> send packet: $QSaveRegisterState;thread:e3f8;#84
lldb < 5> read packet: $2#32
lldb < 36> send packet: $P4=1050fff7ff7f0000;thread:e3f8;#77
lldb < 6> read packet: $OK#9a
lldb < 34> send packet: $qMemoryRegionInfo:7fffffffd758#1d
lldb < 76> read packet:
$start:7ffffffdd000;size:22000;permissions:rw;flags:;name:5b73746163
6b5d;#d9
lldb < 36> send packet: $M7fffffffd758,8:c027400000000000#34
lldb < 6> read packet: $OK#9a
lldb < 36> send packet: $P7=58d7ffffff7f0000;thread:e3f8;#eb
lldb < 6> read packet: $OK#9a
lldb < 37> send packet: $P10=0040fff7ff7f0000;thread:e3f8;#a2
lldb < 6> read packet: $OK#9a
lldb < 15> send packet: $Z0,4027c0,1#73 # <====== ENTRY BKPT
SET (AGAIN)
lldb < 6> read packet: $OK#9a
lldb < 20> send packet: $p10;thread:e3f8;#2f
lldb < 20> read packet: $0040fff7ff7f0000#56
lldb < 15> send packet: $z0,4027c0,1#93 # <======= ENTRY BKPT
CLEARED
lldb < 6> read packet: $OK#9a
b-remote.async> < 20> send packet: $vCont;c:pe3f8.-1#14
b-remote.async> < 615> read packet:
$T05thread:pe3f8.e3f8;name:a.out;threads:e3f8;thread-pcs:00000000004
027c0;00:2f00000000000000;01:08d9ffffff7f0000;02:1101000000000000;03:08d9ffffff7f0000;04:1050fff7ff7f0000
;05:f8d8ffffff7f0000;06:e0d7ffffff7f0000;07:60d7ffffff7f0000;08:0001000000000000;09:0400000000000000;0a:8
0914a0000000000;0b:0f00000000000000;0c:f8d8ffffff7f0000;0d:0200000000000000;0e:604d4a0000000000;0f:020000
0000000000;10:c027400000000000;11:0602000000000000;12:3300000000000000;13:0000000000000000;14:00000000000
00000;15:2b00000000000000;16:c0134b0000000000;17:0000000000000000;18:0000000000000000;19:0000000000000000
;reason:breakpoint;#fa
<snip>
intern-state < 40> send packet: $QRestoreRegisterState:2;thread:e3f8;#45
intern-state < 6> read packet: $OK#9a
<snip>
(int) $1 = 47
```
This is a log of me evaluating two expressions. The problematic part is that
during the evaluation of the first expression, we set the entry breakpoint
(which is supposed to be hit when the expression gets evaluation) -- but this
breakpoint doesn't get cleared. Then, when we evaluate the second expression,
we set the breakpoint *again* -- and then we also *clear* it (presumably
intending to clear the breakpoint from the first run).
Now, on lldb-server and debugserver this does not actually matter -- because
they implement the set/clear breakpoint packets using a
[refcount](https://github.com/llvm/llvm-project/blob/8442c9c417a579c77e5ac776dda393f33233c5ea/lldb/source/Host/common/NativeProcessProtocol.cpp#L348).
This means the breakpoint remains set when evaluating the expression -- as
expected.
However, it's not clear to me that this is actually the expected way to
implement these packets. The [gdb protocol
spec](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#insert-breakpoint-or-watchpoint-packet)
doesn't say much on the matter, but if we consider gdbserver to be a
"reference implementation" of the spec, then this would point to it *not* being
the case:
```
gdb) maintenance packet Z0,7ffff7fe3880,1
sending: Z0,7ffff7fe3880,1
[remote] Sending packet: $Z0,7ffff7fe3880,1#b7
[remote] Packet received: OK
received: "OK"
(gdb) maintenance packet Z0,7ffff7fe3880,1
sending: Z0,7ffff7fe3880,1
[remote] Sending packet: $Z0,7ffff7fe3880,1#b7
[remote] Packet received: OK
received: "OK"
(gdb) maintenance packet z0,7ffff7fe3880,1
sending: z0,7ffff7fe3880,1
[remote] Sending packet: $z0,7ffff7fe3880,1#d7
[remote] Packet received: E01
received: "E01"
```
Now, the reason I noticed this is because we have an (internal) stub, which
implements these packets the "gdb way", which means that the entry breakpoint
is *not* set when evaluating the second expression, and the expression ends up
starting the binary all over again (which, predictably, blows up).
I'm not sure if this is a case for the windows implementation. Being in-process
it doesn't use the same code as lldb-server, but I'm not completely sure in how
it interacts with the rest of lldb. However, the failure mode is at least
consistent with the behavior I've seen using our stub.
I've also looked at how qemu (a debug stub built for gdb that I have access to)
implements this and -- to my surprise -- it does implement the reference
counting behavior. I haven't looked at the source code, so I don't know if this
is intentional or not (I can imagine this kind of behavior falling out
"naturally" in some implementations).
Given all of this, I think we need to make a decision: do expect stub to
support reference counted breakpoints or not?
The list of stubs which are currently known to not support this is not
particularly compelling:
- gdbserver (which is not particularly interesting, although people
occasionally show up trying to use it)
- our internal stub (which you don't need to care about, and I can fix
relatively easily)
- lldb windows in-process plugin (maybe)
However, I am worried about all the random debug stub implementations out
there, potentially embedded in jtag probes or whatnot. I don't have access to
these to verify, but I understand that people are using these with lldb, and
these sound like the kind of things that would be hard to modify.
This is why my vote, whatever its worth, would be to fix this on the lldb side,
and ideally revert this patch in the mean time. If it helps, I volunteer to rip
out the reference counting code from within lldb-server to make this easier to
test (and make sure it doesn't happen again).
https://github.com/llvm/llvm-project/pull/192971
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits