Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: noackmode zombie state handling #2060

Merged
merged 4 commits into from
Jan 21, 2025

Conversation

perigoso
Copy link
Contributor

Detailed description

When a connection is terminated abruptly the noackmode state may be left in a "zombie" state, enabled, because we are unable to detect the connection was terminated.

We previously used the qSupported packet to signal a new connection and reset the state, but this breaks compatibility with LLDB which does not send qSupported as the first packet.

This attempts a new approach, by checking if a acknowledgement was sent in response to qSupported reply, we can detect when noackmode is enabled when it shouldn't. This also needs some special cases to acknowledge the first packets in a connection when noackmode is in a zombie state.

This introduces a small issue on LLDB connections, it tries to get an acknowledgement on qSupported which never comes, this is intended but, at least in hosted, the timeout is apparently not respected resulting in a slowdown of the connection of around ~1 second. This is an unrelated bug, and the connection is still successful in the end so I deem it out of scope of this PR to fix it.

Debug logs for connections after the changes

GDB, normal operation / clean state:

gdb_packet_ack: ACK
gdb_packet_receive: qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;QThreadOptions+;no-resumed+;memory-tagging+
gdb_packet_send: PacketSize=400;qXfer:memory-map:read+;qXfer:features:read+;vContSupported+;QStartNoAckMode+
gdb_packet_get_ack: ACK
gdb_packet_ack: ACK
gdb_packet_receive: vCont?
gdb_packet_send: vCont;c;C;s;t
gdb_packet_get_ack: ACK
gdb_packet_ack: ACK
gdb_packet_receive: vMustReplyEmpty
gdb_packet_send: 
gdb_packet_get_ack: ACK
gdb_packet_ack: ACK
gdb_packet_receive: QStartNoAckMode
Enabling NoAckMode
gdb_packet_send: OK
gdb_packet_receive: !
gdb_packet_send: OK
gdb_packet_receive: Hg0
gdb_packet_send: OK
gdb_packet_receive: qXfer:features:read:target.xml:0,3fb
gdb_packet_send: E01
gdb_packet_receive: qTStatus
*** Unsupported packet: qTStatus
gdb_packet_send: 
gdb_packet_receive: ?
gdb_packet_send: W00

GDB, NoAckMode zombie state:

gdb_packet_receive: qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;QThreadOptions+;no-resumed+;memory-tagging+
gdb_packet_ack: ACK
gdb_packet_send: PacketSize=400;qXfer:memory-map:read+;qXfer:features:read+;vContSupported+;QStartNoAckMode+
gdb_packet_get_ack: ACK
Received acknowledgment in NoAckMode, likely result of a session being terminated abruptly
Disabling NoAckMode
gdb_packet_ack: ACK
gdb_packet_receive: vCont?
gdb_packet_send: vCont;c;C;s;t
gdb_packet_get_ack: ACK
gdb_packet_ack: ACK
gdb_packet_receive: vMustReplyEmpty
gdb_packet_send: 
gdb_packet_get_ack: ACK
gdb_packet_ack: ACK
gdb_packet_receive: QStartNoAckMode
Enabling NoAckMode
gdb_packet_send: OK
gdb_packet_receive: !
gdb_packet_send: OK
gdb_packet_receive: Hg0
gdb_packet_send: OK
gdb_packet_receive: qXfer:features:read:target.xml:0,3fb
gdb_packet_send: E01
gdb_packet_receive: qTStatus
*** Unsupported packet: qTStatus
gdb_packet_send: 
gdb_packet_receive: ?
gdb_packet_send: W00

LLDB, normal operation / clean state:

gdb_packet_ack: ACK
gdb_packet_receive: QStartNoAckMode
Enabling NoAckMode
gdb_packet_send: OK
gdb_packet_receive: qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events+;vfork-events+
gdb_packet_ack: ACK
gdb_packet_send: PacketSize=400;qXfer:memory-map:read+;qXfer:features:read+;vContSupported+;QStartNoAckMode+
gdb_packet_get_ack: NACK
gdb_packet_receive: qC
gdb_packet_send: QC1
gdb_packet_receive: QListThreadsInStopReply
*** Unsupported packet: QListThreadsInStopReply
gdb_packet_send: 
gdb_packet_receive: qHostInfo
*** Unsupported packet: qHostInfo
gdb_packet_send: 
gdb_packet_receive: vCont?
gdb_packet_send: vCont;c;C;s;t
gdb_packet_receive: qVAttachOrWaitSupported
*** Unsupported packet: qVAttachOrWaitSupported
gdb_packet_send: 
gdb_packet_receive: QEnableErrorStrings
*** Unsupported packet: QEnableErrorStrings
gdb_packet_send: 
gdb_packet_receive: qProcessInfo
*** Unsupported packet: qProcessInfo
gdb_packet_send: 
gdb_packet_receive: qC
gdb_packet_send: QC1
gdb_packet_receive: ?
gdb_packet_send: W00
gdb_packet_receive: qProcessInfo
*** Unsupported packet: qProcessInfo
gdb_packet_send: 

LLDB, NoAckMode zombie state:

gdb_packet_receive: QStartNoAckMode
gdb_packet_ack: ACK
gdb_packet_send: OK
gdb_packet_receive: qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events+;vfork-events+
gdb_packet_ack: ACK
gdb_packet_send: PacketSize=400;qXfer:memory-map:read+;qXfer:features:read+;vContSupported+;QStartNoAckMode+
gdb_packet_get_ack: NACK
gdb_packet_receive: qC
gdb_packet_send: QC1
gdb_packet_receive: QListThreadsInStopReply
*** Unsupported packet: QListThreadsInStopReply
gdb_packet_send: 
gdb_packet_receive: qHostInfo
*** Unsupported packet: qHostInfo
gdb_packet_send: 
gdb_packet_receive: vCont?
gdb_packet_send: vCont;c;C;s;t
gdb_packet_receive: qVAttachOrWaitSupported
*** Unsupported packet: qVAttachOrWaitSupported
gdb_packet_send: 
gdb_packet_receive: QEnableErrorStrings
*** Unsupported packet: QEnableErrorStrings
gdb_packet_send: 
gdb_packet_receive: qProcessInfo
*** Unsupported packet: qProcessInfo
gdb_packet_send: 
gdb_packet_receive: qC
gdb_packet_send: QC1
gdb_packet_receive: ?
gdb_packet_send: W00
gdb_packet_receive: qProcessInfo
*** Unsupported packet: qProcessInfo
gdb_packet_send:

Your checklist for this pull request

Closing issues

@dragonmux dragonmux added this to the v2.0 release milestone Jan 20, 2025
@dragonmux dragonmux added Bug Confirmed bug GDB Issue/PR related to GDB labels Jan 20, 2025
Copy link
Member

@dragonmux dragonmux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good, there's just a couple of (mostly code style) things to sort and we'll get this merged. Seen it demonstrated working so that's all fine.

src/gdb_main.c Outdated Show resolved Hide resolved
src/include/gdb_packet.h Outdated Show resolved Hide resolved
src/gdb_packet.c Outdated Show resolved Hide resolved
@perigoso perigoso force-pushed the fix/noackmode-zombie-state branch from 567bc23 to 4d81e01 Compare January 21, 2025 09:58
When a connection is terminated abruptly the noackmode state may be left in a "zombie" state, enabled, because we are unable to detect the connection was terminated.

 We previously used the qSupported packet to signal a new connection and reset the state, but this breaks compatibility with LLDb which does not send qSupported as the first packet.

This attempts a new approach, by checking if a acknowledgement was sent in response to qSupported reply, we can detect when noackmode is enabled when it shouldn't. This also needs some special cases to acknowledge the first packets in a connection when noackmode is in a zombie state.
@perigoso perigoso force-pushed the fix/noackmode-zombie-state branch from 4d81e01 to f4e79b6 Compare January 21, 2025 17:55
Copy link
Member

@dragonmux dragonmux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all LGTM, going to give it a quick spin locally and then once convinced it's all working as intended, we'll merge it. Thank you for the contribution!

@dragonmux dragonmux merged commit f4e79b6 into blackmagic-debug:main Jan 21, 2025
36 checks passed
@perigoso perigoso deleted the fix/noackmode-zombie-state branch January 22, 2025 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Confirmed bug GDB Issue/PR related to GDB
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants