Skip to content

Commit 052dc6c

Browse files
authored
Fix TTD negotiation break regular debugging in GDB MI adapter (#1023)
1 parent 8186cfb commit 052dc6c

1 file changed

Lines changed: 28 additions & 23 deletions

File tree

core/adapters/gdbmiadapter.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,34 @@ bool GdbMiAdapter::Connect(const std::string& server, uint32_t port) {
530530
}
531531
}
532532

533+
// Detect reverse debugging / TTD support by querying GDB's knowledge of the
534+
// remote server's capabilities from the initial qSupported handshake.
535+
//
536+
// IMPORTANT: We must NOT send a raw qSupported packet via "maintenance packet" because
537+
// this re-negotiates the GDB remote protocol mid-session, causing gdbserver to reset its
538+
// internal register description state. After re-negotiation, gdbserver may lose knowledge
539+
// of registers (e.g. AVX ymm0h), and subsequent register reads will crash it.
540+
//
541+
// Instead, we query GDB's cached knowledge of the 'bc' (reverse-continue) and 'bs'
542+
// (reverse-step) packet support, which was negotiated during -target-select.
543+
m_canReverseContinue = false;
544+
m_canReverseStep = false;
545+
{
546+
std::string bcStatus = InvokeBackendCommand("show remote reverse-continue-packet");
547+
std::string bsStatus = InvokeBackendCommand("show remote reverse-step-packet");
548+
549+
// Output: 'Support for the 'bc' packet ... is "auto", currently enabled.'
550+
if (!bcStatus.empty() && bcStatus.find("currently enabled") != std::string::npos)
551+
m_canReverseContinue = true;
552+
if (!bsStatus.empty() && bsStatus.find("currently enabled") != std::string::npos)
553+
m_canReverseStep = true;
554+
555+
if (m_canReverseContinue && m_canReverseStep)
556+
LogInfo("Reverse debugging support detected (TTD enabled)");
557+
else
558+
LogInfo("No reverse debugging support detected");
559+
}
560+
533561
// Fetch register list - needed for Method 3 if architecture still not detected,
534562
// and also needed later for populating m_registerNames
535563
auto regListResult = m_mi->SendCommand("-data-list-register-names");
@@ -588,9 +616,7 @@ bool GdbMiAdapter::Connect(const std::string& server, uint32_t port) {
588616
{
589617
m_registerNames.clear();
590618
for (const auto& regVal : value["register-names"].GetList())
591-
{
592619
m_registerNames.push_back(regVal.GetString());
593-
}
594620
LogInfo("Found %zu registers in register-names list", m_registerNames.size());
595621
}
596622
else
@@ -609,27 +635,6 @@ bool GdbMiAdapter::Connect(const std::string& server, uint32_t port) {
609635
}
610636
}
611637

612-
// Detect reverse debugging / TTD support by probing the remote server's qSupported capabilities.
613-
// Servers like udbserver and rr advertise ReverseContinue+ and ReverseStep+ in qSupported.
614-
m_canReverseContinue = false;
615-
m_canReverseStep = false;
616-
{
617-
std::string qSupportedResponse = InvokeBackendCommand(
618-
"maintenance packet qSupported:ReverseContinue+;ReverseStep+");
619-
if (!qSupportedResponse.empty())
620-
{
621-
if (qSupportedResponse.find("ReverseContinue+") != std::string::npos)
622-
m_canReverseContinue = true;
623-
if (qSupportedResponse.find("ReverseStep+") != std::string::npos)
624-
m_canReverseStep = true;
625-
}
626-
627-
if (m_canReverseContinue && m_canReverseStep)
628-
LogInfo("Reverse debugging support detected (TTD enabled)");
629-
else
630-
LogInfo("No reverse debugging support detected");
631-
}
632-
633638
// AFTER we are connected and stopped, populate the cache for the first time.
634639
LogInfo("Populating initial state cache...");
635640
ScheduleStateRefresh();

0 commit comments

Comments
 (0)