From 953ddded1aa2b459a939e0f1649691c9086ba416 Mon Sep 17 00:00:00 2001 From: Ted Woodward Date: Thu, 16 Sep 2021 18:40:09 -0500 Subject: [PATCH] [lldb] Handle malformed qfThreadInfo reply If the remote gdbserver's qfThreadInfo reply has a trailing comma, GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs will return an empty vector of thread ids. This will cause lldb to recurse through three functions trying to get the list of threads, until it blows its stack and crashes. A trailing comma is a malformed response, but it shouldn't cause lldb to crash. This patch will return the tids received before the malformed response. Reviewed By: clayborg, labath Differential Revision: https://reviews.llvm.org/D109937 --- .../gdb-remote/GDBRemoteCommunicationClient.cpp | 6 ++++- .../TestThreadInfoTrailingComma.py | 27 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/functionalities/gdb_remote_client/TestThreadInfoTrailingComma.py diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index d949cfe..bf4baf7 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2908,8 +2908,12 @@ GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs( if (ch == 'm') { do { auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID); + // If we get an invalid response, break out of the loop. + // If there are valid tids, they have been added to ids. + // If there are no valid tids, we'll fall through to the + // bare-iron target handling below. if (!pid_tid) - return {}; + break; ids.push_back(pid_tid.getValue()); ch = response.GetChar(); // Skip the command separator diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestThreadInfoTrailingComma.py b/lldb/test/API/functionalities/gdb_remote_client/TestThreadInfoTrailingComma.py new file mode 100644 index 0000000..0035e1c --- /dev/null +++ b/lldb/test/API/functionalities/gdb_remote_client/TestThreadInfoTrailingComma.py @@ -0,0 +1,27 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + + +class TestThreadInfoTrailingComma(GDBRemoteTestBase): + + def test(self): + class MyResponder(MockGDBServerResponder): + def haltReason(self): + return "T02thread:1" + + def qfThreadInfo(self): + return "m1,2,3,4," + + self.server.responder = MyResponder() + target = self.dbg.CreateTarget('') + if self.TraceOn(): + self.runCmd("log enable gdb-remote packets") + self.addTearDownHook( + lambda: self.runCmd("log disable gdb-remote packets")) + process = self.connect(target) + self.assertEqual(process.GetThreadAtIndex(0).GetThreadID(), 1) + self.assertEqual(process.GetThreadAtIndex(1).GetThreadID(), 2) + self.assertEqual(process.GetThreadAtIndex(2).GetThreadID(), 3) + self.assertEqual(process.GetThreadAtIndex(3).GetThreadID(), 4) -- 2.7.4