diff options
author | Greg Clayton <gclayton@apple.com> | 2013-02-02 01:13:48 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-02-02 01:13:48 +0000 |
commit | 4edb7ab8b26b60353f6713660d47c2228df0489f (patch) | |
tree | 92ffebd4b855e0b50d034db6f08293e4cbdc4444 | |
parent | d712d0dbddcd97e979b813158fe42fc3a351e460 (diff) | |
download | bcm5719-llvm-4edb7ab8b26b60353f6713660d47c2228df0489f.tar.gz bcm5719-llvm-4edb7ab8b26b60353f6713660d47c2228df0489f.zip |
Added support for the qCmd monitor packet command. Currently it can only do:
set logfile=<path>
set logmask=<num>
But this opens the door for us to do much more.
llvm-svn: 174258
-rw-r--r-- | lldb/tools/debugserver/source/DNBLog.cpp | 6 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/DNBLog.h | 1 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.cpp | 132 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.h | 3 |
4 files changed, 139 insertions, 3 deletions
diff --git a/lldb/tools/debugserver/source/DNBLog.cpp b/lldb/tools/debugserver/source/DNBLog.cpp index 890e7e553ca..18d8d2ad3a6 100644 --- a/lldb/tools/debugserver/source/DNBLog.cpp +++ b/lldb/tools/debugserver/source/DNBLog.cpp @@ -84,6 +84,12 @@ DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) g_log_baton = baton; } +DNBCallbackLog +DNBLogGetLogCallback () +{ + return g_log_callback; +} + bool DNBLogEnabled () { diff --git a/lldb/tools/debugserver/source/DNBLog.h b/lldb/tools/debugserver/source/DNBLog.h index 58015ad1465..d019e2d1a1f 100644 --- a/lldb/tools/debugserver/source/DNBLog.h +++ b/lldb/tools/debugserver/source/DNBLog.h @@ -50,6 +50,7 @@ bool DNBLogCheckLogBit (uint32_t bit) DNB_EXPORT; uint32_t DNBLogSetLogMask (uint32_t mask) DNB_EXPORT; uint32_t DNBLogGetLogMask () DNB_EXPORT; void DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) DNB_EXPORT; +DNBCallbackLog DNBLogGetLogCallback () DNB_EXPORT; bool DNBLogEnabled () DNB_EXPORT; bool DNBLogEnabledForAny (uint32_t mask) DNB_EXPORT; int DNBLogGetDebug () DNB_EXPORT; diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index bc8164f3c2c..2de6a9c82e3 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -30,7 +30,6 @@ #include <iomanip> #include <sstream> - #include <TargetConditionals.h> // for endianness predefines //---------------------------------------------------------------------- @@ -155,9 +154,9 @@ RNBRemote::CreatePacketTable () t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z3", "Remove read watchpoint")); t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z4", "Insert access watchpoint")); t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z4", "Remove access watchpoint")); + t.push_back (Packet (query_monitor, &RNBRemote::HandlePacket_qCmd, NULL, "qCmd", "Monitor command")); t.push_back (Packet (query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, "qC", "Query current thread ID")); t.push_back (Packet (query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, "qGetPid", "Query process id")); -// t.push_back (Packet (query_memory_crc, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qCRC:", "Compute CRC of memory region")); t.push_back (Packet (query_thread_ids_first, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", "Get list of active threads (first req)")); t.push_back (Packet (query_thread_ids_subsequent, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", "Get list of active threads (subsequent req)")); // APPLE LOCAL: qThreadStopInfo @@ -1435,6 +1434,135 @@ RNBRemote::HandlePacket_qThreadExtraInfo (const char *p) return SendPacket (""); } + +const char *k_space_delimiters = " \t"; +static void +skip_spaces (std::string &line) +{ + if (!line.empty()) + { + size_t space_pos = line.find_first_not_of (k_space_delimiters); + if (space_pos > 0) + line.erase(0, space_pos); + } +} + +static std::string +get_identifier (std::string &line) +{ + std::string word; + skip_spaces (line); + const size_t line_size = line.size(); + size_t end_pos; + for (end_pos = 0; end_pos < line_size; ++end_pos) + { + if (end_pos == 0) + { + if (isalpha(line[end_pos]) || line[end_pos] == '_') + continue; + } + else if (isalnum(line[end_pos]) || line[end_pos] == '_') + continue; + break; + } + word.assign (line, 0, end_pos); + line.erase(0, end_pos); + return word; +} + +static std::string +get_operator (std::string &line) +{ + std::string op; + skip_spaces (line); + if (!line.empty()) + { + if (line[0] == '=') + { + op = '='; + line.erase(0,1); + } + } + return op; +} + +static std::string +get_value (std::string &line) +{ + std::string value; + skip_spaces (line); + if (!line.empty()) + { + value.swap(line); + } + return value; +} + + +extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args); +extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); + +rnb_err_t +RNBRemote::HandlePacket_qCmd (const char *p) +{ + const char *c = p + strlen("qCmd,"); + std::string line; + while (c[0] && c[1]) + { + char smallbuf[3] = { c[0], c[1], '\0' }; + errno = 0; + int ch = strtoul (smallbuf, NULL, 16); + if (errno != 0 && ch == 0) + return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qCmd packet"); + line.push_back(ch); + c += 2; + } + if (*c == '\0') + { + std::string command = get_identifier(line); + if (command.compare("set") == 0) + { + std::string variable = get_identifier (line); + std::string op = get_operator (line); + std::string value = get_value (line); + if (variable.compare("logfile") == 0) + { + FILE *log_file = fopen(value.c_str(), "w"); + if (log_file) + { + DNBLogSetLogCallback(FileLogCallback, log_file); + return SendPacket ("OK"); + } + return SendPacket ("E71"); + } + else if (variable.compare("logmask") == 0) + { + char *end; + errno = 0; + uint32_t logmask = strtoul (value.c_str(), &end, 0); + if (errno == 0 && end && *end == '\0') + { + DNBLogSetLogMask (logmask); + if (!DNBLogGetLogCallback()) + DNBLogSetLogCallback(ASLLogCallback, NULL); + return SendPacket ("OK"); + } + errno = 0; + logmask = strtoul (value.c_str(), &end, 16); + if (errno == 0 && end && *end == '\0') + { + DNBLogSetLogMask (logmask); + return SendPacket ("OK"); + } + return SendPacket ("E72"); + } + return SendPacket ("E70"); + } + return SendPacket ("E69"); + } + return SendPacket ("E73"); +} + rnb_err_t RNBRemote::HandlePacket_qC (const char *p) { diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h index 611441b02aa..77d596c02b1 100644 --- a/lldb/tools/debugserver/source/RNBRemote.h +++ b/lldb/tools/debugserver/source/RNBRemote.h @@ -79,9 +79,9 @@ public: insert_access_watch_bp, // 'Z4' remove_access_watch_bp, // 'z4' + query_monitor, // 'qCmd' query_current_thread_id, // 'qC' query_get_pid, // 'qGetPid' - query_memory_crc, // 'qCRC:' query_thread_ids_first, // 'qfThreadInfo' query_thread_ids_subsequent, // 'qsThreadInfo' query_thread_extra_info, // 'qThreadExtraInfo' @@ -166,6 +166,7 @@ public: rnb_err_t HandlePacket_A (const char *p); rnb_err_t HandlePacket_H (const char *p); rnb_err_t HandlePacket_qC (const char *p); + rnb_err_t HandlePacket_qCmd (const char *p); rnb_err_t HandlePacket_qGetPid (const char *p); rnb_err_t HandlePacket_qLaunchSuccess (const char *p); rnb_err_t HandlePacket_qRegisterInfo (const char *p); |