[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors created this revision. Herald added a subscriber: mgorny. This is a new C++ test framework based on Google Test, and one working example test. The intention is to replace the existing tests in packages/Python/lldbsuite/test/tools/lldb-server/ with this suite and use this framework for all new client server tests. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/.gitignore unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/TestClientException.cpp unittests/tools/lldb-server/tests/TestClientException.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp unittests/tools/lldb-server/tests/gtest_common.h Index: unittests/tools/lldb-server/tests/gtest_common.h === --- /dev/null +++ unittests/tools/lldb-server/tests/gtest_common.h @@ -0,0 +1,26 @@ +//===-- gtest_common.h --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#if defined(LLDB_GTEST_COMMON_H) +#error "gtest_common.h should not be included manually." +#else +#define LLDB_GTEST_COMMON_H +#endif + +// This header file is force included by all of LLDB's unittest compilation +// units. Be very leary about putting anything in this file. + +#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0) +// Due to a bug in , when _HAS_EXCEPTIONS == 0 the header will try to +// call +// uncaught_exception() without having a declaration for it. The fix for this +// is +// to manually #include , which contains this declaration. +#include +#endif Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,52 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace std; +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + JThreadsInfo jthreads_info = client.GetJThreadsInfo(); + auto stop_reply = client.GetLatestStopReply(); + 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."; + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClientException.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClientException.h @@ -0,0 +1,21 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +namespace CommunicationTests { +class TestClientException : public std::exception { +public: + TestClientException(const std::string& message); + const char* what() const noexcept; +private: + std::string message; +}; +}
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 43 inline comments as done. jmajors added a comment. Every comment should either be marked done, with an accompanying code change, or have a reply comment. Comment at: unittests/CMakeLists.txt:57 add_subdirectory(Breakpoint) +add_subdirectory(tools) add_subdirectory(Core) takuto.ikuta wrote: > better to sort alphabetically? > Using tools instead of Tools intentionally? I'm following the naming and case of the source directories. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:61-63 +string name; +thread_info->GetValueForKeyAsString("name", name); +string reason; zturner wrote: > `StringRef name, reason;` There is no GetValueForKeyAsStringRef(). I need a std::string to populate. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:77-79 + string key_str; + keys->GetItemAtIndexAsString(i, key_str); + string value_str; zturner wrote: > `StringRef key_str, value_str;` These need to be strings for the same reason as above. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:83-88 + if (endian == LITTLE) { +registers[register_id] = SwitchEndian(value_str); + } + else { +registers[register_id] = stoul(value_str, nullptr, 16); + } zturner wrote: > This code block is unnecessary. > > ``` > unsigned long X; > if (!value_str.getAsInteger(X)) > return some error; > llvm::support::endian::write(®isters[register_id], X, endian); > ``` > > By using llvm endianness functions you can just delete the `SwitchEndian()` > function entirely, as it's not needed. These endian functions don't work here. getAsInteger() assumes the number is in human reading order (i.e. big endian). So it's converting the little endian string as if it's big, then converting that little endian long to another little endian long, which does nothing. I need something that reverses the string first. What do you think about adding a version of StringRef::getAsInteger that accepts an endianness parameter? Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:122-123 + while (true) { +stringstream ss; +ss << hex << setw(2) << setfill('0') << register_id; +string hex_id = ss.str(); zturner wrote: > Use `llvm::raw_string_ostream` or `raw_svector_ostream` instead of > `stringstream`. I don't see anything in either class or their ancestors that will format the number as a two nibble hex value. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:133 + + for (auto i = elements.begin(); i != elements.end(); i++) { +if (i->first[0] == 'T' && i->first.substr(3, 6) == "thread") { takuto.ikuta wrote: > Why not range based for? That container lacks a necessary constructor. Comment at: unittests/tools/lldb-server/tests/MessageObjects.h:82-87 +// Common functions for parsing packet data. +std::unordered_map SplitPairList(const std::string& s); +std::vector SplitList(const std::string& s, char delimeter); +std::pair SplitPair(const std::string& s); +std::string HexDecode(const std::string& hex_encoded); +unsigned long SwitchEndian(const std::string& little_endian); tberghammer wrote: > Does these have to be global? Can we make them local to the .cc file > (anonymous namespace or file static variable)? I use one of them in the TestClient.cpp file. I could make the other local. Comment at: unittests/tools/lldb-server/tests/MessageObjects.h:83 +// Common functions for parsing packet data. +std::unordered_map SplitPairList(const std::string& s); +std::vector SplitList(const std::string& s, char delimeter); zturner wrote: > tberghammer wrote: > > What if the key isn't unique? > Return an `llvm::StringMap` here. Also the argument should be a > `StringRef`. I was working on the assumption that the keys in lldb response packets would be unique, and that it would map a key to a list of values if it needed to have a one:many relationship. Are there any that have duplicate keys? Comment at: unittests/tools/lldb-server/tests/TestClient.cpp:65 + + sleep(5); // TODO: Sleep is bad. Can I wait for it to start? + SendAck(); // Send this as a handshake. labath wrote: > Since you're using reverse-connect (which is good), you should be able to > detect that the server is ready by the fact it has connected to you. Are you implying that that connection is a side effect of something I've called, or that there's another function to call? When I didn't have this sleep here, I got a very generic error on all subsequent communication. Comment at: unittests/tools/lldb-server/tests/TestClient.cpp:70 +void TestClient::StopDebugger() { + Host::Kill(server_process_info.GetProce
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98673. jmajors marked an inline comment as done. jmajors added a comment. Made changes based on feedback. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,52 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + std::shared_ptr jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,55 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + std::shared_ptr GetProcessInfo(); + std::shared_ptr GetJThreadsInfo(); + std::shared_ptr GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::shared_ptr process_info; + std::shared_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned int pc_register; +}; +} Index: unittests/tools/lldb-server/tests/TestClient.cpp === --- /dev
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 2 inline comments as done. jmajors added inline comments. Comment at: unittests/tools/lldb-server/inferior/thread_inferior.cpp:21 + + LLVM_BUILTIN_DEBUGTRAP; + delay = false; zturner wrote: > This will work on MSVC and presumably clang. I'm not sure about gcc. Is > that sufficient for your needs? Do you know if gcc has the > `__builtin_debugtrap` intrinsic? Do we use gcc to build/test lldb? If not, then it shouldn't be an issue. If we ever change our compiler of choice, we can always change this to match. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98675. jmajors added a comment. Feedback changes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,52 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + std::shared_ptr jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,55 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + std::shared_ptr GetProcessInfo(); + std::shared_ptr GetJThreadsInfo(); + std::shared_ptr GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::shared_ptr process_info; + std::shared_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned int pc_register; +}; +} Index: unittests/tools/lldb-server/tests/TestClient.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.c
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 5 inline comments as done. jmajors added inline comments. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:200 + + return std::stoul(big_endian, nullptr, 16); +} krytarowski wrote: > Throws exceptions. I didn't change this, because I'm expecting to remove the whole function. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:83-88 + if (endian == LITTLE) { +registers[register_id] = SwitchEndian(value_str); + } + else { +registers[register_id] = stoul(value_str, nullptr, 16); + } zturner wrote: > jmajors wrote: > > zturner wrote: > > > This code block is unnecessary. > > > > > > ``` > > > unsigned long X; > > > if (!value_str.getAsInteger(X)) > > > return some error; > > > llvm::support::endian::write(®isters[register_id], X, endian); > > > ``` > > > > > > By using llvm endianness functions you can just delete the > > > `SwitchEndian()` function entirely, as it's not needed. > > These endian functions don't work here. getAsInteger() assumes the number > > is in human reading order (i.e. big endian). So it's converting the little > > endian string as if it's big, then converting that little endian long to > > another little endian long, which does nothing. > > I need something that reverses the string first. > > > > What do you think about adding a version of StringRef::getAsInteger that > > accepts an endianness parameter? > Hmm.. What about this? > > ``` > unsigned long X; > if (!value_str.getAsInteger(X)) > return some error; > sys::swapByteOrder(X); > ``` > > It shouldn't matter if you swap the bytes in the string before doing the > translation, or swap the bytes in the number after doing the translation > should it? It doesn't matter when I do it. The issue with the other functions was they were converting target to host, when both were little. For string parsing, it needs target to big to string, or target to string to big. Comment at: unittests/tools/lldb-server/tests/TestClient.cpp:76-80 + for (size_t i = 0; i < inferior_args.size(); i++) { +if (i > 0) command << ','; +string hex_encoded = HexEncode(inferior_args[i]); +command << hex_encoded.size() << ',' << i << ',' << hex_encoded; + } zturner wrote: > `for (const auto &arg : inferior_args)` I need an parameter index to pass to the command, so the classic for loop makes more sense. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98691. jmajors marked an inline comment as done. jmajors added a comment. More feedback changes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,52 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + std::shared_ptr jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,55 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + std::shared_ptr GetProcessInfo(); + std::shared_ptr GetJThreadsInfo(); + std::shared_ptr GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::shared_ptr process_info; + std::shared_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned int pc_register; +}; +} Index: unittests/tools/lldb-server/tests/TestClient.cpp === --- /dev/null +++
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked an inline comment as done. jmajors added a comment. I cleaned up the includes. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98702. jmajors added a comment. Cleaned up the includes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,50 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,55 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + std::shared_ptr GetProcessInfo(); + std::shared_ptr GetJThreadsInfo(); + std::shared_ptr GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::shared_ptr process_info; + std::shared_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned int pc_register; +}; +} Index: unittests/tools/lldb-server/tests/TestClient.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.cpp @@ -0,0 +1,228
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 17 inline comments as done. jmajors added a comment. More feedback changes. Comment at: unittests/tools/lldb-server/inferior/thread_inferior.cpp:21 + + LLVM_BUILTIN_DEBUGTRAP; + delay = false; krytarowski wrote: > jmajors wrote: > > zturner wrote: > > > This will work on MSVC and presumably clang. I'm not sure about gcc. Is > > > that sufficient for your needs? Do you know if gcc has the > > > `__builtin_debugtrap` intrinsic? > > Do we use gcc to build/test lldb? If not, then it shouldn't be an issue. If > > we ever change our compiler of choice, we can always change this to match. > Yes, we use and support GCC with libstdc++ to build LLDB including tests. At > least on NetBSD. Is there a gcc equivalent, that I could wrap in some #ifdefs? Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:83-88 + if (endian == LITTLE) { +registers[register_id] = SwitchEndian(value_str); + } + else { +registers[register_id] = stoul(value_str, nullptr, 16); + } krytarowski wrote: > zturner wrote: > > jmajors wrote: > > > zturner wrote: > > > > jmajors wrote: > > > > > zturner wrote: > > > > > > This code block is unnecessary. > > > > > > > > > > > > ``` > > > > > > unsigned long X; > > > > > > if (!value_str.getAsInteger(X)) > > > > > > return some error; > > > > > > llvm::support::endian::write(®isters[register_id], X, endian); > > > > > > ``` > > > > > > > > > > > > By using llvm endianness functions you can just delete the > > > > > > `SwitchEndian()` function entirely, as it's not needed. > > > > > These endian functions don't work here. getAsInteger() assumes the > > > > > number is in human reading order (i.e. big endian). So it's > > > > > converting the little endian string as if it's big, then converting > > > > > that little endian long to another little endian long, which does > > > > > nothing. > > > > > I need something that reverses the string first. > > > > > > > > > > What do you think about adding a version of StringRef::getAsInteger > > > > > that accepts an endianness parameter? > > > > Hmm.. What about this? > > > > > > > > ``` > > > > unsigned long X; > > > > if (!value_str.getAsInteger(X)) > > > > return some error; > > > > sys::swapByteOrder(X); > > > > ``` > > > > > > > > It shouldn't matter if you swap the bytes in the string before doing > > > > the translation, or swap the bytes in the number after doing the > > > > translation should it? > > > It doesn't matter when I do it. The issue with the other functions was > > > they were converting target to host, when both were little. For string > > > parsing, it needs target to big to string, or target to string to big. > > Maybe I'm just missing something, but if you've got the string "ABCDEF" > > which is a little endian string, then it is supposed to represent the > > number 0x00EFCDAB or 15,715,755 (assuming a 4 byte number). If you parse > > it as big endian, which is what `getAsInteger` does, you're going to end up > > with the number 0xABCDEF00 which is 2,882,400,000, which is |AB|CD|EF|00| > > (on a big endian machine) or |00|EF|CD|AB| (on a little endian machine). > > If you then swap the bytes, you're going to end up with |00|EF|CD|AB| (on a > > big endian machine) or |AB|CD|EF|00| on a little endian machine. In both > > cases, these represent the number 15,715,755 as desired. > > > > It's possible I'm just getting confused here, but I don't see why the above > > code sample doesn't work. > We are also technically supposed to support PDP endian. It's part of the GDB > protocol and there are scratches for it in the LLDB code. Currently we don't > support these targets in LLVM, but this might change in future (GCC actively > maintains these targets). I might have been unclear. Using swapByteOrder, when the target is little endian works. I was explaining why the read & write functions didn't work for this case. Comment at: unittests/tools/lldb-server/tests/TestClient.cpp:70 +void TestClient::StopDebugger() { + Host::Kill(server_process_info.GetProcessID(), 15); +} krytarowski wrote: > jmajors wrote: > > labath wrote: > > > This is not portable. > > Is there a portable way of stopping? > `15` on my platform (NetBSD) is `SIGTERM`. > > I've implemented similar feature in `NativeProcessNetBSD::Halt()`. Perhaps > you can call `Halt()` as well? I changed it to send $k and let the lldb-server figure out platform issues. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98826. jmajors marked an inline comment as done. jmajors added a comment. Feedback changes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,50 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,57 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + std::shared_ptr GetProcessInfo(); + std::shared_ptr GetJThreadsInfo(); + std::shared_ptr GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + void SendMessage(const std::string& message, std::string& response_string, + PacketResult expected_result); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::shared_ptr process_info; + std::shared_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned int pc_register; +}; +} Index: unittests/tools/lldb-server/tests/
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 6 inline comments as done. jmajors added inline comments. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:25-30 + elements["pid"].getAsInteger(16, pid); + elements["parent-pid"].getAsInteger(16, parent_pid); + elements["real-uid"].getAsInteger(16, real_uid); + elements["real-gid"].getAsInteger(16, real_gid); + elements["effective-uid"].getAsInteger(16, effective_uid); + elements["effective-gid"].getAsInteger(16, effective_gid); zturner wrote: > Since this is in a constructor, what happens if you get a malformed response? > You don't have a way to return an error here, and none of these errors are > checked. Do you want to `assert` if this happens? Or are you ok silently > dropping this kind of failure? I changed it to a Create with tests for success. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:142 +llvm::support::endianness endian) { + auto stop_reply = std::shared_ptr(new StopReply()); + zturner wrote: > Can you use `llvm::make_shared()` here? Probably doesn't matter > much, but it's good practice to use `make_shared<>` wherever possible since > it uses less memory. I wanted to keep my constructors protected, to force the use of Create(). make_shared doesn't work with protected constructors. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:167 +std::stringstream ss; +ss << std::hex << std::setw(2) << std::setfill('0') << register_id; +std::string hex_id = ss.str(); zturner wrote: > Is this the same as `std::string hex_id = llvm::utostr(register_id);`? No. The register IDs are all two nibbles wide, so I need the setw & setfill (or equivalent). https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98858. jmajors marked an inline comment as done. jmajors added a comment. More feedback changes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,50 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,57 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + std::shared_ptr GetProcessInfo(); + std::shared_ptr GetJThreadsInfo(); + std::shared_ptr GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + void SendMessage(const std::string& message, std::string& response_string, + PacketResult expected_result); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::shared_ptr process_info; + std::shared_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned int pc_register; +}; +} Index: unittests/tools/lldb-server/t
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 7 inline comments as done. jmajors added inline comments. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:142 +llvm::support::endianness endian) { + auto stop_reply = std::shared_ptr(new StopReply()); + labath wrote: > jmajors wrote: > > zturner wrote: > > > Can you use `llvm::make_shared()` here? Probably doesn't > > > matter much, but it's good practice to use `make_shared<>` wherever > > > possible since it uses less memory. > > I wanted to keep my constructors protected, to force the use of Create(). > > make_shared doesn't work with protected constructors. > I raise the bet to `llvm::make_unique` ;). shared pointers lead to messy > ownership semantics, we should only use them when absolutely necessary, and I > don't think that is the case here. Since I'm returning copies of the pointer container in getter functions, I think I need shared, not unique. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:189 +if (key.size() >= 9 && key[0] == 'T' && key.substr(3, 6) == "thread") { + val.getAsInteger(16, stop_reply->thread); + key.substr(1, 2).getAsInteger(16, stop_reply->signal); labath wrote: > zturner wrote: > > Is error checking needed here? > More error checking definitely needed (here and everywhere else). If I break > lldb-server while working on it, I'd like to see a clear error message from > the test rather than an obscure crash. This should return > `Expected` if you don't care about copying or > `Expected>` if you do (*), so that the test can > ASSERT that the message was received and parsed correctly and print out the > error otherwise. > > (*) Or the out argument idea I wrote about earlier. I converted my pointer containers to Expected>. I noticed that ASSERT_* doesn't fail the test, it returns, so I need to make the functions in TestClient return Error or Expected<> objects and check them in the test body. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 98869. jmajors marked 2 inline comments as done. jmajors added a comment. Changed shared_ptr returns to Expected>. Some other error processing additions. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,50 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include + +#include "gtest/gtest.h" +#include "TestClient.h" + +using namespace CommunicationTests; + +TEST(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + client.StartDebugger(); + client.SetInferior(inferior_args); + client.ListThreadsInStopReply(); + client.Continue(); + unsigned int pc_reg = client.GetPcRegisterId(); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info.get()) << "Error reading JThreadInfo."; + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) + << "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) + << "Mismatched PC for thread: " << tid; + } + + client.StopDebugger(); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,57 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" + +#include "MessageObjects.h" + +namespace CommunicationTests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient : + public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + void StartDebugger(); + void StopDebugger(); + void SetInferior(llvm::ArrayRef inferior_args); + void ListThreadsInStopReply(); + void SetBreakpoint(unsigned long address); + void Continue(unsigned long thread_id = 0); + const ProcessInfo& GetProcessInfo(); + std::unique_ptr GetJThreadsInfo(); + const StopReply& GetLatestStopReply(); + void SendMessage(const std::string& message); + void SendMessage(const std::string& message, std::string& response_string); + void SendMessage(const std::string& message, std::string& response_string, + PacketResult expected_result); + unsigned int GetPcRegisterId(); + +private: + void GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::ArchSpec& arch) const; + std::string FormatFailedResult(const std::string& message, + lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult + result); + + std::unique_ptr process_info; + std::unique_ptr stop_reply; + lldb_private::ProcessLaunchInfo server_process_info; + std::string test_name; + std::string test_case_name; + unsigned
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 99365. jmajors marked 15 inline comments as done. jmajors added a comment. Moved asserts to the TEST(), where they'll actually do something. Made TestClient members warn if their return values go unused. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,55 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include "TestClient.h" +#include "gtest/gtest.h" + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { + protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.Continue()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,58 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { + public: + static void Initialize(); + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool Continue(unsigned long thread_id = 0); + const ProcessInfo& GetProcessInfo(); + std::unique_ptr GetJThreadsInfo(); + const StopReply& GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(const std::string& message); + LLVM_NODISCARD bool SendMessage(const std::string& message, + std::string& response_string); + LLVM_NODISCARD bool SendMessage(const std::string& message, + std::string& response_string, + PacketResult expected_result); + unsigned int GetPcRegisterId(); + + private: + LLV
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 7 inline comments as done. jmajors added inline comments. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:10 + +#include +#include labath wrote: > Do you still need these includes? Yes. I'm using a stringstream to convert integer register IDs to two nibble hex strings. Comment at: unittests/tools/lldb-server/tests/MessageObjects.cpp:26-27 +Expected> ProcessInfo::Create(StringRef response) { + std::unique_ptr process_info = +std::unique_ptr(new ProcessInfo); + auto elements = SplitPairList(response); zturner wrote: > How about `std::unique_ptr process_info(new ProcessInfo);` Java brainwashing. :) Comment at: unittests/tools/lldb-server/tests/MessageObjects.h:10 + +#include +#include labath wrote: > This still looks wrong. Did you run clang-format on the full patch (`git > clang-format origin/master` should do the trick. you may need to set the > clangFormat.binary git setting to point to a clang-format executable) ? I ran clang-format -i *h *cpp. It reordered the includes. I just ran it as a git subcommand, and it didn't change these lines. I even tried scrambling the includes around, and that's the order it seems to want them in. Comment at: unittests/tools/lldb-server/tests/MessageObjects.h:63 + public: + static llvm::Expected> Create( + llvm::StringRef response, llvm::support::endianness endian); tberghammer wrote: > Why do we need the unique_ptr here? Can it return llvm::Expected > instead? Same question for the other Create functions. Since I don't build the JThreadsInfo, ProcessInfo, and StopReply members of TestClient in the constructor, I'd need a default constructor, which I hid to force use of Create(). Also, it allows me to have an uninitialized value for these members, so I can verify some things happen in the correct order. Comment at: unittests/tools/lldb-server/tests/TestClient.cpp:62 +.str(); +GTEST_LOG_(ERROR) << error; +return false; labath wrote: > This won't actually fail the test (i'm not sure whether you intended that or > not). I think it would be better to bubble the error one more level and do > the assert in the TEST. After zachary is done with D33059, we will have a > nice way to assert on llvm::Error types. After I commit D33241, you can > easily convert Status into llvm::Error. > > Also the whole `Error` class is marked as nodiscard, so you won't need to > annotate all functions with the macro explicitly. The false return/no discard combo causes the test to fail. I didn't want to return an Error object, because it adds a lot of overhead. If Zachary's assert change reduces this overhead, I can switch it. Comment at: unittests/tools/lldb-server/tests/TestClient.cpp:115 + + if (thread_id == 0) thread_id = process_info->GetPid(); + labath wrote: > This is a linux-ism. Other targets don't have the "pid == main thread id" > concept. What is the semantics you intended for the thread_id = 0 case? If > you wanted to resume the whole process (all threads) you can send `vCont;c` > or just `c`. We also have the LLDB_INVALID_THREAD_ID symbolic constant to > signify invalid thread. I was using 0 so the caller didn't have to know what the main thread id was. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 99491. jmajors marked an inline comment as done. jmajors added a comment. More CL feedback. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,55 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include "TestClient.h" +#include "gtest/gtest.h" + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { + protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.Continue()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +ASSERT_EQ(stop_reply_pcs[tid], thread_infos[tid].ReadRegister(pc_reg)) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,58 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include +#include +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { + public: + static void Initialize(); + TestClient(const std::string& test_name, const std::string& test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool Continue(unsigned long thread_id = 0); + const ProcessInfo& GetProcessInfo(); + std::unique_ptr GetJThreadsInfo(); + const StopReply& GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string& response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string& response_string, + PacketResult expected_result); + unsigned int GetPcRegisterId(); + + private: + LLVM_NODISCARD bool GenerateConnectionAddress(std::string& address); + std::string GenerateLogFileName(const lldb_private::
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors marked 12 inline comments as done. jmajors added inline comments. Comment at: unittests/tools/lldb-server/tests/MessageObjects.h:52 + + unsigned long ReadRegister(unsigned long register_id) const; + labath wrote: > tberghammer wrote: > > "unsigned long" is only 32 bit on some systems but a register can be > > arbitrary large so the return value should be something more generic. This > > is true for every location you are working with registers. > changing to uint64_t does not really solve the issue Tamas was pointing out, > it possibly even makes it worse. The reason I did not bring it up until now > is that `long` happens match the size of general purpose registers, which are > the ones that we care about for the moment, which was kinda nice. > > However, intel sse registers can be up to 512 bits wide, so we will need to > have something more generic sooner or later. lldb has a `RegisterValue` class > for this purpose, so we should probably use that. If it shows that it makes > the code too clunky, we can add some accessor functions which assert that the > size of register is e.g. sizeof(void*) and return a simple integer. They can > then be used it cases where you know that the register must contain a > pointer-sized value. Rather than trying to test and convert them all, I just left them as strings. I only access one value (the PC), so I'm converting it as I need it. Comment at: unittests/tools/lldb-server/tests/MessageObjects.h:33-42 + lldb::pid_t pid; + lldb::pid_t parent_pid; + uint32_t real_uid; + uint32_t real_gid; + uint32_t effective_uid; + uint32_t effective_gid; + std::string triple; tberghammer wrote: > A large part of these variables are never read by anybody. Do we want to keep > them around just in case or should we remove them? I figured I might as well parse the whole message at once, in case new tests need the pieces. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 99644. jmajors marked an inline comment as done. jmajors added a comment. More feedback changes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,58 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestClient.h" +#include "gtest/gtest.h" +#include + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { +protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.ContinueAll()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +uint64_t pc_value; +ASSERT_TRUE(thread_infos[tid].ReadRegisterAsUint64(pc_reg, pc_value)) +<< "Failure reading ThreadInfo register " << pc_reg; +ASSERT_EQ(stop_reply_pcs[tid], pc_value) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,61 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" +#include "llvm/ADT/Optional.h" +#include +#include + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + static void Initialize(); + TestClient(const std::string &test_name, const std::string &test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool ContinueAll(); + LLVM_NODISCARD bool ContinueThread(unsigned long thread_id); + const ProcessInfo &GetProcessInfo(); + llvm::Optional GetJThreadsInfo(); + const StopReply &GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string, +
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 99788. jmajors marked 11 inline comments as done. jmajors added a comment. CR feedback. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,58 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestClient.h" +#include "gtest/gtest.h" +#include + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { +protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.ContinueAll()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +uint64_t pc_value; +ASSERT_TRUE(thread_infos[tid].ReadRegisterAsUint64(pc_reg, pc_value)) +<< "Failure reading ThreadInfo register " << pc_reg; +ASSERT_EQ(stop_reply_pcs[tid], pc_value) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,61 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" +#include "llvm/ADT/Optional.h" +#include +#include + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + static void Initialize(); + TestClient(const std::string &test_name, const std::string &test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool ContinueAll(); + LLVM_NODISCARD bool ContinueThread(unsigned long thread_id); + const ProcessInfo &GetProcessInfo(); + llvm::Optional GetJThreadsInfo(); + const StopReply &GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string, + PacketR
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors added a comment. Addressed more feedback. https://reviews.llvm.org/D32930 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 100151. jmajors added a comment. Added m_ prefix to member variables. Converted lldb-server start to single thread. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,58 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestClient.h" +#include "gtest/gtest.h" +#include + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { +protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.ContinueAll()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +uint64_t pc_value; +ASSERT_TRUE(thread_infos[tid].ReadRegisterAsUint64(pc_reg, pc_value)) +<< "Failure reading ThreadInfo register " << pc_reg; +ASSERT_EQ(stop_reply_pcs[tid], pc_value) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,61 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" +#include "llvm/ADT/Optional.h" +#include +#include + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + static void Initialize(); + TestClient(const std::string &test_name, const std::string &test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool ContinueAll(); + LLVM_NODISCARD bool ContinueThread(unsigned long thread_id); + const ProcessInfo &GetProcessInfo(); + llvm::Optional GetJThreadsInfo(); + const StopReply &GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string, +
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 100178. jmajors added a comment. Format changes. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,58 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestClient.h" +#include "gtest/gtest.h" +#include + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { +protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.ContinueAll()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +uint64_t pc_value; +ASSERT_TRUE(thread_infos[tid].ReadRegisterAsUint64(pc_reg, pc_value)) +<< "Failure reading ThreadInfo register " << pc_reg; +ASSERT_EQ(stop_reply_pcs[tid], pc_value) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,61 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" +#include "llvm/ADT/Optional.h" +#include +#include + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + static void Initialize(); + TestClient(const std::string &test_name, const std::string &test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool ContinueAll(); + LLVM_NODISCARD bool ContinueThread(unsigned long thread_id); + const ProcessInfo &GetProcessInfo(); + llvm::Optional GetJThreadsInfo(); + const StopReply &GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string, + PacketResult expected_result); + unsigned int
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 100287. jmajors added a comment. Make inferior break more portable. Restrict tests to running on Linux, BSD, or Android systems. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,58 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestClient.h" +#include "gtest/gtest.h" +#include + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { +protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.ContinueAll()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +uint64_t pc_value; +ASSERT_TRUE(thread_infos[tid].ReadRegisterAsUint64(pc_reg, pc_value)) +<< "Failure reading ThreadInfo register " << pc_reg; +ASSERT_EQ(stop_reply_pcs[tid], pc_value) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,61 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" +#include "llvm/ADT/Optional.h" +#include +#include + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + static void Initialize(); + TestClient(const std::string &test_name, const std::string &test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool ContinueAll(); + LLVM_NODISCARD bool ContinueThread(unsigned long thread_id); + const ProcessInfo &GetProcessInfo(); + llvm::Optional GetJThreadsInfo(); + const StopReply &GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string, +
[Lldb-commits] [PATCH] D32930: New framework for lldb client-server communication tests.
jmajors updated this revision to Diff 100288. jmajors marked an inline comment as done. jmajors added a comment. Made directory test more portable. https://reviews.llvm.org/D32930 Files: unittests/CMakeLists.txt unittests/tools/CMakeLists.txt unittests/tools/lldb-server/CMakeLists.txt unittests/tools/lldb-server/inferior/thread_inferior.cpp unittests/tools/lldb-server/tests/CMakeLists.txt unittests/tools/lldb-server/tests/MessageObjects.cpp unittests/tools/lldb-server/tests/MessageObjects.h unittests/tools/lldb-server/tests/TestClient.cpp unittests/tools/lldb-server/tests/TestClient.h unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp Index: unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp === --- /dev/null +++ unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -0,0 +1,58 @@ +//===-- ThreadsInJstopinfoTest.cpp --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestClient.h" +#include "gtest/gtest.h" +#include + +using namespace llgs_tests; + +class ThreadsInJstopinfoTest : public ::testing::Test { +protected: + virtual void SetUp() { TestClient::Initialize(); } +}; + +TEST_F(ThreadsInJstopinfoTest, TestStopReplyContainsThreadPcsLlgs) { + std::vector inferior_args; + // This inferior spawns N threads, then forces a break. + inferior_args.push_back(THREAD_INFERIOR); + inferior_args.push_back("4"); + + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + + TestClient client(test_info->name(), test_info->test_case_name()); + ASSERT_TRUE(client.StartDebugger()); + ASSERT_TRUE(client.SetInferior(inferior_args)); + ASSERT_TRUE(client.ListThreadsInStopReply()); + ASSERT_TRUE(client.ContinueAll()); + unsigned int pc_reg = client.GetPcRegisterId(); + ASSERT_NE(pc_reg, UINT_MAX); + + auto jthreads_info = client.GetJThreadsInfo(); + ASSERT_TRUE(jthreads_info); + + auto stop_reply = client.GetLatestStopReply(); + 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."; + + for (auto stop_reply_pc : stop_reply_pcs) { +unsigned long tid = stop_reply_pc.first; +ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) +<< "Thread ID: " << tid << " not in JThreadsInfo."; +uint64_t pc_value; +ASSERT_TRUE(thread_infos[tid].ReadRegisterAsUint64(pc_reg, pc_value)) +<< "Failure reading ThreadInfo register " << pc_reg; +ASSERT_EQ(stop_reply_pcs[tid], pc_value) +<< "Mismatched PC for thread: " << tid; + } + + ASSERT_TRUE(client.StopDebugger()); +} Index: unittests/tools/lldb-server/tests/TestClient.h === --- /dev/null +++ unittests/tools/lldb-server/tests/TestClient.h @@ -0,0 +1,61 @@ +//===-- TestClient.h *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MessageObjects.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ProcessLaunchInfo.h" +#include "llvm/ADT/Optional.h" +#include +#include + +namespace llgs_tests { +// TODO: Make the test client an abstract base class, with different children +// for different types of connections: llgs v. debugserver +class TestClient +: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { +public: + static void Initialize(); + TestClient(const std::string &test_name, const std::string &test_case_name); + virtual ~TestClient(); + LLVM_NODISCARD bool StartDebugger(); + LLVM_NODISCARD bool StopDebugger(); + LLVM_NODISCARD bool SetInferior(llvm::ArrayRef inferior_args); + LLVM_NODISCARD bool ListThreadsInStopReply(); + LLVM_NODISCARD bool SetBreakpoint(unsigned long address); + LLVM_NODISCARD bool ContinueAll(); + LLVM_NODISCARD bool ContinueThread(unsigned long thread_id); + const ProcessInfo &GetProcessInfo(); + llvm::Optional GetJThreadsInfo(); + const StopReply &GetLatestStopReply(); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string); + LLVM_NODISCARD bool SendMessage(llvm::StringRef message, + std::string &response_string, +
[Lldb-commits] [PATCH] D27289: Return "thread-pcs" in jstopinfo on Linux/Android.
jmajors created this revision. jmajors added a reviewer: labath. jmajors added a subscriber: lldb-commits. Herald added a subscriber: danalbert. To prevent costly calls to the server to get the PC for every thread, add all the thread's PCs to the jstopinfo message. This also makes the Linux/Android server behave like the macOS server. https://reviews.llvm.org/D27289 Files: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -415,18 +415,20 @@ static void WriteRegisterValueInHexFixedWidth( StreamString &response, NativeRegisterContextSP ®_ctx_sp, -const RegisterInfo ®_info, const RegisterValue *reg_value_p) { +const RegisterInfo ®_info, const RegisterValue *reg_value_p, +lldb::ByteOrder byte_order) { RegisterValue reg_value; if (!reg_value_p) { Error error = reg_ctx_sp->ReadRegister(®_info, reg_value); if (error.Success()) reg_value_p = ®_value; // else log. } + bool little_endian = byte_order == lldb::eByteOrderLittle; if (reg_value_p) { AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(), - reg_value_p->GetByteSize(), false); + reg_value_p->GetByteSize(), little_endian); } else { // Zero-out any unreadable values. if (reg_info.byte_size > 0) { @@ -436,6 +438,13 @@ } } +static void WriteRegisterValueInHexFixedWidth( +StreamString &response, NativeRegisterContextSP ®_ctx_sp, +const RegisterInfo ®_info, const RegisterValue *reg_value_p) { + WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, reg_info, + reg_value_p, lldb::eByteOrderBig); +} + static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread, bool abridged) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); @@ -570,6 +579,7 @@ if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged)) thread_obj_sp->SetObject("registers", registers_sp); + thread_obj_sp->SetObject("tid", std::make_shared(tid)); if (signum != 0) thread_obj_sp->SetObject("signal", std::make_shared(signum)); @@ -721,6 +731,41 @@ "jstopinfo field for pid %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID()); } + +uint32_t i = 0; +ByteOrder byte_order = endian::InlHostByteOrder(); +response.PutCString("thread-pcs"); +char delimiter = ':'; +for (NativeThreadProtocolSP thread_sp; +(thread_sp = m_debugged_process_sp->GetThreadAtIndex(i)) != nullptr; +++i) { + NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); + if (!reg_ctx_sp) +continue; + + uint32_t reg_to_read = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo* const reg_info_p = +reg_ctx_sp->GetRegisterInfoAtIndex(reg_to_read); + + RegisterValue reg_value; + Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); + if (error.Fail()) { +if (log) + log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", + __FUNCTION__, + reg_info_p->name ? reg_info_p->name : "", + reg_to_read, error.AsCString()); +continue; + } + + response.PutChar(delimiter); + delimiter = ','; + WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, +®_value, byte_order); +} + +response.PutChar(';'); } // Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -415,18 +415,20 @@ static void WriteRegisterValueInHexFixedWidth( StreamString &response, NativeRegisterContextSP ®_ctx_sp, -const RegisterInfo ®_info, const RegisterValue *reg_value_p) { +const RegisterInfo ®_info, const RegisterValue *reg_value_p, +lldb::ByteOrder byte_order) { RegisterValue reg_value; if (!reg_value_p) { Error error = reg_ctx_sp->ReadRegister(®_info, reg_value); if (error.Success()) reg_value_p = ®_value; // else log. } + bool little_endian = byte_order == lldb::eByteOrderLittle; if (reg_value_p) { AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(), - reg_value_p->GetByteSize(), false); + reg_value_p->GetByteSize(), little_endian); } else {
[Lldb-commits] [PATCH] D30234: Reformat inferior's main.cpp in lldb-server test
jmajors accepted this revision. jmajors added a comment. This revision is now accepted and ready to land. Do we have any plans to put something like cpplint into effect? https://reviews.llvm.org/D30234 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D30515: Made GetClangTargetCPU() const.
jmajors created this revision. It does not change members or call non-const members. HostInfo::GetArchitecture() returns a const object ref (maybe others?), which can't access the non-const function. https://reviews.llvm.org/D30515 Files: include/lldb/Core/ArchSpec.h source/Core/ArchSpec.cpp Index: source/Core/ArchSpec.cpp === --- source/Core/ArchSpec.cpp +++ source/Core/ArchSpec.cpp @@ -657,7 +657,7 @@ SetFlags(flag); } -std::string ArchSpec::GetClangTargetCPU() { +std::string ArchSpec::GetClangTargetCPU() const { std::string cpu; const llvm::Triple::ArchType machine = GetMachine(); Index: include/lldb/Core/ArchSpec.h === --- include/lldb/Core/ArchSpec.h +++ include/lldb/Core/ArchSpec.h @@ -307,7 +307,7 @@ /// @return A string representing target CPU for the current /// architecture. //-- - std::string GetClangTargetCPU(); + std::string GetClangTargetCPU() const; //-- /// Return a string representing target application ABI. Index: source/Core/ArchSpec.cpp === --- source/Core/ArchSpec.cpp +++ source/Core/ArchSpec.cpp @@ -657,7 +657,7 @@ SetFlags(flag); } -std::string ArchSpec::GetClangTargetCPU() { +std::string ArchSpec::GetClangTargetCPU() const { std::string cpu; const llvm::Triple::ArchType machine = GetMachine(); Index: include/lldb/Core/ArchSpec.h === --- include/lldb/Core/ArchSpec.h +++ include/lldb/Core/ArchSpec.h @@ -307,7 +307,7 @@ /// @return A string representing target CPU for the current /// architecture. //-- - std::string GetClangTargetCPU(); + std::string GetClangTargetCPU() const; //-- /// Return a string representing target application ABI. ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits