mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.
This is a work-in-progress to provide minimal support for multiprocess GDB
protocol extension. For a start, a new function to parse thread-ids accounting
for the possible process id extension.
https://reviews.llvm.org/D98482
Files:
lldb/include/lldb/Utility/StringExtractor.h
lldb/source/Utility/StringExtractor.cpp
lldb/unittests/Utility/StringExtractorTest.cpp
Index: lldb/unittests/Utility/StringExtractorTest.cpp
===================================================================
--- lldb/unittests/Utility/StringExtractorTest.cpp
+++ lldb/unittests/Utility/StringExtractorTest.cpp
@@ -1,7 +1,9 @@
#include "gtest/gtest.h"
+#include "gmock/gmock.h"
#include <limits.h>
#include "lldb/Utility/StringExtractor.h"
+#include "lldb/lldb-defines.h"
namespace {
class StringExtractorTest : public ::testing::Test {};
@@ -695,3 +697,193 @@
ex.Reset("123456789ABCDEF000");
EXPECT_EQ(0ull, ex.GetHexMaxU64(false, 0));
}
+
+TEST_F(StringExtractorTest, GetPidTid) {
+ StringExtractor ex("");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ // invalid/short values
+
+ ex.Reset("narf");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset(";1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset(".1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("pnarf");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p;1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p.1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p1234.");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p1234.;1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("-2");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p1234.-2");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p-2");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p-2.1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ // overflow
+
+ ex.Reset("p10000000000000000");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p10000000000000000.0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("10000000000000000");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p0.10000000000000000");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ ex.Reset("p10000000000000000.10000000000000000");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, llvm::None));
+
+ // pure thread id
+
+ ex.Reset("0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, 0));
+
+ ex.Reset("-1");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, LLDB_INVALID_THREAD_ID));
+
+ ex.Reset("1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, 0x1234ULL));
+
+ ex.Reset("123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(llvm::None, 0x123456789ABCDEF0ULL));
+
+ // pure process id
+
+ ex.Reset("p0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0, llvm::None));
+
+ ex.Reset("p-1");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(LLDB_INVALID_PROCESS_ID, llvm::None));
+
+ ex.Reset("p1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x1234ULL, llvm::None));
+
+ ex.Reset("p123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x123456789ABCDEF0ULL, llvm::None));
+
+ // combined thread id + process id
+
+ ex.Reset("p0.0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0, 0));
+
+ ex.Reset("p0.-1");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0, LLDB_INVALID_THREAD_ID));
+
+ // NB: technically, specific thread with unspecified process is invalid
+ // but we do not filter that in StringExtractor
+
+ ex.Reset("p0.1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0, 0x1234ULL));
+
+ ex.Reset("p0.123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0, 0x123456789ABCDEF0ULL));
+
+ ex.Reset("p-1.0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(LLDB_INVALID_PROCESS_ID, 0));
+
+ ex.Reset("p-1.-1");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID));
+
+ ex.Reset("p-1.1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(LLDB_INVALID_PROCESS_ID, 0x1234ULL));
+
+ ex.Reset("p-1.123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(LLDB_INVALID_PROCESS_ID, 0x123456789ABCDEF0ULL));
+
+ ex.Reset("p1234.0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x1234ULL, 0));
+
+ ex.Reset("p1234.-1");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x1234ULL, LLDB_INVALID_THREAD_ID));
+
+ ex.Reset("p1234.123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x1234ULL, 0x123456789ABCDEF0ULL));
+
+ ex.Reset("p123456789ABCDEF0.0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x123456789ABCDEF0ULL, 0));
+
+ ex.Reset("p123456789ABCDEF0.-1");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x123456789ABCDEF0ULL, LLDB_INVALID_THREAD_ID));
+
+ ex.Reset("p123456789ABCDEF0.1234");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x123456789ABCDEF0ULL, 0x1234ULL));
+
+ ex.Reset("p123456789ABCDEF0.123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x123456789ABCDEF0ULL, 0x123456789ABCDEF0ULL));
+
+ ex.Reset("p123456789ABCDEF0.123456789ABCDEF0");
+ EXPECT_THAT(ex.GetPidTid(),
+ ::testing::Pair(0x123456789ABCDEF0ULL, 0x123456789ABCDEF0ULL));
+}
Index: lldb/source/Utility/StringExtractor.cpp
===================================================================
--- lldb/source/Utility/StringExtractor.cpp
+++ lldb/source/Utility/StringExtractor.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Utility/StringExtractor.h"
+#include "lldb/lldb-defines.h"
#include "llvm/ADT/StringExtras.h"
#include <tuple>
@@ -369,3 +370,56 @@
while (m_index < n && llvm::isSpace(m_packet[m_index]))
++m_index;
}
+
+std::pair<llvm::Optional<lldb::pid_t>, llvm::Optional<lldb::tid_t>>
+StringExtractor::GetPidTid() {
+ llvm::Optional<lldb::pid_t> pid = llvm::None;
+ llvm::Optional<lldb::tid_t> tid = llvm::None;
+
+ SkipSpaces();
+ if (m_index < m_packet.size() && m_packet[m_index] == 'p') {
+ // process identifier
+ ++m_index;
+ SkipSpaces();
+ if (m_index + 1 < m_packet.size() && m_packet[m_index] == '-' &&
+ m_packet[m_index + 1] == '1') {
+ // -1 is a special case
+ m_index += 2;
+ pid = LLDB_INVALID_PROCESS_ID;
+ } else {
+ uint64_t prev_index = m_index;
+ pid = GetHexMaxU64(false, 0);
+ if (m_index == prev_index || m_index == UINT64_MAX) {
+ // if index was not incremented or we overflowed, it failed
+ pid = llvm::None;
+ return {pid, tid};
+ }
+ }
+
+ // "." must follow if we expect TID too
+ SkipSpaces();
+ if (!(m_index < m_packet.size() && m_packet[m_index] == '.'))
+ return {pid, tid};
+ ++m_index;
+ SkipSpaces();
+ }
+
+ // thread identifier
+ if (m_index + 1 < m_packet.size() && m_packet[m_index] == '-' &&
+ m_packet[m_index + 1] == '1') {
+ // -1 is a special case
+ m_index += 2;
+ tid = LLDB_INVALID_PROCESS_ID;
+ } else {
+ uint64_t prev_index = m_index;
+ tid = GetHexMaxU64(false, 0);
+ if (m_index == prev_index || m_index == UINT64_MAX) {
+ // if index was not incremented or we overflowed, it failed
+ // (also reset pid since the value is incorrect)
+ pid = llvm::None;
+ tid = llvm::None;
+ }
+ }
+
+ return {pid, tid};
+}
Index: lldb/include/lldb/Utility/StringExtractor.h
===================================================================
--- lldb/include/lldb/Utility/StringExtractor.h
+++ lldb/include/lldb/Utility/StringExtractor.h
@@ -10,8 +10,11 @@
#define LLDB_UTILITY_STRINGEXTRACTOR_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include "lldb/lldb-types.h"
+
#include <stddef.h>
#include <stdint.h>
#include <string>
@@ -95,6 +98,13 @@
size_t GetHexByteStringTerminatedBy(std::string &str, char terminator);
+ // Read thread-id in the <tid> | "p" <pid> ["." <tid>] format, where <pid>
+ // and <tid> can be either "-1", "0" or a hex-encoded number. Note that
+ // the function does not check for incorrect values such as -1.<tid != -1>.
+ // A pair of (llvm::None, llvm::None) is returned for malformed input.
+ std::pair<llvm::Optional<lldb::pid_t>, llvm::Optional<lldb::tid_t>>
+ GetPidTid();
+
bool ConsumeFront(const llvm::StringRef &str);
const char *Peek() {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits