[Lldb-commits] [lldb] r320820 - llgs-tests: Add support for "exit" stop-reply packets
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Fri Dec 15 07:19:45 PST 2017
Author: labath
Date: Fri Dec 15 07:19:45 2017
New Revision: 320820
URL: http://llvm.org/viewvc/llvm-project?rev=320820&view=rev
Log:
llgs-tests: Add support for "exit" stop-reply packets
Summary:
This makes StopReply class abstract, so that we can represent different
types of stop replies such as StopReplyStop and StopReplyExit (there
should also be a StopReplySignal, but I don't need that right now so I
haven't implemented it yet).
This prepares the ground for a new test I'm writing.
Reviewers: eugene, zturner
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D41067
Modified:
lldb/trunk/include/lldb/Host/Host.h
lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp
lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.h
lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp
lldb/trunk/unittests/tools/lldb-server/tests/TestClient.h
lldb/trunk/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp
Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=320820&r1=320819&r2=320820&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Fri Dec 15 07:19:45 2017
@@ -48,6 +48,12 @@ struct WaitStatus {
static WaitStatus Decode(int wstatus);
};
+inline bool operator==(WaitStatus a, WaitStatus b) {
+ return a.type == b.type && a.status == b.status;
+}
+
+inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
+
//----------------------------------------------------------------------
/// @class Host Host.h "lldb/Host/Host.h"
/// @brief A class that provides host computer information.
Modified: lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp?rev=320820&r1=320819&r2=320820&view=diff
==============================================================================
--- lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp (original)
+++ lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp Fri Dec 15 07:19:45 2017
@@ -133,70 +133,91 @@ const ThreadInfoMap &JThreadsInfo::GetTh
}
//====== StopReply =============================================================
-const U64Map &StopReply::GetThreadPcs() const { return m_thread_pcs; }
-
-Expected<StopReply> StopReply::Create(StringRef response,
- llvm::support::endianness endian) {
- if (response.size() < 3 || !response.consume_front("T"))
+Expected<std::unique_ptr<StopReply>>
+StopReply::create(StringRef Response, llvm::support::endianness Endian) {
+ if (Response.size() < 3)
return make_parsing_error("StopReply: Invalid packet");
+ if (Response.consume_front("T"))
+ return StopReplyStop::create(Response, Endian);
+ if (Response.consume_front("W"))
+ return StopReplyExit::create(Response);
+ return make_parsing_error("StopReply: Invalid packet");
+}
- StopReply stop_reply;
-
- StringRef signal = response.take_front(2);
- response = response.drop_front(2);
- if (!llvm::to_integer(signal, stop_reply.m_signal, 16))
+Expected<std::unique_ptr<StopReplyStop>>
+StopReplyStop::create(StringRef Response, llvm::support::endianness Endian) {
+ unsigned int Signal;
+ StringRef SignalStr = Response.take_front(2);
+ Response = Response.drop_front(2);
+ if (!to_integer(SignalStr, Signal, 16))
return make_parsing_error("StopReply: stop signal");
- auto elements = SplitPairList(response);
- for (StringRef field :
+ auto Elements = SplitPairList(Response);
+ for (StringRef Field :
{"name", "reason", "thread", "threads", "thread-pcs"}) {
// This will insert an empty field if there is none. In the future, we
// should probably differentiate between these fields not being present and
// them being empty, but right now no tests depends on this.
- if (elements.insert({field, {""}}).first->second.size() != 1)
+ if (Elements.insert({Field, {""}}).first->second.size() != 1)
return make_parsing_error(
- "StopReply: got multiple responses for the {0} field", field);
+ "StopReply: got multiple responses for the {0} field", Field);
}
- stop_reply.m_name = elements["name"][0];
- stop_reply.m_reason = elements["reason"][0];
+ StringRef Name = Elements["name"][0];
+ StringRef Reason = Elements["reason"][0];
- if (!llvm::to_integer(elements["thread"][0], stop_reply.m_thread, 16))
+ lldb::tid_t Thread;
+ if (!to_integer(Elements["thread"][0], Thread, 16))
return make_parsing_error("StopReply: thread");
- SmallVector<StringRef, 20> threads;
- SmallVector<StringRef, 20> pcs;
- elements["threads"][0].split(threads, ',');
- elements["thread-pcs"][0].split(pcs, ',');
- if (threads.size() != pcs.size())
+ SmallVector<StringRef, 20> Threads;
+ SmallVector<StringRef, 20> Pcs;
+ Elements["threads"][0].split(Threads, ',');
+ Elements["thread-pcs"][0].split(Pcs, ',');
+ if (Threads.size() != Pcs.size())
return make_parsing_error("StopReply: thread/PC count mismatch");
- for (size_t i = 0; i < threads.size(); i++) {
- lldb::tid_t thread_id;
- uint64_t pc;
- if (threads[i].getAsInteger(16, thread_id))
- return make_parsing_error("StopReply: thread ID at [{0}].", i);
- if (pcs[i].getAsInteger(16, pc))
- return make_parsing_error("StopReply: thread PC at [{0}].", i);
+ U64Map ThreadPcs;
+ 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));
- stop_reply.m_thread_pcs[thread_id] = pc;
+ ThreadPcs[Id] = Pc;
}
- for (auto i = elements.begin(); i != elements.end(); i++) {
- StringRef key = i->getKey();
- const auto &val = i->getValue();
- if (key.size() == 2) {
- unsigned int reg;
- if (key.getAsInteger(16, reg))
- continue;
- if (val.size() != 1)
- return make_parsing_error(
- "StopReply: multiple entries for register field [{0:x}]", reg);
+ RegisterMap Registers;
+ 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;
- stop_reply.m_registers[reg] = val[0].str();
- }
+ if (Val.size() != 1)
+ return make_parsing_error(
+ "StopReply: multiple entries for register field [{0:x}]", Reg);
+
+ Registers[Reg] = Val[0].str();
}
- return stop_reply;
+ return llvm::make_unique<StopReplyStop>(Signal, Thread, Name, ThreadPcs,
+ Registers, Reason);
+}
+
+Expected<std::unique_ptr<StopReplyExit>>
+StopReplyExit::create(StringRef Response) {
+ uint8_t Status;
+ if (!to_integer(Response, Status, 16))
+ return make_parsing_error("StopReply: exit status");
+ return llvm::make_unique<StopReplyExit>(Status);
}
//====== Globals ===============================================================
Modified: lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.h?rev=320820&r1=320819&r2=320820&view=diff
==============================================================================
--- lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.h (original)
+++ lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.h Fri Dec 15 07:19:45 2017
@@ -10,6 +10,7 @@
#ifndef LLDB_SERVER_TESTS_MESSAGEOBJECTS_H
#define LLDB_SERVER_TESTS_MESSAGEOBJECTS_H
+#include "lldb/Host/Host.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
@@ -74,20 +75,67 @@ private:
class StopReply {
public:
- static llvm::Expected<StopReply> Create(llvm::StringRef response,
- llvm::support::endianness endian);
- const U64Map &GetThreadPcs() const;
+ StopReply() = default;
+ virtual ~StopReply() = default;
+
+ static llvm::Expected<std::unique_ptr<StopReply>>
+ create(llvm::StringRef response, llvm::support::endianness endian);
+
+ // for llvm::cast<>
+ virtual lldb_private::WaitStatus getKind() const = 0;
+
+ StopReply(const StopReply &) = delete;
+ void operator=(const StopReply &) = delete;
+};
+
+class StopReplyStop : public StopReply {
+public:
+ StopReplyStop(uint8_t Signal, lldb::tid_t ThreadId, llvm::StringRef Name,
+ U64Map 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);
+
+ const U64Map &getThreadPcs() const { return ThreadPcs; }
+ lldb::tid_t getThreadId() const { return ThreadId; }
+
+ // for llvm::cast<>
+ lldb_private::WaitStatus getKind() const override {
+ return lldb_private::WaitStatus{lldb_private::WaitStatus::Stop, Signal};
+ }
+ static bool classof(const StopReply *R) {
+ return R->getKind().type == lldb_private::WaitStatus::Stop;
+ }
private:
- StopReply() = default;
- void ParseResponse(llvm::StringRef response,
- llvm::support::endianness endian);
- unsigned int m_signal;
- lldb::tid_t m_thread;
- std::string m_name;
- U64Map m_thread_pcs;
- RegisterMap m_registers;
- std::string m_reason;
+ uint8_t Signal;
+ lldb::tid_t ThreadId;
+ std::string Name;
+ U64Map ThreadPcs;
+ RegisterMap Registers;
+ std::string Reason;
+};
+
+class StopReplyExit : public StopReply {
+public:
+ explicit StopReplyExit(uint8_t Status) : Status(Status) {}
+
+ static llvm::Expected<std::unique_ptr<StopReplyExit>>
+ create(llvm::StringRef response);
+
+ // for llvm::cast<>
+ lldb_private::WaitStatus getKind() const override {
+ return lldb_private::WaitStatus{lldb_private::WaitStatus::Exit, Status};
+ }
+ static bool classof(const StopReply *R) {
+ return R->getKind().type == lldb_private::WaitStatus::Exit;
+ }
+
+private:
+ uint8_t Status;
};
// Common functions for parsing packet data.
Modified: lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp?rev=320820&r1=320819&r2=320820&view=diff
==============================================================================
--- lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp (original)
+++ lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp Fri Dec 15 07:19:45 2017
@@ -154,7 +154,8 @@ Optional<JThreadsInfo> TestClient::GetJT
}
const StopReply &TestClient::GetLatestStopReply() {
- return m_stop_reply.getValue();
+ assert(m_stop_reply);
+ return *m_stop_reply;
}
Error TestClient::SendMessage(StringRef message) {
@@ -236,7 +237,7 @@ Error TestClient::Continue(StringRef mes
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());
if (Error E = creation.takeError())
return E;
Modified: lldb/trunk/unittests/tools/lldb-server/tests/TestClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/tools/lldb-server/tests/TestClient.h?rev=320820&r1=320819&r2=320820&view=diff
==============================================================================
--- lldb/trunk/unittests/tools/lldb-server/tests/TestClient.h (original)
+++ lldb/trunk/unittests/tools/lldb-server/tests/TestClient.h Fri Dec 15 07:19:45 2017
@@ -16,6 +16,8 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Connection.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/FormatVariadic.h"
#include <memory>
#include <string>
@@ -44,6 +46,14 @@ public:
const ProcessInfo &GetProcessInfo();
llvm::Optional<JThreadsInfo> GetJThreadsInfo();
const StopReply &GetLatestStopReply();
+ template <typename T> llvm::Expected<const T &> GetLatestStopReplyAs() {
+ assert(m_stop_reply);
+ if (const auto *Reply = llvm::dyn_cast<T>(m_stop_reply.get()))
+ return *Reply;
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("Unexpected Stop Reply {0}", m_stop_reply->getKind()),
+ llvm::inconvertibleErrorCode());
+ }
llvm::Error SendMessage(llvm::StringRef message);
llvm::Error SendMessage(llvm::StringRef message,
std::string &response_string);
@@ -62,7 +72,7 @@ private:
result);
llvm::Optional<ProcessInfo> m_process_info;
- llvm::Optional<StopReply> m_stop_reply;
+ std::unique_ptr<StopReply> m_stop_reply;
unsigned int m_pc_register = UINT_MAX;
};
Modified: lldb/trunk/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp?rev=320820&r1=320819&r2=320820&view=diff
==============================================================================
--- lldb/trunk/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp (original)
+++ lldb/trunk/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Fri Dec 15 07:19:45 2017
@@ -31,8 +31,9 @@ TEST_F(StandardStartupTest, TestStopRepl
auto jthreads_info = Client->GetJThreadsInfo();
ASSERT_TRUE(jthreads_info);
- auto stop_reply = Client->GetLatestStopReply();
- auto stop_reply_pcs = stop_reply.GetThreadPcs();
+ auto stop_reply = Client->GetLatestStopReplyAs<StopReplyStop>();
+ ASSERT_THAT_EXPECTED(stop_reply, Succeeded());
+ auto stop_reply_pcs = stop_reply->getThreadPcs();
auto thread_infos = jthreads_info->GetThreadInfos();
ASSERT_EQ(stop_reply_pcs.size(), thread_infos.size())
<< "Thread count mismatch.";
More information about the lldb-commits
mailing list