zturner updated this revision to Diff 69741.
zturner added a comment.
Rebased after submitting all local changes. This should apply cleanly on top
of LLDB r280139.
https://reviews.llvm.org/D24013
Files:
include/lldb/Core/Event.h
include/lldb/Core/RegularExpression.h
include/lldb/Utility/StringExtractor.h
source/Core/Event.cpp
source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
source/Utility/StringExtractor.cpp
source/Utility/StringExtractorGDBRemote.cpp
source/Utility/StringExtractorGDBRemote.h
unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
unittests/Utility/StringExtractorTest.cpp
Index: unittests/Utility/StringExtractorTest.cpp
===================================================================
--- unittests/Utility/StringExtractorTest.cpp
+++ unittests/Utility/StringExtractorTest.cpp
@@ -17,7 +17,7 @@
ASSERT_EQ (true, ex.IsGood());
ASSERT_EQ (0u, ex.GetFilePos());
- ASSERT_STREQ (kEmptyString, ex.GetStringRef().c_str());
+ ASSERT_EQ(kEmptyString, ex.Peek());
ASSERT_EQ (true, ex.Empty());
ASSERT_EQ (0u, ex.GetBytesLeft());
}
@@ -29,12 +29,53 @@
ASSERT_EQ (true, ex.IsGood());
ASSERT_EQ (0u, ex.GetFilePos());
- ASSERT_STREQ (kInitMiscString, ex.GetStringRef().c_str());
+ ASSERT_EQ(kInitMiscString, ex.Peek());
ASSERT_EQ (false, ex.Empty());
ASSERT_EQ (sizeof(kInitMiscString)-1, ex.GetBytesLeft());
ASSERT_EQ(kInitMiscString[0], ex.PeekChar());
}
+TEST_F(StringExtractorTest, PeekAndGetSize)
+{
+ llvm::StringRef Str("StringExtractorTest::Size()");
+ StringExtractor ex(Str);
+
+ EXPECT_EQ(true, ex.IsGood());
+ EXPECT_EQ(0u, ex.GetFilePos());
+ EXPECT_EQ(Str.size(), ex.GetTotalBytes());
+ EXPECT_EQ(Str.size(), ex.GetBytesLeft());
+
+ EXPECT_EQ('S', ex.PeekChar());
+ EXPECT_EQ(Str.size(), ex.GetTotalBytes());
+ EXPECT_EQ(Str.size(), ex.GetBytesLeft());
+ EXPECT_EQ(Str, ex.Peek());
+
+ EXPECT_EQ('S', ex.GetChar());
+ EXPECT_EQ(Str.size(), ex.GetTotalBytes());
+ EXPECT_EQ(Str.size() - 1, ex.GetBytesLeft());
+ EXPECT_EQ(Str.drop_front(1), ex.Peek());
+}
+
+TEST_F(StringExtractorTest, Consume)
+{
+ llvm::StringRef Str("StringExtractorTest::Consume()");
+ llvm::StringRef ConsumeStr("String");
+ StringExtractor ex(Str);
+
+ ASSERT_TRUE(ex.IsGood());
+ ASSERT_EQ(0u, ex.GetFilePos());
+
+ EXPECT_EQ(Str.size(), ex.GetBytesLeft());
+ EXPECT_FALSE(ex.Consume("Blah"));
+ EXPECT_EQ(Str.size(), ex.GetBytesLeft());
+ EXPECT_EQ(Str, ex.Peek());
+
+ EXPECT_TRUE(ex.Consume(ConsumeStr));
+ EXPECT_EQ(Str.size() - ConsumeStr.size(), ex.GetBytesLeft());
+ EXPECT_EQ("ExtractorTest::Consume()", ex.Peek());
+ ;
+}
+
TEST_F (StringExtractorTest, DecodeHexU8_Underflow)
{
const char kEmptyString[] = "";
Index: unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
===================================================================
--- unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -41,19 +41,19 @@
{
StringExtractorGDBRemote request;
ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
- ASSERT_EQ("QThreadSuffixSupported", request.GetStringRef());
+ ASSERT_EQ("QThreadSuffixSupported", request.Peek());
if (supported)
ASSERT_EQ(PacketResult::Success, server.SendOKResponse());
else
- ASSERT_EQ(PacketResult::Success, server.SendUnimplementedResponse(nullptr));
+ ASSERT_EQ(PacketResult::Success, server.SendUnimplementedResponse(""));
}
void
HandlePacket(MockServer &server, llvm::StringRef expected, llvm::StringRef response)
{
StringExtractorGDBRemote request;
ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
- ASSERT_EQ(expected, request.GetStringRef());
+ ASSERT_EQ(expected, request.Peek());
ASSERT_EQ(PacketResult::Success, server.SendPacket(response));
}
Index: unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
===================================================================
--- unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
+++ unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
@@ -114,23 +114,23 @@
// Continue. The inferior will stop with a signal.
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
+ ASSERT_EQ("T01", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
// Continue. The inferior will exit.
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("W01"));
ASSERT_EQ(eStateExited, fix.SendCPacket(response));
- ASSERT_EQ("W01", response.GetStringRef());
+ ASSERT_EQ("W01", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
// Continue. The inferior will get killed.
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("X01"));
ASSERT_EQ(eStateExited, fix.SendCPacket(response));
- ASSERT_EQ("X01", response.GetStringRef());
+ ASSERT_EQ("X01", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
}
TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal)
@@ -147,25 +147,25 @@
std::future<StateType> continue_state =
std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.Peek());
fix.WaitForRunEvent();
std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.SendAsyncSignal(0x47); });
// First we'll get interrupted.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ("\x03", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
// Then we get the signal packet.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("C47", response.GetStringRef());
+ ASSERT_EQ("C47", response.PeekFullPacket());
ASSERT_TRUE(async_result.get());
// And we report back a signal stop.
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T47"));
ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T47", continue_response.GetStringRef());
+ ASSERT_EQ("T47", continue_response.Peek());
}
TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket)
@@ -180,7 +180,7 @@
std::future<StateType> continue_state =
std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
fix.WaitForRunEvent();
// Sending without async enabled should fail.
@@ -192,24 +192,24 @@
// First we'll get interrupted.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ("\x03", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
// Then we get the async packet.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("qTest2", response.GetStringRef());
+ ASSERT_EQ("qTest2", response.PeekFullPacket());
// Send the response and receive it.
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest2"));
ASSERT_EQ(PacketResult::Success, async_result.get());
- ASSERT_EQ("QTest2", async_response.GetStringRef());
+ ASSERT_EQ("QTest2", async_response.PeekFullPacket());
// And we get resumed again.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T01", continue_response.GetStringRef());
+ ASSERT_EQ("T01", continue_response.PeekFullPacket());
}
TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt)
@@ -226,19 +226,19 @@
std::future<StateType> continue_state =
std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
fix.WaitForRunEvent();
std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
// We get interrupted.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ("\x03", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
// And that's it.
ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T13", continue_response.GetStringRef());
+ ASSERT_EQ("T13", continue_response.PeekFullPacket());
ASSERT_TRUE(async_result.get());
}
@@ -253,25 +253,25 @@
std::future<StateType> continue_state =
std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
fix.WaitForRunEvent();
std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
// However, the target stops due to a different reason than the original interrupt.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ("\x03", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T01", continue_response.GetStringRef());
+ ASSERT_EQ("T01", continue_response.PeekFullPacket());
ASSERT_TRUE(async_result.get());
// The subsequent continue packet should work normally.
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
+ ASSERT_EQ("T01", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
}
TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug)
@@ -289,31 +289,31 @@
std::future<StateType> continue_state =
std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
fix.WaitForRunEvent();
std::future<bool> interrupt_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
// We get interrupted. We'll send two packets to simulate a buggy stub.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ("\x03", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
// We should stop.
ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T13", continue_response.GetStringRef());
+ ASSERT_EQ("T13", continue_response.PeekFullPacket());
ASSERT_TRUE(interrupt_result.get());
// Packet stream should remain synchronized.
std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
return fix.client.SendPacketAndWaitForResponse("qTest", async_response, !send_async);
});
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("qTest", response.GetStringRef());
+ ASSERT_EQ("qTest", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
ASSERT_EQ(PacketResult::Success, send_result.get());
- ASSERT_EQ("QTest", async_response.GetStringRef());
+ ASSERT_EQ("QTest", async_response.PeekFullPacket());
}
TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface)
@@ -330,9 +330,9 @@
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
+ ASSERT_EQ("T01", response.PeekFullPacket());
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
EXPECT_EQ("ABCD", fix.delegate.output);
EXPECT_EQ("profile", fix.delegate.misc_data);
@@ -350,14 +350,14 @@
std::future<StateType> continue_state =
std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ("c", response.PeekFullPacket());
fix.WaitForRunEvent();
std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
// We get interrupted, but we don't send a stop packet.
ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ("\x03", response.PeekFullPacket());
// The functions should still terminate (after a timeout).
ASSERT_TRUE(async_result.get());
Index: source/Utility/StringExtractorGDBRemote.h
===================================================================
--- source/Utility/StringExtractorGDBRemote.h
+++ source/Utility/StringExtractorGDBRemote.h
@@ -24,21 +24,24 @@
StringExtractorGDBRemote() :
StringExtractor(),
- m_validator(nullptr)
+ m_validator(nullptr),
+ m_validator_baton(nullptr)
{
}
- StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr) {}
+ StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr), m_validator_baton(nullptr) {}
StringExtractorGDBRemote(const char *cstr) :
StringExtractor(cstr),
- m_validator(nullptr)
+ m_validator(nullptr),
+ m_validator_baton(nullptr)
{
}
StringExtractorGDBRemote(const StringExtractorGDBRemote& rhs) :
StringExtractor(rhs),
- m_validator(rhs.m_validator)
+ m_validator(rhs.m_validator),
+ m_validator_baton(rhs.m_validator_baton)
{
}
Index: source/Utility/StringExtractorGDBRemote.cpp
===================================================================
--- source/Utility/StringExtractorGDBRemote.cpp
+++ source/Utility/StringExtractorGDBRemote.cpp
@@ -427,7 +427,7 @@
// starts with a '['. This is a quick validator to just make sure the
// response could be valid JSON without having to validate all of the
// JSON content.
- switch (response.GetStringRef()[0])
+ switch (response.PeekChar())
{
case '{': return true;
case '[': return true;
@@ -456,7 +456,7 @@
case StringExtractorGDBRemote::eResponse:
{
uint32_t valid_count = 0;
- for (const char ch : response.GetStringRef())
+ for (const char ch : response.PeekFullPacket())
{
if (!isxdigit(ch))
{
Index: source/Utility/StringExtractor.cpp
===================================================================
--- source/Utility/StringExtractor.cpp
+++ source/Utility/StringExtractor.cpp
@@ -110,6 +110,15 @@
return (uint8_t)((hi_nibble << 4) + lo_nibble);
}
+bool
+StringExtractor::Consume(llvm::StringRef str)
+{
+ if (!Peek().startswith(str))
+ return false;
+ m_index += str.size();
+ return true;
+}
+
//----------------------------------------------------------------------
// If a pair of valid hex digits exist at the head of the
// StringExtractor they are decoded into an unsigned byte and returned
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -407,10 +407,10 @@
CalculateThreadStopInfo (ThreadGDBRemote *thread);
size_t
- UpdateThreadPCsFromStopReplyThreadsValue (std::string &value);
+ UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value);
size_t
- UpdateThreadIDsFromStopReplyThreadsValue (std::string &value);
+ UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value);
bool
HandleNotifyPacket(StringExtractorGDBRemote &packet);
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1672,44 +1672,32 @@
}
size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue (std::string &value)
+ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value)
{
m_thread_ids.clear();
- m_thread_pcs.clear();
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
+ lldb::addr_t tid;
+ llvm::StringRef tid_str;
+ while (!value.empty())
+ {
+ std::tie(tid_str, value) = value.split(',');
+ if (!tid_str.getAsInteger(16, tid))
+ m_thread_ids.push_back(tid);
+ }
return m_thread_ids.size();
}
size_t
-ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue (std::string &value)
+ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value)
{
m_thread_pcs.clear();
- size_t comma_pos;
lldb::addr_t pc;
- while ((comma_pos = value.find(',')) != std::string::npos)
+ llvm::StringRef pc_str;
+ while (!value.empty())
{
- value[comma_pos] = '\0';
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
+ std::tie(pc_str, value) = value.split(',');
+ if (!pc_str.getAsInteger(16, pc))
m_thread_pcs.push_back (pc);
- value.erase(0, comma_pos + 1);
}
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_THREAD_ID)
- m_thread_pcs.push_back (pc);
return m_thread_pcs.size();
}
@@ -1759,32 +1747,19 @@
{
// Get the thread stop info
StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
- const std::string &stop_info_str = stop_info.GetStringRef();
m_thread_pcs.clear();
- const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
- if (thread_pcs_pos != std::string::npos)
+ llvm::StringRef threads_value = stop_info.Peek().split(";thread-pcs:").second
+ .split(";").first;
+ if (!threads_value.empty())
+ UpdateThreadPCsFromStopReplyThreadsValue(threads_value);
+
+ threads_value = stop_info.Peek().split(";threads:").second
+ .split(";").first;
+ if (!threads_value.empty())
{
- const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
- const size_t end = stop_info_str.find(';', start);
- if (end != std::string::npos)
- {
- std::string value = stop_info_str.substr(start, end - start);
- UpdateThreadPCsFromStopReplyThreadsValue(value);
- }
- }
-
- const size_t threads_pos = stop_info_str.find(";threads:");
- if (threads_pos != std::string::npos)
- {
- const size_t start = threads_pos + strlen(";threads:");
- const size_t end = stop_info_str.find(';', start);
- if (end != std::string::npos)
- {
- std::string value = stop_info_str.substr(start, end - start);
- if (UpdateThreadIDsFromStopReplyThreadsValue(value))
- return true;
- }
+ if (UpdateThreadIDsFromStopReplyThreadsValue(threads_value))
+ return true;
}
}
}
@@ -1982,9 +1957,8 @@
for (const auto &pair : expedited_register_map)
{
- StringExtractor reg_value_extractor;
- reg_value_extractor.GetStringRef() = pair.second;
- DataBufferSP buffer_sp(new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0));
+ StringExtractor reg_value_extractor(pair.second);
+ DataBufferSP buffer_sp(new DataBufferHeap(reg_value_extractor.GetBytesLeft() / 2, 0));
reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
}
@@ -2357,12 +2331,12 @@
{
if (mem_cache_addr != LLDB_INVALID_ADDRESS)
{
- StringExtractor bytes;
- if (mem_cache_dict->GetValueForKeyAsString("bytes", bytes.GetStringRef()))
+ std::string bytes_str;
+ if (mem_cache_dict->GetValueForKeyAsString("bytes", bytes_str))
{
- bytes.SetFilePos(0);
+ StringExtractor bytes(bytes_str);
- const size_t byte_size = bytes.GetStringRef().size()/2;
+ const size_t byte_size = bytes_str.size() / 2;
DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetData(), 0);
if (bytes_copied == byte_size)
@@ -2912,9 +2886,10 @@
else
{
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - got unexpected response to k packet: %s", response.GetStringRef().c_str());
+ log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response to k packet: %s",
+ response.PeekFullPacket().str().c_str());
exit_string.assign("got unexpected response to k packet: ");
- exit_string.append(response.GetStringRef());
+ exit_string.append(response.PeekFullPacket().str());
}
}
else
@@ -2948,7 +2923,7 @@
void
ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
{
- const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
+ const bool did_exec = response.Peek().find(";reason:exec;") != llvm::StringRef::npos;
if (did_exec)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
@@ -3079,7 +3054,7 @@
// much data for some reason.
data_received_size = size;
}
- memcpy (buf, response.GetStringRef().data(), data_received_size);
+ memcpy(buf, response.Peek().data(), data_received_size);
return data_received_size;
}
else
@@ -3092,7 +3067,8 @@
else if (response.IsUnsupportedResponse())
error.SetErrorStringWithFormat("GDB server does not support reading memory");
else
- error.SetErrorStringWithFormat("unexpected response to GDB server memory read packet '%s': '%s'", packet, response.GetStringRef().c_str());
+ error.SetErrorStringWithFormat("unexpected response to GDB server memory read packet '%s': '%s'", packet,
+ response.PeekFullPacket().str().c_str());
}
else
{
@@ -3129,7 +3105,8 @@
else if (response.IsUnsupportedResponse())
error.SetErrorStringWithFormat("GDB server does not support writing memory");
else
- error.SetErrorStringWithFormat("unexpected response to GDB server memory write packet '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
+ error.SetErrorStringWithFormat("unexpected response to GDB server memory write packet '%s': '%s'",
+ packet.GetString().c_str(), response.PeekFullPacket().str().c_str());
}
else
{
@@ -3831,10 +3808,8 @@
bool
ProcessGDBRemote::HandleNotifyPacket (StringExtractorGDBRemote &packet)
{
- // get the packet at a string
- const std::string &pkt = packet.GetStringRef();
// skip %stop:
- StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
+ StringExtractorGDBRemote stop_info(packet.Peek().drop_front(5));
// pass as a thread stop info packet
SetLastStopPacket(stop_info);
@@ -4194,7 +4169,7 @@
{
if (!response.Empty())
{
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
+ object_sp = StructuredData::ParseJSON(response.Peek().str());
}
}
}
@@ -4270,7 +4245,7 @@
{
if (!response.Empty())
{
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
+ object_sp = StructuredData::ParseJSON(response.Peek().str());
}
}
}
@@ -4309,7 +4284,7 @@
{
if (!response.Empty())
{
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
+ object_sp = StructuredData::ParseJSON(response.Peek().str());
}
}
}
@@ -4577,14 +4552,13 @@
}
else if (name == "dynamic_size_dwarf_expr_bytes")
{
- StringExtractor opcode_extractor;
std::string opcode_string = value.str ();
size_t dwarf_opcode_len = opcode_string.length () / 2;
assert (dwarf_opcode_len > 0);
dwarf_opcode_bytes.resize (dwarf_opcode_len);
reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
- opcode_extractor.GetStringRef ().swap (opcode_string);
+ StringExtractor opcode_extractor(opcode_string);
uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes);
assert (dwarf_opcode_len == ret_val);
@@ -5426,17 +5400,16 @@
result.SetStatus (eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
output_strm.Printf (" packet: %s\n", packet_cstr);
- std::string &response_str = response.GetStringRef();
if (strstr(packet_cstr, "qGetProfileData") != NULL)
{
- response_str = process->HarmonizeThreadIdsForProfileData(response);
+ response.SetString(process->HarmonizeThreadIdsForProfileData(response));
}
- if (response_str.empty())
+ if (response.GetBytesLeft() == 0)
output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
+ output_strm.Printf("response: %s\n", response.Peek().str().c_str());
}
}
return true;
@@ -5477,20 +5450,18 @@
StreamString packet;
packet.PutCString("qRcmd,");
packet.PutBytesAsRawHex8(command, strlen(command));
- const char *packet_cstr = packet.GetString().c_str();
bool send_async = true;
StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
+ process->GetGDBRemote().SendPacketAndWaitForResponse(packet.GetString(), response, send_async);
result.SetStatus (eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
- output_strm.Printf (" packet: %s\n", packet_cstr);
- const std::string &response_str = response.GetStringRef();
+ output_strm.Printf(" packet: %s\n", packet.GetString().c_str());
- if (response_str.empty())
+ if (response.GetBytesLeft() == 0)
output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
+ output_strm.Printf("response: %s\n", response.Peek().str().c_str());
}
return true;
}
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1187,7 +1187,7 @@
{
// FIXME add continue at address support for $C{signo}[;{continue-address}].
if (packet.PeekChar() == ';')
- return SendUnimplementedResponse (packet.GetStringRef().c_str());
+ return SendUnimplementedResponse(packet.PeekFullPacket());
else
return SendIllFormedResponse (packet, "unexpected content after $C{signal-number}");
}
@@ -1258,7 +1258,7 @@
{
if (log)
log->Printf ("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]", __FUNCTION__, packet.Peek ());
- return SendUnimplementedResponse (packet.GetStringRef().c_str());
+ return SendUnimplementedResponse(packet.PeekFullPacket());
}
// Ensure we have a native process.
@@ -1694,7 +1694,9 @@
if (reg_index == std::numeric_limits<uint32_t>::max ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"",
+ __FUNCTION__, packet.Peek().str().c_str());
return SendErrorResponse (0x15);
}
@@ -1775,7 +1777,9 @@
if (reg_index == std::numeric_limits<uint32_t>::max ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"",
+ __FUNCTION__, packet.Peek().str().c_str());
return SendErrorResponse (0x29);
}
@@ -2772,7 +2776,8 @@
if (tid == LLDB_INVALID_THREAD_ID)
{
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse thread id from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not parse thread id from request \"%s\"",
+ __FUNCTION__, packet.Peek().str().c_str());
return SendErrorResponse (0x15);
}
return SendStopReplyPacketForThread (tid);
@@ -2918,7 +2923,9 @@
if (packet.GetBytesLeft () < 1 || packet.GetChar () != ';')
{
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected ';' prior to start of thread suffix: packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected ';' prior to start of "
+ "thread suffix: packet contents = '%s'",
+ __FUNCTION__, packet.Peek().str().c_str());
return thread_sp;
}
@@ -2929,7 +2936,9 @@
if (packet.Peek().startswith("thread:"))
{
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not found, packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not "
+ "found, packet contents = '%s'",
+ __FUNCTION__, packet.Peek().str().c_str());
return thread_sp;
}
packet.SetFilePos (packet.GetFilePos () + strlen("thread:"));
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1081,7 +1081,7 @@
GDBRemoteCommunicationServerCommon::Handle_qEcho (StringExtractorGDBRemote &packet)
{
// Just echo back the exact same packet for qEcho...
- return SendPacketNoLock(packet.GetStringRef());
+ return SendPacketNoLock(packet.PeekFullPacket());
}
GDBRemoteCommunication::PacketResult
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -60,7 +60,7 @@
bool m_exit_now; // use in asynchronous handling to indicate process should exit.
PacketResult
- SendUnimplementedResponse (const char *packet);
+ SendUnimplementedResponse(llvm::StringRef packet);
PacketResult
SendErrorResponse (uint8_t error);
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -67,13 +67,13 @@
break;
case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
+ packet_result = SendUnimplementedResponse(packet.PeekFullPacket());
break;
default:
auto handler_it = m_packet_handlers.find(packet_type);
if (handler_it == m_packet_handlers.end())
- packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
+ packet_result = SendUnimplementedResponse(packet.PeekFullPacket());
else
packet_result = handler_it->second (packet, error, interrupt, quit);
break;
@@ -99,8 +99,7 @@
return packet_result;
}
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
+GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServer::SendUnimplementedResponse(llvm::StringRef)
{
// TODO: Log the packet we aren't handling...
return SendPacketNoLock ("");
@@ -121,7 +120,8 @@
{
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__, failed_packet.GetStringRef ().c_str (), message ? message : "");
+ log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__,
+ failed_packet.PeekFullPacket().str().c_str(), message ? message : "");
return SendErrorResponse (0x03);
}
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -675,7 +675,7 @@
// Given the list of compression types that the remote debug stub can support,
// possibly enable compression if we find an encoding we can handle.
void
- MaybeEnableCompression (std::vector<std::string> supported_compressions);
+ MaybeEnableCompression(std::vector<llvm::StringRef> supported_compressions);
bool
DecodeProcessInfoResponse (StringExtractorGDBRemote &response,
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -42,6 +42,7 @@
#include "lldb/Host/Config.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
#if defined (HAVE_LIBCOMPRESSION)
#include <compression.h>
@@ -419,93 +420,57 @@
}
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetData(),
- response,
+ if (SendPacketAndWaitForResponse(packet.GetData(), response,
/*send_async=*/false) == PacketResult::Success)
{
- const char *response_cstr = response.GetStringRef().c_str();
+ llvm::StringRef response_str = response.Peek();
// Hang on to the qSupported packet, so that platforms can do custom
// configuration of the transport before attaching/launching the
// process.
- m_qSupported_response = response_cstr;
+ m_qSupported_response = response_str;
- if (::strstr (response_cstr, "qXfer:auxv:read+"))
+ if (response_str.contains("qXfer:auxv:read+"))
m_supports_qXfer_auxv_read = eLazyBoolYes;
- if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
+ if (response_str.contains("qXfer:libraries-svr4:read+"))
m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
- if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
+ if (response_str.contains("augmented-libraries-svr4-read"))
{
m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
}
- if (::strstr (response_cstr, "qXfer:libraries:read+"))
+ if (response_str.contains("qXfer:libraries:read+"))
m_supports_qXfer_libraries_read = eLazyBoolYes;
- if (::strstr (response_cstr, "qXfer:features:read+"))
+ if (response_str.contains("qXfer:features:read+"))
m_supports_qXfer_features_read = eLazyBoolYes;
// Look for a list of compressions in the features list e.g.
// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
- const char *features_list = ::strstr (response_cstr, "qXfer:features:");
- if (features_list)
+ llvm::StringRef compressions =
+ response_str.split("qXfer:features:").second
+ .split("SupportedCompressions=").second
+ .split(";").first;
+ std::vector<llvm::StringRef> supported_compressions;
+ while (!compressions.empty())
{
- const char *compressions = ::strstr (features_list, "SupportedCompressions=");
- if (compressions)
- {
- std::vector<std::string> supported_compressions;
- compressions += sizeof ("SupportedCompressions=") - 1;
- const char *end_of_compressions = strchr (compressions, ';');
- if (end_of_compressions == NULL)
- {
- end_of_compressions = strchr (compressions, '\0');
- }
- const char *current_compression = compressions;
- while (current_compression < end_of_compressions)
- {
- const char *next_compression_name = strchr (current_compression, ',');
- const char *end_of_this_word = next_compression_name;
- if (next_compression_name == NULL || end_of_compressions < next_compression_name)
- {
- end_of_this_word = end_of_compressions;
- }
-
- if (end_of_this_word)
- {
- if (end_of_this_word == current_compression)
- {
- current_compression++;
- }
- else
- {
- std::string this_compression (current_compression, end_of_this_word - current_compression);
- supported_compressions.push_back (this_compression);
- current_compression = end_of_this_word + 1;
- }
- }
- else
- {
- supported_compressions.push_back (current_compression);
- current_compression = end_of_compressions;
- }
- }
-
- if (supported_compressions.size() > 0)
- {
- MaybeEnableCompression (supported_compressions);
- }
- }
+ llvm::StringRef this_compression;
+ std::tie(this_compression, compressions) = compressions.split(',');
+ supported_compressions.push_back(this_compression);
}
- if (::strstr (response_cstr, "qEcho"))
+ if (!supported_compressions.empty())
+ MaybeEnableCompression(supported_compressions);
+
+ if (response_str.contains("qEcho"))
m_supports_qEcho = eLazyBoolYes;
else
m_supports_qEcho = eLazyBoolNo;
- const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
- if (packet_size_str)
+ llvm::StringRef packet_size_str = response_str.split("PacketSize=").second;
+ if (!packet_size_str.empty())
{
- StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
+ StringExtractorGDBRemote packet_response(packet_size_str);
m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
if (m_max_packet_size == 0)
{
@@ -547,17 +512,17 @@
m_supports_vCont_S = eLazyBoolNo;
if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
{
- const char *response_cstr = response.GetStringRef().c_str();
- if (::strstr (response_cstr, ";c"))
+ llvm::StringRef response_str = response.Peek();
+ if (response_str.contains(";c"))
m_supports_vCont_c = eLazyBoolYes;
- if (::strstr (response_cstr, ";C"))
+ if (response_str.contains(";C"))
m_supports_vCont_C = eLazyBoolYes;
- if (::strstr (response_cstr, ";s"))
+ if (response_str.contains(";s"))
m_supports_vCont_s = eLazyBoolYes;
- if (::strstr (response_cstr, ";S"))
+ if (response_str.contains(";S"))
m_supports_vCont_S = eLazyBoolYes;
if (m_supports_vCont_c == eLazyBoolYes &&
@@ -658,7 +623,7 @@
}
else if (!response.Empty())
{
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
+ object_sp = StructuredData::ParseJSON(response.Peek());
}
}
}
@@ -772,16 +737,13 @@
if (result != PacketResult::Success)
return result;
- const std::string &this_string = this_response.GetStringRef();
-
// Check for m or l as first character; l seems to mean this is the last chunk
- char first_char = *this_string.c_str();
+ char first_char = this_response.GetChar();
if (first_char != 'm' && first_char != 'l')
- {
return PacketResult::ErrorReplyInvalid;
- }
+
// Concatenate the result so far (skipping 'm' or 'l')
- response_string.append(this_string, 1, std::string::npos);
+ response_string.append(this_response.Peek());
if (first_char == 'l')
// We're done
return PacketResult::Success;
@@ -855,7 +817,7 @@
if (response.GetChar() == 'E')
{
// A string the describes what failed when launching...
- error_str = response.GetStringRef().substr(1);
+ error_str = response.Peek();
}
else
{
@@ -1166,7 +1128,7 @@
}
void
-GDBRemoteCommunicationClient::MaybeEnableCompression (std::vector<std::string> supported_compressions)
+GDBRemoteCommunicationClient::MaybeEnableCompression(std::vector<llvm::StringRef> supported_compressions)
{
CompressionType avail_type = CompressionType::None;
std::string avail_name;
@@ -2377,8 +2339,7 @@
if (!DecodeProcessInfoResponse (response, process_info))
break;
process_infos.Append(process_info);
- response.GetStringRef().clear();
- response.SetFilePos(0);
+ response.Reset();
} while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
}
else
@@ -2407,7 +2368,7 @@
// Make sure we parsed the right number of characters. The response is
// the hex encoded user name and should make up the entire packet.
// If there are any non-hex ASCII bytes, the length won't match below..
- if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
+ if (response.GetHexByteString(name) && !response.GetBytesLeft())
return true;
}
}
@@ -2432,14 +2393,14 @@
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
- if (response.IsNormalResponse())
- {
- // Make sure we parsed the right number of characters. The response is
- // the hex encoded group name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
- if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
- return true;
- }
+ if (!response.IsNormalResponse())
+ return false;
+
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded group name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString(name) * 2 == response.GetTotalBytes())
+ return true;
}
else
{
@@ -2717,7 +2678,7 @@
if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success)
return 0;
- StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef());
+ StructuredData::ObjectSP data = StructuredData::ParseJSON(response.Peek());
if (!data)
return 0;
@@ -3479,7 +3440,7 @@
!response.IsNormalResponse())
return nullptr;
- DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ DataBufferSP buffer_sp(new DataBufferHeap(response.GetBytesLeft() / 2, 0));
response.GetHexBytes(buffer_sp->GetData(), '\xcc');
return buffer_sp;
}
@@ -3494,7 +3455,7 @@
!response.IsNormalResponse())
return nullptr;
- DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ DataBufferSP buffer_sp(new DataBufferHeap(response.GetBytesLeft() / 2, 0));
response.GetHexBytes(buffer_sp->GetData(), '\xcc');
return buffer_sp;
}
@@ -3673,7 +3634,7 @@
std::string & out,
lldb_private::Error & err) {
- std::stringstream output;
+ llvm::raw_string_ostream output(out);
StringExtractorGDBRemote chunk;
uint64_t size = GetRemoteMaxPacketSize();
@@ -3704,24 +3665,24 @@
return false;
}
- const std::string & str = chunk.GetStringRef( );
- if ( str.length() == 0 ) {
+ if (chunk.GetBytesLeft() == 0)
+ {
// should have some data in chunk
err.SetErrorString( "Empty response from $qXfer packet" );
return false;
}
// check packet code
- switch ( str[0] ) {
+ switch (chunk.GetChar())
+ {
// last chunk
case ( 'l' ):
active = false;
LLVM_FALLTHROUGH;
// more chunks
case ( 'm' ) :
- if ( str.length() > 1 )
- output << &str[1];
+ output << chunk.Peek();
offset += size;
break;
@@ -3732,7 +3693,7 @@
}
}
- out = output.str( );
+ output.flush();
err.Success( );
return true;
}
@@ -3809,10 +3770,8 @@
}
else
{
- llvm::StringRef response_str(response.GetStringRef());
- if (response_str.startswith("qSymbol:"))
+ if (response.Consume("qSymbol:"))
{
- response.SetFilePos(strlen("qSymbol:"));
std::string symbol_name;
if (response.GetHexByteString(symbol_name))
{
@@ -3924,18 +3883,17 @@
if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
send_async) == PacketResult::Success)
{
- m_supported_async_json_packets_sp = StructuredData::ParseJSON(
- response.GetStringRef());
+ m_supported_async_json_packets_sp = StructuredData::ParseJSON(response.Peek());
if (m_supported_async_json_packets_sp &&
!m_supported_async_json_packets_sp->GetAsArray())
{
// We were returned something other than a JSON array. This
// is invalid. Clear it out.
if (log)
log->Printf("GDBRemoteCommunicationClient::%s(): "
"QSupportedAsyncJSONPackets returned invalid "
- "result: %s", __FUNCTION__,
- response.GetStringRef().c_str());
+ "result: %s",
+ __FUNCTION__, response.Peek().str().c_str());
m_supported_async_json_packets_sp.reset();
}
}
@@ -4002,17 +3960,16 @@
if (result == PacketResult::Success)
{
// We failed if the config result comes back other than OK.
- if (strcmp(response.GetStringRef().c_str(), "OK") == 0)
+ if (response.Peek().equals("OK"))
{
// Okay!
error.Clear();
}
else
{
error.SetErrorStringWithFormat("configuring StructuredData feature "
"%s failed with error %s",
- type_name.AsCString(),
- response.GetStringRef().c_str());
+ type_name.AsCString(), response.Peek().str().c_str());
}
}
else
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -467,7 +467,7 @@
if (echo_packet_result == PacketResult::Success)
{
++successful_responses;
- if (response_regex.Execute(echo_response.GetStringRef().c_str()))
+ if (response_regex.Execute(echo_response.Peek().str().c_str()))
{
sync_success = true;
break;
@@ -896,7 +896,6 @@
size_t content_end = content_start + content_length;
bool success = true;
- std::string &packet_str = packet.GetStringRef();
if (log)
{
// If logging was just enabled and we have history, then dump out what
@@ -957,8 +956,7 @@
m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
- // Clear packet_str in case there is some existing data in it.
- packet_str.clear();
+ std::string packet_str;
// Copy the packet from m_bytes to packet_str expanding the
// run-length encoding in the process.
// Reserve enough byte for the most common case (no RLE used)
@@ -1026,9 +1024,9 @@
log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
}
}
-
+
m_bytes.erase(0, total_length);
- packet.SetFilePos(0);
+ packet.SetString(packet_str);
if (isNotifyPacket)
return GDBRemoteCommunication::PacketType::Notify;
@@ -1476,14 +1474,9 @@
if (type == PacketType::Notify)
{
- // put this packet into an event
- const char *pdata = packet.GetStringRef().c_str();
-
// as the communication class, we are a broadcaster and the
// async thread is tuned to listen to us
- BroadcastEvent(
- eBroadcastBitGdbReadThreadGotNotify,
- new EventDataBytes(pdata));
+ BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify, new EventDataBytes(packet.Peek()));
}
}
}
Index: source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -77,7 +77,8 @@
const char stop_type = response.GetChar();
if (log)
- log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
+ log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
+ response.PeekFullPacket().str().c_str());
switch (stop_type)
{
@@ -99,27 +100,29 @@
break;
}
case 'A':
- delegate.HandleAsyncMisc(llvm::StringRef(response.GetStringRef()).substr(1));
+ delegate.HandleAsyncMisc(response.Peek());
break;
case 'J':
+ {
// Asynchronous JSON packet, destined for a
// StructuredDataPlugin.
- {
- // Parse the content into a StructuredData instance.
- auto payload_index = strlen("JSON-async:");
- StructuredData::ObjectSP json_sp =
- StructuredData::ParseJSON(response.GetStringRef()
- .substr(payload_index));
+
+ StructuredData::ObjectSP json_sp;
+ llvm::StringRef json_text;
+ // The 'J' was already consumed.
+ if (response.Consume("SON-async:"))
+ {
+ // Parse the content into a StructuredData instance.
+ json_sp = StructuredData::ParseJSON(json_text = response.Peek());
+ }
+
if (log)
{
if (json_sp)
- log->Printf(
- "GDBRemoteCommmunicationClientBase::%s() "
+ log->Printf("GDBRemoteCommmunicationClientBase::%s() "
"received Async StructuredData packet: %s",
- __FUNCTION__,
- response.GetStringRef().
- substr(payload_index).c_str());
+ __FUNCTION__, json_text.str().c_str());
else
log->Printf("GDBRemoteCommmunicationClientBase::%s"
"() received StructuredData packet:"
@@ -171,6 +174,7 @@
break;
}
}
+ response.SetFilePos(0);
}
bool
@@ -232,7 +236,7 @@
Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
if (log)
log->Printf("error: packet with payload \"%.*s\" got invalid response \"%s\": %s", int(payload.size()),
- payload.data(), response.GetStringRef().c_str(),
+ payload.data(), response.Peek().str().c_str(),
(i == (max_response_retries - 1)) ? "using invalid response and giving up"
: "ignoring response and waiting for another");
}
Index: source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
===================================================================
--- source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -303,9 +303,7 @@
std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
uint32_t j;
- StringExtractor opcode_extractor;
- // Swap "dwarf_opcode_string" over into "opcode_extractor"
- opcode_extractor.GetStringRef ().swap (dwarf_opcode_string);
+ StringExtractor opcode_extractor(dwarf_opcode_string);
uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes);
assert (ret_val == reg_info.dynamic_size_dwarf_len);
Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
===================================================================
--- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -891,7 +891,7 @@
response.GetResponseType() != response.eResponse)
return m_remote_signals_sp;
- auto object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ auto object_sp = StructuredData::ParseJSON(response.Peek());
if (!object_sp || !object_sp->IsValid())
return m_remote_signals_sp;
Index: source/Core/Event.cpp
===================================================================
--- source/Core/Event.cpp
+++ source/Core/Event.cpp
@@ -138,6 +138,11 @@
{
}
+EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes()
+{
+ SetBytes(str.data(), str.size());
+}
+
EventDataBytes::EventDataBytes (const char *cstr) :
m_bytes()
{
Index: include/lldb/Utility/StringExtractor.h
===================================================================
--- include/lldb/Utility/StringExtractor.h
+++ include/lldb/Utility/StringExtractor.h
@@ -44,6 +44,13 @@
operator=(const StringExtractor& rhs);
void
+ Reset()
+ {
+ m_packet.clear();
+ m_index = 0;
+ }
+
+ void
Reset(llvm::StringRef str)
{
m_packet = str;
@@ -80,16 +87,11 @@
void
SkipSpaces ();
- std::string &
- GetStringRef ()
- {
- return m_packet;
- }
-
- const std::string &
- GetStringRef () const
+ void
+ SetString(llvm::StringRef str)
{
- return m_packet;
+ m_packet = str;
+ m_index = 0;
}
bool
@@ -99,18 +101,27 @@
}
size_t
- GetBytesLeft ()
+ GetTotalBytes() const
+ {
+ return m_packet.size();
+ }
+
+ size_t
+ GetBytesLeft() const
{
if (m_index < m_packet.size())
return m_packet.size() - m_index;
return 0;
}
+ bool
+ Consume(llvm::StringRef Str);
+
char
GetChar (char fail_value = '\0');
char
- PeekChar (char fail_value = '\0')
+ PeekChar(char fail_value = '\0') const
{
llvm::StringRef str = Peek();
if (str.empty())
@@ -172,6 +183,12 @@
return llvm::StringRef(m_packet).drop_front(m_index);
}
+ llvm::StringRef
+ PeekFullPacket() const
+ {
+ return m_packet;
+ }
+
protected:
bool
fail()
Index: include/lldb/Core/RegularExpression.h
===================================================================
--- include/lldb/Core/RegularExpression.h
+++ include/lldb/Core/RegularExpression.h
@@ -11,6 +11,7 @@
#define liblldb_RegularExpression_h_
#ifdef _WIN32
+// TODO: We should not be including LLDB private headers.
#include "../lib/Support/regex_impl.h"
typedef llvm_regmatch_t regmatch_t;
Index: include/lldb/Core/Event.h
===================================================================
--- include/lldb/Core/Event.h
+++ include/lldb/Core/Event.h
@@ -24,6 +24,8 @@
#include "lldb/Host/Predicate.h"
#include "lldb/Core/Broadcaster.h"
+#include "llvm/ADT/StringRef.h"
+
namespace lldb_private {
//----------------------------------------------------------------------
@@ -65,6 +67,8 @@
//------------------------------------------------------------------
EventDataBytes ();
+ EventDataBytes::EventDataBytes(llvm::StringRef str);
+
EventDataBytes (const char *cstr);
EventDataBytes (const void *src, size_t src_len);
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits