diff options
Diffstat (limited to 'lldb/tools/debugserver/source/RNBRemote.cpp')
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 1951dfee065..f852b6875c9 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -193,6 +193,8 @@ RNBRemote::CreatePacketTable () t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process.")); t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process.")); t.push_back (Packet (memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, "qMemoryRegionInfo", "Return size and attributes of a memory region that contains the given address")); + t.push_back (Packet (get_profile_data, &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target.")); + t.push_back (Packet (set_enable_profiling, &RNBRemote::HandlePacket_SetAsyncEnableProfiling, NULL, "QSetAsyncEnableProfiling", "Enable or disable the profiling of current target.")); t.push_back (Packet (watchpoint_support_info, &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints")); } @@ -226,6 +228,25 @@ RNBRemote::FlushSTDIO () } } +void +RNBRemote::SendAsyncProfileData () +{ + if (m_ctx.HasValidProcessID()) + { + nub_process_t pid = m_ctx.ProcessID(); + char buf[256]; + nub_size_t count; + do + { + count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf)); + if (count > 0) + { + SendAsyncProfileDataPacket (buf, count); + } + } while (count > 0); + } +} + rnb_err_t RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer) { @@ -262,6 +283,18 @@ RNBRemote::SendSTDERRPacket (char *buf, nub_size_t buf_size) return SendHexEncodedBytePacket("O", buf, buf_size, NULL); } +// This makes use of asynchronous bit 'A' in the gdb remote protocol. +rnb_err_t +RNBRemote::SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size) +{ + if (buf_size == 0) + return rnb_success; + + std::string packet("A"); + packet.append(buf, buf_size); + return SendPacket(packet); +} + rnb_err_t RNBRemote::SendPacket (const std::string &s) { @@ -3428,6 +3461,58 @@ RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) } rnb_err_t +RNBRemote::HandlePacket_GetProfileData (const char *p) +{ + nub_process_t pid = m_ctx.ProcessID(); + if (pid == INVALID_NUB_PROCESS) + return SendPacket ("OK"); + + const char *data = DNBProcessGetProfileDataAsCString(pid); + if (data) + { + return SendPacket (data); + } + else + { + return SendPacket ("OK"); + } +} + + +// QSetAsyncEnableProfiling;enable:[0|1]:interval_usec:XXXXXX; +rnb_err_t +RNBRemote::HandlePacket_SetAsyncEnableProfiling (const char *p) +{ + nub_process_t pid = m_ctx.ProcessID(); + if (pid == INVALID_NUB_PROCESS) + return SendPacket (""); + + StringExtractor packet(p += sizeof ("QSetAsyncEnableProfiling:") - 1); + bool enable = false; + uint64_t interval_usec = 0; + std::string name; + std::string value; + while (packet.GetNameColonValue(name, value)) + { + if (name.compare ("enable") == 0) + { + enable = strtoul(value.c_str(), NULL, 10) > 0; + } + else if (name.compare ("interval_usec") == 0) + { + interval_usec = strtoul(value.c_str(), NULL, 10); + } + } + + if (interval_usec == 0) + { + enable = 0; + } + DNBProcessSetAsyncEnableProfiling(pid, enable, interval_usec); + return SendPacket ("OK"); +} + +rnb_err_t RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) { /* This packet simply returns the number of supported hardware watchpoints. |

