svn commit: r329939 - vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests

Dimitry Andric dim at FreeBSD.org
Sat Feb 24 21:28:08 UTC 2018


Author: dim
Date: Sat Feb 24 21:28:02 2018
New Revision: 329939
URL: https://svnweb.freebsd.org/changeset/base/329939

Log:
  Vendor import of lldb release_60 branch r325932:
  https://llvm.org/svn/llvm-project/lldb/branches/release_60@325932

Modified:
  vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.cpp
  vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.h
  vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.cpp
  vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.h
  vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp

Modified: vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.cpp
==============================================================================
--- vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.cpp	Sat Feb 24 21:27:59 2018	(r329938)
+++ vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.cpp	Sat Feb 24 21:28:02 2018	(r329939)
@@ -8,16 +8,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "MessageObjects.h"
-#include "lldb/Utility/StructuredData.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/StringExtractor.h"
 #include "llvm/ADT/StringExtras.h"
 #include "gtest/gtest.h"
 
 using namespace lldb_private;
+using namespace lldb;
 using namespace llvm;
-using namespace llvm::support;
 namespace llgs_tests {
 
-Expected<ProcessInfo> ProcessInfo::Create(StringRef response) {
+Expected<ProcessInfo> ProcessInfo::create(StringRef response) {
   ProcessInfo process_info;
   auto elements_or_error = SplitUniquePairList("ProcessInfo", response);
   if (!elements_or_error)
@@ -53,36 +54,50 @@ Expected<ProcessInfo> ProcessInfo::Create(StringRef re
 
 lldb::pid_t ProcessInfo::GetPid() const { return m_pid; }
 
-endianness ProcessInfo::GetEndian() const { return m_endian; }
+support::endianness ProcessInfo::GetEndian() const { return m_endian; }
 
 //====== ThreadInfo ============================================================
-ThreadInfo::ThreadInfo(StringRef name, StringRef reason,
-                       const RegisterMap &registers, unsigned int signal)
-    : m_name(name.str()), m_reason(reason.str()), m_registers(registers),
-      m_signal(signal) {}
+ThreadInfo::ThreadInfo(StringRef name, StringRef reason, RegisterMap registers,
+                       unsigned int signal)
+    : m_name(name.str()), m_reason(reason.str()),
+      m_registers(std::move(registers)), m_signal(signal) {}
 
-StringRef ThreadInfo::ReadRegister(unsigned int register_id) const {
-  return m_registers.lookup(register_id);
+const RegisterValue *ThreadInfo::ReadRegister(unsigned int Id) const {
+  auto Iter = m_registers.find(Id);
+  return Iter == m_registers.end() ? nullptr : &Iter->getSecond();
 }
 
-Expected<uint64_t>
-ThreadInfo::ReadRegisterAsUint64(unsigned int register_id) const {
-  uint64_t value;
-  std::string value_str(m_registers.lookup(register_id));
-  if (!llvm::to_integer(value_str, value, 16))
-    return make_parsing_error("ThreadInfo value for register {0}: {1}",
-                              register_id, value_str);
+//====== JThreadsInfo ==========================================================
 
-  sys::swapByteOrder(value);
-  return value;
+Expected<RegisterMap>
+JThreadsInfo::parseRegisters(const StructuredData::Dictionary &Dict,
+                             ArrayRef<RegisterInfo> RegInfos) {
+  RegisterMap Result;
+
+  auto KeysObj = Dict.GetKeys();
+  auto Keys = KeysObj->GetAsArray();
+  for (size_t i = 0; i < Keys->GetSize(); i++) {
+    StringRef KeyStr, ValueStr;
+    Keys->GetItemAtIndexAsString(i, KeyStr);
+    Dict.GetValueForKeyAsString(KeyStr, ValueStr);
+    unsigned int Register;
+    if (!llvm::to_integer(KeyStr, Register, 10))
+      return make_parsing_error("JThreadsInfo: register key[{0}]", i);
+
+    auto RegValOr =
+        parseRegisterValue(RegInfos[Register], ValueStr, support::big);
+    if (!RegValOr)
+      return RegValOr.takeError();
+    Result[Register] = std::move(*RegValOr);
+  }
+  return std::move(Result);
 }
 
-//====== JThreadsInfo ==========================================================
-Expected<JThreadsInfo> JThreadsInfo::Create(StringRef response,
-                                            endianness endian) {
+Expected<JThreadsInfo> JThreadsInfo::create(StringRef Response,
+                                            ArrayRef<RegisterInfo> RegInfos) {
   JThreadsInfo jthreads_info;
 
-  StructuredData::ObjectSP json = StructuredData::ParseJSON(response);
+  StructuredData::ObjectSP json = StructuredData::ParseJSON(Response);
   StructuredData::Array *array = json->GetAsArray();
   if (!array)
     return make_parsing_error("JThreadsInfo: JSON array");
@@ -106,23 +121,11 @@ Expected<JThreadsInfo> JThreadsInfo::Create(StringRef 
     if (!register_dict)
       return make_parsing_error("JThreadsInfo: registers JSON obj");
 
-    RegisterMap registers;
-
-    auto keys_obj = register_dict->GetKeys();
-    auto keys = keys_obj->GetAsArray();
-    for (size_t i = 0; i < keys->GetSize(); i++) {
-      StringRef key_str, value_str;
-      keys->GetItemAtIndexAsString(i, key_str);
-      register_dict->GetValueForKeyAsString(key_str, value_str);
-      unsigned int register_id;
-      if (key_str.getAsInteger(10, register_id))
-        return make_parsing_error("JThreadsInfo: register key[{0}]", i);
-
-      registers[register_id] = value_str.str();
-    }
-
+    auto RegsOr = parseRegisters(*register_dict, RegInfos);
+    if (!RegsOr)
+      return RegsOr.takeError();
     jthreads_info.m_thread_infos[tid] =
-        ThreadInfo(name, reason, registers, signal);
+        ThreadInfo(name, reason, std::move(*RegsOr), signal);
   }
 
   return jthreads_info;
@@ -132,20 +135,130 @@ const ThreadInfoMap &JThreadsInfo::GetThreadInfos() co
   return m_thread_infos;
 }
 
+Expected<RegisterInfo> RegisterInfoParser::create(StringRef Response) {
+  auto ElementsOr = SplitUniquePairList("RegisterInfoParser", Response);
+  if (!ElementsOr)
+    return ElementsOr.takeError();
+  auto &Elements = *ElementsOr;
+
+  RegisterInfo Info = {
+      nullptr,       // Name
+      nullptr,       // Alt name
+      0,             // byte size
+      0,             // offset
+      eEncodingUint, // encoding
+      eFormatHex,    // format
+      {
+          LLDB_INVALID_REGNUM, // eh_frame reg num
+          LLDB_INVALID_REGNUM, // DWARF reg num
+          LLDB_INVALID_REGNUM, // generic reg num
+          LLDB_INVALID_REGNUM, // process plugin reg num
+          LLDB_INVALID_REGNUM  // native register number
+      },
+      NULL,
+      NULL,
+      NULL, // Dwarf expression opcode bytes pointer
+      0     // Dwarf expression opcode bytes length
+  };
+  Info.name = ConstString(Elements["name"]).GetCString();
+  if (!Info.name)
+    return make_parsing_error("qRegisterInfo: name");
+
+  Info.alt_name = ConstString(Elements["alt-name"]).GetCString();
+
+  if (!to_integer(Elements["bitsize"], Info.byte_size, 10))
+    return make_parsing_error("qRegisterInfo: bit-size");
+  Info.byte_size /= CHAR_BIT;
+
+  if (!to_integer(Elements["offset"], Info.byte_offset, 10))
+    return make_parsing_error("qRegisterInfo: offset");
+
+  Info.encoding = Args::StringToEncoding(Elements["encoding"]);
+  if (Info.encoding == eEncodingInvalid)
+    return make_parsing_error("qRegisterInfo: encoding");
+
+  Info.format = StringSwitch<Format>(Elements["format"])
+                    .Case("binary", eFormatBinary)
+                    .Case("decimal", eFormatDecimal)
+                    .Case("hex", eFormatHex)
+                    .Case("float", eFormatFloat)
+                    .Case("vector-sint8", eFormatVectorOfSInt8)
+                    .Case("vector-uint8", eFormatVectorOfUInt8)
+                    .Case("vector-sint16", eFormatVectorOfSInt16)
+                    .Case("vector-uint16", eFormatVectorOfUInt16)
+                    .Case("vector-sint32", eFormatVectorOfSInt32)
+                    .Case("vector-uint32", eFormatVectorOfUInt32)
+                    .Case("vector-float32", eFormatVectorOfFloat32)
+                    .Case("vector-uint64", eFormatVectorOfUInt64)
+                    .Case("vector-uint128", eFormatVectorOfUInt128)
+                    .Default(eFormatInvalid);
+  if (Info.format == eFormatInvalid)
+    return make_parsing_error("qRegisterInfo: format");
+
+  Info.kinds[eRegisterKindGeneric] =
+      Args::StringToGenericRegister(Elements["generic"]);
+
+  return std::move(Info);
+}
+
+Expected<RegisterValue> parseRegisterValue(const RegisterInfo &Info,
+                                           StringRef HexValue,
+                                           llvm::support::endianness Endian) {
+  SmallVector<uint8_t, 64> Bytes(HexValue.size() / 2);
+  StringExtractor(HexValue).GetHexBytes(Bytes, '\xcc');
+  RegisterValue Value;
+  Status ST;
+  Value.SetFromMemoryData(
+      &Info, Bytes.data(), Bytes.size(),
+      Endian == support::little ? eByteOrderLittle : eByteOrderBig, ST);
+  if (ST.Fail())
+    return ST.ToError();
+  return Value;
+}
+
 //====== StopReply =============================================================
 Expected<std::unique_ptr<StopReply>>
-StopReply::create(StringRef Response, llvm::support::endianness Endian) {
+StopReply::create(StringRef Response, llvm::support::endianness Endian,
+                  ArrayRef<RegisterInfo> RegInfos) {
   if (Response.size() < 3)
     return make_parsing_error("StopReply: Invalid packet");
   if (Response.consume_front("T"))
-    return StopReplyStop::create(Response, Endian);
+    return StopReplyStop::create(Response, Endian, RegInfos);
   if (Response.consume_front("W"))
     return StopReplyExit::create(Response);
   return make_parsing_error("StopReply: Invalid packet");
 }
 
+Expected<RegisterMap> StopReplyStop::parseRegisters(
+    const StringMap<SmallVector<StringRef, 2>> &Elements,
+    support::endianness Endian, ArrayRef<lldb_private::RegisterInfo> RegInfos) {
+
+  RegisterMap Result;
+  for (const auto &E : Elements) {
+    StringRef Key = E.getKey();
+    const auto &Val = E.getValue();
+    if (Key.size() != 2)
+      continue;
+
+    unsigned int Reg;
+    if (!to_integer(Key, Reg, 16))
+      continue;
+
+    if (Val.size() != 1)
+      return make_parsing_error(
+          "StopReplyStop: multiple entries for register field [{0:x}]", Reg);
+
+    auto RegValOr = parseRegisterValue(RegInfos[Reg], Val[0], Endian);
+    if (!RegValOr)
+      return RegValOr.takeError();
+    Result[Reg] = std::move(*RegValOr);
+  }
+  return std::move(Result);
+}
+
 Expected<std::unique_ptr<StopReplyStop>>
-StopReplyStop::create(StringRef Response, llvm::support::endianness Endian) {
+StopReplyStop::create(StringRef Response, support::endianness Endian,
+                      ArrayRef<RegisterInfo> RegInfos) {
   unsigned int Signal;
   StringRef SignalStr = Response.take_front(2);
   Response = Response.drop_front(2);
@@ -176,40 +289,31 @@ StopReplyStop::create(StringRef Response, llvm::suppor
   if (Threads.size() != Pcs.size())
     return make_parsing_error("StopReply: thread/PC count mismatch");
 
-  U64Map ThreadPcs;
+  RegisterMap ThreadPcs;
+  const RegisterInfo *PcInfo = find_if(RegInfos, [](const RegisterInfo &Info) {
+    return Info.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC;
+  });
+  assert(PcInfo);
+
   for (auto ThreadPc : zip(Threads, Pcs)) {
     lldb::tid_t Id;
-    uint64_t Pc;
     if (!to_integer(std::get<0>(ThreadPc), Id, 16))
       return make_parsing_error("StopReply: Thread id '{0}'",
                                 std::get<0>(ThreadPc));
-    if (!to_integer(std::get<1>(ThreadPc), Pc, 16))
-      return make_parsing_error("StopReply Thread Pc '{0}'",
-                                std::get<1>(ThreadPc));
 
-    ThreadPcs[Id] = Pc;
+    auto PcOr = parseRegisterValue(*PcInfo, std::get<1>(ThreadPc), Endian);
+    if (!PcOr)
+      return PcOr.takeError();
+    ThreadPcs[Id] = std::move(*PcOr);
   }
 
-  RegisterMap Registers;
-  for (const auto &E : Elements) {
-    StringRef Key = E.getKey();
-    const auto &Val = E.getValue();
-    if (Key.size() != 2)
-      continue;
+  auto RegistersOr = parseRegisters(Elements, Endian, RegInfos);
+  if (!RegistersOr)
+    return RegistersOr.takeError();
 
-    unsigned int Reg;
-    if (!to_integer(Key, Reg, 16))
-      continue;
-
-    if (Val.size() != 1)
-      return make_parsing_error(
-          "StopReply: multiple entries for register field [{0:x}]", Reg);
-
-    Registers[Reg] = Val[0].str();
-  }
-
-  return llvm::make_unique<StopReplyStop>(Signal, Thread, Name, ThreadPcs,
-                                          Registers, Reason);
+  return llvm::make_unique<StopReplyStop>(Signal, Thread, Name,
+                                          std::move(ThreadPcs),
+                                          std::move(*RegistersOr), Reason);
 }
 
 Expected<std::unique_ptr<StopReplyExit>>
@@ -251,3 +355,12 @@ StringMap<SmallVector<StringRef, 2>> SplitPairList(Str
   return pairs;
 }
 } // namespace llgs_tests
+
+std::ostream &lldb_private::operator<<(std::ostream &OS,
+                                       const RegisterValue &RegVal) {
+  ArrayRef<uint8_t> Bytes(static_cast<const uint8_t *>(RegVal.GetBytes()),
+                          RegVal.GetByteSize());
+  return OS << formatv("RegisterValue[{0}]: {1:@[x-2]}", RegVal.GetByteSize(),
+                       make_range(Bytes.begin(), Bytes.end()))
+                   .str();
+}

Modified: vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.h
==============================================================================
--- vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.h	Sat Feb 24 21:27:59 2018	(r329938)
+++ vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/MessageObjects.h	Sat Feb 24 21:28:02 2018	(r329939)
@@ -10,7 +10,9 @@
 #ifndef LLDB_SERVER_TESTS_MESSAGEOBJECTS_H
 #define LLDB_SERVER_TESTS_MESSAGEOBJECTS_H
 
+#include "lldb/Core/RegisterValue.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-types.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallString.h"
@@ -22,12 +24,13 @@
 namespace llgs_tests {
 class ThreadInfo;
 typedef llvm::DenseMap<uint64_t, ThreadInfo> ThreadInfoMap;
-typedef llvm::DenseMap<uint64_t, uint64_t> U64Map;
-typedef llvm::DenseMap<unsigned int, std::string> RegisterMap;
+typedef llvm::DenseMap<unsigned int, lldb_private::RegisterValue> RegisterMap;
 
-class ProcessInfo {
+template <typename T> struct Parser { using result_type = T; };
+
+class ProcessInfo : public Parser<ProcessInfo> {
 public:
-  static llvm::Expected<ProcessInfo> Create(llvm::StringRef response);
+  static llvm::Expected<ProcessInfo> create(llvm::StringRef response);
   lldb::pid_t GetPid() const;
   llvm::support::endianness GetEndian() const;
 
@@ -49,10 +52,9 @@ class ThreadInfo {
 public:
   ThreadInfo() = default;
   ThreadInfo(llvm::StringRef name, llvm::StringRef reason,
-             const RegisterMap &registers, unsigned int signal);
+             RegisterMap registers, unsigned int signal);
 
-  llvm::StringRef ReadRegister(unsigned int register_id) const;
-  llvm::Expected<uint64_t> ReadRegisterAsUint64(unsigned int register_id) const;
+  const lldb_private::RegisterValue *ReadRegister(unsigned int Id) const;
 
 private:
   std::string m_name;
@@ -61,25 +63,40 @@ class ThreadInfo {
   unsigned int m_signal;
 };
 
-class JThreadsInfo {
+class JThreadsInfo : public Parser<JThreadsInfo> {
 public:
-  static llvm::Expected<JThreadsInfo> Create(llvm::StringRef response,
-                                             llvm::support::endianness endian);
+  static llvm::Expected<JThreadsInfo>
+  create(llvm::StringRef Response,
+         llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);
 
   const ThreadInfoMap &GetThreadInfos() const;
 
 private:
+  static llvm::Expected<RegisterMap>
+  parseRegisters(const lldb_private::StructuredData::Dictionary &Dict,
+                 llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);
+
   JThreadsInfo() = default;
   ThreadInfoMap m_thread_infos;
 };
 
+struct RegisterInfoParser : public Parser<lldb_private::RegisterInfo> {
+  static llvm::Expected<lldb_private::RegisterInfo>
+  create(llvm::StringRef Response);
+};
+
+llvm::Expected<lldb_private::RegisterValue>
+parseRegisterValue(const lldb_private::RegisterInfo &Info,
+                   llvm::StringRef HexValue, llvm::support::endianness Endian);
+
 class StopReply {
 public:
   StopReply() = default;
   virtual ~StopReply() = default;
 
   static llvm::Expected<std::unique_ptr<StopReply>>
-  create(llvm::StringRef response, llvm::support::endianness endian);
+  create(llvm::StringRef Response, llvm::support::endianness Endian,
+         llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);
 
   // for llvm::cast<>
   virtual lldb_private::WaitStatus getKind() const = 0;
@@ -91,15 +108,17 @@ class StopReply { (public)
 class StopReplyStop : public StopReply {
 public:
   StopReplyStop(uint8_t Signal, lldb::tid_t ThreadId, llvm::StringRef Name,
-                U64Map ThreadPcs, RegisterMap Registers, llvm::StringRef Reason)
+                RegisterMap ThreadPcs, RegisterMap Registers,
+                llvm::StringRef Reason)
       : Signal(Signal), ThreadId(ThreadId), Name(Name),
         ThreadPcs(std::move(ThreadPcs)), Registers(std::move(Registers)),
         Reason(Reason) {}
 
   static llvm::Expected<std::unique_ptr<StopReplyStop>>
-  create(llvm::StringRef response, llvm::support::endianness endian);
+  create(llvm::StringRef Response, llvm::support::endianness Endian,
+         llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);
 
-  const U64Map &getThreadPcs() const { return ThreadPcs; }
+  const RegisterMap &getThreadPcs() const { return ThreadPcs; }
   lldb::tid_t getThreadId() const { return ThreadId; }
 
   // for llvm::cast<>
@@ -111,10 +130,15 @@ class StopReplyStop : public StopReply { (public)
   }
 
 private:
+  static llvm::Expected<RegisterMap> parseRegisters(
+      const llvm::StringMap<llvm::SmallVector<llvm::StringRef, 2>> &Elements,
+      llvm::support::endianness Endian,
+      llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);
+
   uint8_t Signal;
   lldb::tid_t ThreadId;
   std::string Name;
-  U64Map ThreadPcs;
+  RegisterMap ThreadPcs;
   RegisterMap Registers;
   std::string Reason;
 };
@@ -155,5 +179,9 @@ llvm::Error make_parsing_error(llvm::StringRef format,
 }
 
 } // namespace llgs_tests
+
+namespace lldb_private {
+std::ostream &operator<<(std::ostream &OS, const RegisterValue &RegVal);
+}
 
 #endif // LLDB_SERVER_TESTS_MESSAGEOBJECTS_H

Modified: vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.cpp
==============================================================================
--- vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.cpp	Sat Feb 24 21:27:59 2018	(r329938)
+++ vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.cpp	Sat Feb 24 21:28:02 2018	(r329939)
@@ -25,9 +25,8 @@
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm;
+using namespace llgs_tests;
 
-namespace llgs_tests {
-
 TestClient::TestClient(std::unique_ptr<Connection> Conn) {
   SetConnection(Conn.release());
 
@@ -106,7 +105,7 @@ Expected<std::unique_ptr<TestClient>> TestClient::laun
   auto Client = std::unique_ptr<TestClient>(new TestClient(std::move(Conn)));
 
   if (!InferiorArgs.empty()) {
-    if (Error E = Client->QueryProcessInfo())
+    if (Error E = Client->queryProcess())
       return std::move(E);
   }
 
@@ -136,7 +135,7 @@ Error TestClient::SetInferior(llvm::ArrayRef<std::stri
     return E;
   if (Error E = SendMessage("qLaunchSuccess"))
     return E;
-  if (Error E = QueryProcessInfo())
+  if (Error E = queryProcess())
     return E;
   return Error::success();
 }
@@ -155,19 +154,12 @@ Error TestClient::ContinueThread(unsigned long thread_
   return Continue(formatv("vCont;c:{0:x-}", thread_id).str());
 }
 
-const ProcessInfo &TestClient::GetProcessInfo() { return *m_process_info; }
+const llgs_tests::ProcessInfo &TestClient::GetProcessInfo() {
+  return *m_process_info;
+}
 
-Optional<JThreadsInfo> TestClient::GetJThreadsInfo() {
-  std::string response;
-  if (SendMessage("jThreadsInfo", response))
-    return llvm::None;
-  auto creation = JThreadsInfo::Create(response, m_process_info->GetEndian());
-  if (auto create_error = creation.takeError()) {
-    GTEST_LOG_(ERROR) << toString(std::move(create_error));
-    return llvm::None;
-  }
-
-  return std::move(*creation);
+Expected<JThreadsInfo> TestClient::GetJThreadsInfo() {
+  return SendMessage<JThreadsInfo>("jThreadsInfo", m_register_infos);
 }
 
 const StopReply &TestClient::GetLatestStopReply() {
@@ -209,42 +201,42 @@ Error TestClient::SendMessage(StringRef message, std::
 }
 
 unsigned int TestClient::GetPcRegisterId() {
-  if (m_pc_register != UINT_MAX)
-    return m_pc_register;
+  assert(m_pc_register != LLDB_INVALID_REGNUM);
+  return m_pc_register;
+}
 
-  for (unsigned int register_id = 0;; register_id++) {
-    std::string message = formatv("qRegisterInfo{0:x-}", register_id).str();
-    std::string response;
-    if (SendMessage(message, response)) {
-      GTEST_LOG_(ERROR) << "Unable to query register ID for PC register.";
-      return UINT_MAX;
-    }
+Error TestClient::qProcessInfo() {
+  m_process_info = None;
+  auto InfoOr = SendMessage<ProcessInfo>("qProcessInfo");
+  if (!InfoOr)
+    return InfoOr.takeError();
+  m_process_info = std::move(*InfoOr);
+  return Error::success();
+}
 
-    auto elements_or_error = SplitUniquePairList("GetPcRegisterId", response);
-    if (auto split_error = elements_or_error.takeError()) {
-      GTEST_LOG_(ERROR) << "GetPcRegisterId: Error splitting response: "
-                        << response;
-      return UINT_MAX;
-    }
-
-    auto elements = *elements_or_error;
-    if (elements["alt-name"] == "pc" || elements["generic"] == "pc") {
-      m_pc_register = register_id;
+Error TestClient::qRegisterInfos() {
+  for (unsigned int Reg = 0;; ++Reg) {
+    std::string Message = formatv("qRegisterInfo{0:x-}", Reg).str();
+    Expected<RegisterInfo> InfoOr = SendMessage<RegisterInfoParser>(Message);
+    if (!InfoOr) {
+      consumeError(InfoOr.takeError());
       break;
     }
+    m_register_infos.emplace_back(std::move(*InfoOr));
+    if (m_register_infos[Reg].kinds[eRegisterKindGeneric] ==
+        LLDB_REGNUM_GENERIC_PC)
+      m_pc_register = Reg;
   }
-
-  return m_pc_register;
+  if (m_pc_register == LLDB_INVALID_REGNUM)
+    return make_parsing_error("qRegisterInfo: generic");
+  return Error::success();
 }
 
-llvm::Error TestClient::QueryProcessInfo() {
-  std::string response;
-  if (Error E = SendMessage("qProcessInfo", response))
+Error TestClient::queryProcess() {
+  if (Error E = qProcessInfo())
     return E;
-  auto create_or_error = ProcessInfo::Create(response);
-  if (!create_or_error)
-    return create_or_error.takeError();
-  m_process_info = *create_or_error;
+  if (Error E = qRegisterInfos())
+    return E;
   return Error::success();
 }
 
@@ -254,7 +246,8 @@ Error TestClient::Continue(StringRef message) {
   std::string response;
   if (Error E = SendMessage(message, response))
     return E;
-  auto creation = StopReply::create(response, m_process_info->GetEndian());
+  auto creation = StopReply::create(response, m_process_info->GetEndian(),
+                                    m_register_infos);
   if (Error E = creation.takeError())
     return E;
 
@@ -273,5 +266,3 @@ Error TestClient::Continue(StringRef message) {
   }
   return Error::success();
 }
-
-} // namespace llgs_tests

Modified: vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.h
==============================================================================
--- vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.h	Sat Feb 24 21:27:59 2018	(r329938)
+++ vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/TestClient.h	Sat Feb 24 21:28:02 2018	(r329939)
@@ -59,7 +59,7 @@ class TestClient (public)
   llvm::Error ContinueAll();
   llvm::Error ContinueThread(unsigned long thread_id);
   const ProcessInfo &GetProcessInfo();
-  llvm::Optional<JThreadsInfo> GetJThreadsInfo();
+  llvm::Expected<JThreadsInfo> GetJThreadsInfo();
   const StopReply &GetLatestStopReply();
   template <typename T> llvm::Expected<const T &> GetLatestStopReplyAs() {
     assert(m_stop_reply);
@@ -74,12 +74,18 @@ class TestClient (public)
                           std::string &response_string);
   llvm::Error SendMessage(llvm::StringRef message, std::string &response_string,
                           PacketResult expected_result);
+
+  template <typename P, typename... CreateArgs>
+  llvm::Expected<typename P::result_type> SendMessage(llvm::StringRef Message,
+                                                      CreateArgs &&... Args);
   unsigned int GetPcRegisterId();
 
 private:
   TestClient(std::unique_ptr<lldb_private::Connection> Conn);
 
-  llvm::Error QueryProcessInfo();
+  llvm::Error qProcessInfo();
+  llvm::Error qRegisterInfos();
+  llvm::Error queryProcess();
   llvm::Error Continue(llvm::StringRef message);
   std::string FormatFailedResult(
       const std::string &message,
@@ -88,8 +94,18 @@ class TestClient (public)
 
   llvm::Optional<ProcessInfo> m_process_info;
   std::unique_ptr<StopReply> m_stop_reply;
-  unsigned int m_pc_register = UINT_MAX;
+  std::vector<lldb_private::RegisterInfo> m_register_infos;
+  unsigned int m_pc_register = LLDB_INVALID_REGNUM;
 };
+
+template <typename P, typename... CreateArgs>
+llvm::Expected<typename P::result_type>
+TestClient::SendMessage(llvm::StringRef Message, CreateArgs &&... Args) {
+  std::string ResponseText;
+  if (llvm::Error E = SendMessage(Message, ResponseText))
+    return std::move(E);
+  return P::create(ResponseText, std::forward<CreateArgs>(Args)...);
+}
 
 } // namespace llgs_tests
 

Modified: vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp
==============================================================================
--- vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp	Sat Feb 24 21:27:59 2018	(r329938)
+++ vendor/lldb/dist-release_60/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp	Sat Feb 24 21:28:02 2018	(r329939)
@@ -9,13 +9,19 @@
 
 #include "TestBase.h"
 #include "TestClient.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <string>
 
 using namespace llgs_tests;
+using namespace lldb_private;
 using namespace llvm;
+using namespace lldb;
+using namespace testing;
 
 TEST_F(StandardStartupTest, TestStopReplyContainsThreadPcs) {
   // This inferior spawns 4 threads, then forces a break.
@@ -29,7 +35,7 @@ TEST_F(StandardStartupTest, TestStopReplyContainsThrea
   ASSERT_NE(pc_reg, UINT_MAX);
 
   auto jthreads_info = Client->GetJThreadsInfo();
-  ASSERT_TRUE(jthreads_info);
+  ASSERT_THAT_EXPECTED(jthreads_info, Succeeded());
 
   auto stop_reply = Client->GetLatestStopReplyAs<StopReplyStop>();
   ASSERT_THAT_EXPECTED(stop_reply, Succeeded());
@@ -42,9 +48,7 @@ TEST_F(StandardStartupTest, TestStopReplyContainsThrea
     unsigned long tid = stop_reply_pc.first;
     ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end())
         << "Thread ID: " << tid << " not in JThreadsInfo.";
-    auto pc_value = thread_infos[tid].ReadRegisterAsUint64(pc_reg);
-    ASSERT_THAT_EXPECTED(pc_value, Succeeded());
-    ASSERT_EQ(stop_reply_pcs[tid], *pc_value)
-        << "Mismatched PC for thread: " << tid;
+    EXPECT_THAT(thread_infos[tid].ReadRegister(pc_reg),
+                Pointee(Eq(stop_reply_pc.second)));
   }
 }


More information about the svn-src-all mailing list