Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 999adb9

Browse files
committed
Merging r324722:
------------------------------------------------------------------------ r324722 | labath | 2018-02-09 10:40:03 +0100 (Fri, 09 Feb 2018) | 17 lines llgs-test: Parse and store register info recieved from lldb-server Summary: Right now the test client is not parsing register values correctly, which is manifesting itself in one test failing on 32-bit architectures (pr36013). This parses the information from the qRegisterInfo packets and stores it in the client, which will enable fixing the parsing in a follow up commit. I am also adding a new templated SendMessage overload, which enables one to send a message get a parsed response in a single call. Reviewers: eugene, davide Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D43076 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/lldb/branches/release_60@325562 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9a61218 commit 999adb9

File tree

5 files changed

+130
-41
lines changed

5 files changed

+130
-41
lines changed

unittests/tools/lldb-server/tests/MessageObjects.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "MessageObjects.h"
11+
#include "lldb/Interpreter/Args.h"
1112
#include "lldb/Utility/StructuredData.h"
1213
#include "llvm/ADT/StringExtras.h"
1314
#include "gtest/gtest.h"
1415

1516
using namespace lldb_private;
17+
using namespace lldb;
1618
using namespace llvm;
1719
using namespace llvm::support;
1820
namespace llgs_tests {
1921

20-
Expected<ProcessInfo> ProcessInfo::Create(StringRef response) {
22+
Expected<ProcessInfo> ProcessInfo::create(StringRef response) {
2123
ProcessInfo process_info;
2224
auto elements_or_error = SplitUniquePairList("ProcessInfo", response);
2325
if (!elements_or_error)
@@ -132,6 +134,72 @@ const ThreadInfoMap &JThreadsInfo::GetThreadInfos() const {
132134
return m_thread_infos;
133135
}
134136

137+
Expected<RegisterInfo> RegisterInfoParser::create(StringRef Response) {
138+
auto ElementsOr = SplitUniquePairList("RegisterInfoParser", Response);
139+
if (!ElementsOr)
140+
return ElementsOr.takeError();
141+
auto &Elements = *ElementsOr;
142+
143+
RegisterInfo Info = {
144+
nullptr, // Name
145+
nullptr, // Alt name
146+
0, // byte size
147+
0, // offset
148+
eEncodingUint, // encoding
149+
eFormatHex, // format
150+
{
151+
LLDB_INVALID_REGNUM, // eh_frame reg num
152+
LLDB_INVALID_REGNUM, // DWARF reg num
153+
LLDB_INVALID_REGNUM, // generic reg num
154+
LLDB_INVALID_REGNUM, // process plugin reg num
155+
LLDB_INVALID_REGNUM // native register number
156+
},
157+
NULL,
158+
NULL,
159+
NULL, // Dwarf expression opcode bytes pointer
160+
0 // Dwarf expression opcode bytes length
161+
};
162+
Info.name = ConstString(Elements["name"]).GetCString();
163+
if (!Info.name)
164+
return make_parsing_error("qRegisterInfo: name");
165+
166+
Info.alt_name = ConstString(Elements["alt-name"]).GetCString();
167+
168+
if (!to_integer(Elements["bitsize"], Info.byte_size, 10))
169+
return make_parsing_error("qRegisterInfo: bit-size");
170+
Info.byte_size /= CHAR_BIT;
171+
172+
if (!to_integer(Elements["offset"], Info.byte_offset, 10))
173+
return make_parsing_error("qRegisterInfo: offset");
174+
175+
Info.encoding = Args::StringToEncoding(Elements["encoding"]);
176+
if (Info.encoding == eEncodingInvalid)
177+
return make_parsing_error("qRegisterInfo: encoding");
178+
179+
Info.format = StringSwitch<Format>(Elements["format"])
180+
.Case("binary", eFormatBinary)
181+
.Case("decimal", eFormatDecimal)
182+
.Case("hex", eFormatHex)
183+
.Case("float", eFormatFloat)
184+
.Case("vector-sint8", eFormatVectorOfSInt8)
185+
.Case("vector-uint8", eFormatVectorOfUInt8)
186+
.Case("vector-sint16", eFormatVectorOfSInt16)
187+
.Case("vector-uint16", eFormatVectorOfUInt16)
188+
.Case("vector-sint32", eFormatVectorOfSInt32)
189+
.Case("vector-uint32", eFormatVectorOfUInt32)
190+
.Case("vector-float32", eFormatVectorOfFloat32)
191+
.Case("vector-uint64", eFormatVectorOfUInt64)
192+
.Case("vector-uint128", eFormatVectorOfUInt128)
193+
.Default(eFormatInvalid);
194+
if (Info.format == eFormatInvalid)
195+
return make_parsing_error("qRegisterInfo: format");
196+
197+
Info.kinds[eRegisterKindGeneric] =
198+
Args::StringToGenericRegister(Elements["generic"]);
199+
200+
return std::move(Info);
201+
}
202+
135203
//====== StopReply =============================================================
136204
Expected<std::unique_ptr<StopReply>>
137205
StopReply::create(StringRef Response, llvm::support::endianness Endian) {

unittests/tools/lldb-server/tests/MessageObjects.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ typedef llvm::DenseMap<uint64_t, ThreadInfo> ThreadInfoMap;
2525
typedef llvm::DenseMap<uint64_t, uint64_t> U64Map;
2626
typedef llvm::DenseMap<unsigned int, std::string> RegisterMap;
2727

28-
class ProcessInfo {
28+
template <typename T> struct Parser { using result_type = T; };
29+
30+
class ProcessInfo : public Parser<ProcessInfo> {
2931
public:
30-
static llvm::Expected<ProcessInfo> Create(llvm::StringRef response);
32+
static llvm::Expected<ProcessInfo> create(llvm::StringRef response);
3133
lldb::pid_t GetPid() const;
3234
llvm::support::endianness GetEndian() const;
3335

@@ -73,6 +75,11 @@ class JThreadsInfo {
7375
ThreadInfoMap m_thread_infos;
7476
};
7577

78+
struct RegisterInfoParser : public Parser<lldb_private::RegisterInfo> {
79+
static llvm::Expected<lldb_private::RegisterInfo>
80+
create(llvm::StringRef Response);
81+
};
82+
7683
class StopReply {
7784
public:
7885
StopReply() = default;

unittests/tools/lldb-server/tests/TestClient.cpp

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525
using namespace lldb;
2626
using namespace lldb_private;
2727
using namespace llvm;
28-
29-
namespace llgs_tests {
28+
using namespace llgs_tests;
3029

3130
TestClient::TestClient(std::unique_ptr<Connection> Conn) {
3231
SetConnection(Conn.release());
@@ -106,7 +105,7 @@ Expected<std::unique_ptr<TestClient>> TestClient::launchCustom(StringRef Log, Ar
106105
auto Client = std::unique_ptr<TestClient>(new TestClient(std::move(Conn)));
107106

108107
if (!InferiorArgs.empty()) {
109-
if (Error E = Client->QueryProcessInfo())
108+
if (Error E = Client->queryProcess())
110109
return std::move(E);
111110
}
112111

@@ -136,7 +135,7 @@ Error TestClient::SetInferior(llvm::ArrayRef<std::string> inferior_args) {
136135
return E;
137136
if (Error E = SendMessage("qLaunchSuccess"))
138137
return E;
139-
if (Error E = QueryProcessInfo())
138+
if (Error E = queryProcess())
140139
return E;
141140
return Error::success();
142141
}
@@ -155,7 +154,9 @@ Error TestClient::ContinueThread(unsigned long thread_id) {
155154
return Continue(formatv("vCont;c:{0:x-}", thread_id).str());
156155
}
157156

158-
const ProcessInfo &TestClient::GetProcessInfo() { return *m_process_info; }
157+
const llgs_tests::ProcessInfo &TestClient::GetProcessInfo() {
158+
return *m_process_info;
159+
}
159160

160161
Optional<JThreadsInfo> TestClient::GetJThreadsInfo() {
161162
std::string response;
@@ -209,42 +210,42 @@ Error TestClient::SendMessage(StringRef message, std::string &response_string,
209210
}
210211

211212
unsigned int TestClient::GetPcRegisterId() {
212-
if (m_pc_register != UINT_MAX)
213-
return m_pc_register;
214-
215-
for (unsigned int register_id = 0;; register_id++) {
216-
std::string message = formatv("qRegisterInfo{0:x-}", register_id).str();
217-
std::string response;
218-
if (SendMessage(message, response)) {
219-
GTEST_LOG_(ERROR) << "Unable to query register ID for PC register.";
220-
return UINT_MAX;
221-
}
213+
assert(m_pc_register != LLDB_INVALID_REGNUM);
214+
return m_pc_register;
215+
}
222216

223-
auto elements_or_error = SplitUniquePairList("GetPcRegisterId", response);
224-
if (auto split_error = elements_or_error.takeError()) {
225-
GTEST_LOG_(ERROR) << "GetPcRegisterId: Error splitting response: "
226-
<< response;
227-
return UINT_MAX;
228-
}
217+
Error TestClient::qProcessInfo() {
218+
m_process_info = None;
219+
auto InfoOr = SendMessage<ProcessInfo>("qProcessInfo");
220+
if (!InfoOr)
221+
return InfoOr.takeError();
222+
m_process_info = std::move(*InfoOr);
223+
return Error::success();
224+
}
229225

230-
auto elements = *elements_or_error;
231-
if (elements["alt-name"] == "pc" || elements["generic"] == "pc") {
232-
m_pc_register = register_id;
226+
Error TestClient::qRegisterInfos() {
227+
for (unsigned int Reg = 0;; ++Reg) {
228+
std::string Message = formatv("qRegisterInfo{0:x-}", Reg).str();
229+
Expected<RegisterInfo> InfoOr = SendMessage<RegisterInfoParser>(Message);
230+
if (!InfoOr) {
231+
consumeError(InfoOr.takeError());
233232
break;
234233
}
234+
m_register_infos.emplace_back(std::move(*InfoOr));
235+
if (m_register_infos[Reg].kinds[eRegisterKindGeneric] ==
236+
LLDB_REGNUM_GENERIC_PC)
237+
m_pc_register = Reg;
235238
}
236-
237-
return m_pc_register;
239+
if (m_pc_register == LLDB_INVALID_REGNUM)
240+
return make_parsing_error("qRegisterInfo: generic");
241+
return Error::success();
238242
}
239243

240-
llvm::Error TestClient::QueryProcessInfo() {
241-
std::string response;
242-
if (Error E = SendMessage("qProcessInfo", response))
244+
Error TestClient::queryProcess() {
245+
if (Error E = qProcessInfo())
246+
return E;
247+
if (Error E = qRegisterInfos())
243248
return E;
244-
auto create_or_error = ProcessInfo::Create(response);
245-
if (!create_or_error)
246-
return create_or_error.takeError();
247-
m_process_info = *create_or_error;
248249
return Error::success();
249250
}
250251

@@ -273,5 +274,3 @@ Error TestClient::Continue(StringRef message) {
273274
}
274275
return Error::success();
275276
}
276-
277-
} // namespace llgs_tests

unittests/tools/lldb-server/tests/TestClient.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,17 @@ class TestClient
7474
std::string &response_string);
7575
llvm::Error SendMessage(llvm::StringRef message, std::string &response_string,
7676
PacketResult expected_result);
77+
78+
template <typename P>
79+
llvm::Expected<typename P::result_type> SendMessage(llvm::StringRef Message);
7780
unsigned int GetPcRegisterId();
7881

7982
private:
8083
TestClient(std::unique_ptr<lldb_private::Connection> Conn);
8184

82-
llvm::Error QueryProcessInfo();
85+
llvm::Error qProcessInfo();
86+
llvm::Error qRegisterInfos();
87+
llvm::Error queryProcess();
8388
llvm::Error Continue(llvm::StringRef message);
8489
std::string FormatFailedResult(
8590
const std::string &message,
@@ -88,9 +93,19 @@ class TestClient
8893

8994
llvm::Optional<ProcessInfo> m_process_info;
9095
std::unique_ptr<StopReply> m_stop_reply;
91-
unsigned int m_pc_register = UINT_MAX;
96+
std::vector<lldb_private::RegisterInfo> m_register_infos;
97+
unsigned int m_pc_register = LLDB_INVALID_REGNUM;
9298
};
9399

100+
template <typename P>
101+
llvm::Expected<typename P::result_type>
102+
TestClient::SendMessage(llvm::StringRef Message) {
103+
std::string ResponseText;
104+
if (llvm::Error E = SendMessage(Message, ResponseText))
105+
return std::move(E);
106+
return P::create(ResponseText);
107+
}
108+
94109
} // namespace llgs_tests
95110

96111
#endif // LLDB_SERVER_TESTS_TESTCLIENT_H

unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ TEST_F(StandardStartupTest, TestStopReplyContainsThreadPcs) {
4444
<< "Thread ID: " << tid << " not in JThreadsInfo.";
4545
auto pc_value = thread_infos[tid].ReadRegisterAsUint64(pc_reg);
4646
ASSERT_THAT_EXPECTED(pc_value, Succeeded());
47-
ASSERT_EQ(stop_reply_pcs[tid], *pc_value)
47+
ASSERT_EQ(stop_reply_pc.second, *pc_value)
4848
<< "Mismatched PC for thread: " << tid;
4949
}
5050
}

0 commit comments

Comments
 (0)