diff options
Diffstat (limited to 'lldb/tools/debugserver/source')
| -rw-r--r-- | lldb/tools/debugserver/source/JSONGenerator.h | 490 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.cpp | 199 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.h | 2 |
3 files changed, 6 insertions, 685 deletions
diff --git a/lldb/tools/debugserver/source/JSONGenerator.h b/lldb/tools/debugserver/source/JSONGenerator.h deleted file mode 100644 index 423b2bd5792..00000000000 --- a/lldb/tools/debugserver/source/JSONGenerator.h +++ /dev/null @@ -1,490 +0,0 @@ -//===-- JSONGenerator.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef __JSONGenerator_h_ -#define __JSONGenerator_h_ - -// C Includes -// C++ Includes - -#include <iomanip> -#include <sstream> -#include <string> -#include <utility> -#include <vector> - -//---------------------------------------------------------------------- -/// @class JSONGenerator JSONGenerator.h -/// @brief A class which can construct structured data for the sole purpose -/// of printing it in JSON format. -/// -/// A stripped down version of lldb's StructuredData objects which are much -/// general purpose. This variant is intended only for assembling information -/// and printing it as a JSON string. -//---------------------------------------------------------------------- - -class JSONGenerator -{ -public: - - class Object; - class Array; - class Integer; - class Float; - class Boolean; - class String; - class Dictionary; - class Generic; - - typedef std::shared_ptr<Object> ObjectSP; - typedef std::shared_ptr<Array> ArraySP; - typedef std::shared_ptr<Integer> IntegerSP; - typedef std::shared_ptr<Float> FloatSP; - typedef std::shared_ptr<Boolean> BooleanSP; - typedef std::shared_ptr<String> StringSP; - typedef std::shared_ptr<Dictionary> DictionarySP; - typedef std::shared_ptr<Generic> GenericSP; - - enum class Type - { - eTypeInvalid = -1, - eTypeNull = 0, - eTypeGeneric, - eTypeArray, - eTypeInteger, - eTypeFloat, - eTypeBoolean, - eTypeString, - eTypeDictionary - }; - - class Object : - public std::enable_shared_from_this<Object> - { - public: - - Object (Type t = Type::eTypeInvalid) : - m_type (t) - { - } - - virtual ~Object () - { - } - - virtual bool - IsValid() const - { - return true; - } - - virtual void - Clear () - { - m_type = Type::eTypeInvalid; - } - - Type - GetType () const - { - return m_type; - } - - void - SetType (Type t) - { - m_type = t; - } - - Array * - GetAsArray () - { - if (m_type == Type::eTypeArray) - return (Array *)this; - return NULL; - } - - Dictionary * - GetAsDictionary () - { - if (m_type == Type::eTypeDictionary) - return (Dictionary *)this; - return NULL; - } - - Integer * - GetAsInteger () - { - if (m_type == Type::eTypeInteger) - return (Integer *)this; - return NULL; - } - - Float * - GetAsFloat () - { - if (m_type == Type::eTypeFloat) - return (Float *)this; - return NULL; - } - - Boolean * - GetAsBoolean () - { - if (m_type == Type::eTypeBoolean) - return (Boolean *)this; - return NULL; - } - - String * - GetAsString () - { - if (m_type == Type::eTypeString) - return (String *)this; - return NULL; - } - - Generic * - GetAsGeneric() - { - if (m_type == Type::eTypeGeneric) - return (Generic *)this; - return NULL; - } - - virtual void - Dump (std::ostream &s) const = 0; - - private: - Type m_type; - }; - - class Array : public Object - { - public: - Array () : - Object (Type::eTypeArray) - { - } - - virtual - ~Array() - { - } - - void - AddItem(ObjectSP item) - { - m_items.push_back(item); - } - - void Dump(std::ostream &s) const override - { - s << "["; - const size_t arrsize = m_items.size(); - for (size_t i = 0; i < arrsize; ++i) - { - m_items[i]->Dump(s); - if (i + 1 < arrsize) - s << ","; - } - s << "]"; - } - - protected: - typedef std::vector<ObjectSP> collection; - collection m_items; - }; - - - class Integer : public Object - { - public: - Integer (uint64_t value = 0) : - Object (Type::eTypeInteger), - m_value (value) - { - } - - virtual ~Integer() - { - } - - void - SetValue (uint64_t value) - { - m_value = value; - } - - void Dump(std::ostream &s) const override - { - s << m_value; - } - - protected: - uint64_t m_value; - }; - - class Float : public Object - { - public: - Float (double d = 0.0) : - Object (Type::eTypeFloat), - m_value (d) - { - } - - virtual ~Float() - { - } - - void - SetValue (double value) - { - m_value = value; - } - - void Dump(std::ostream &s) const override - { - s << m_value; - } - - protected: - double m_value; - }; - - class Boolean : public Object - { - public: - Boolean (bool b = false) : - Object (Type::eTypeBoolean), - m_value (b) - { - } - - virtual ~Boolean() - { - } - - void - SetValue (bool value) - { - m_value = value; - } - - void Dump(std::ostream &s) const override - { - if (m_value == true) - s << "true"; - else - s << "false"; - } - - protected: - bool m_value; - }; - - - - class String : public Object - { - public: - String () : - Object (Type::eTypeString), - m_value () - { - } - - String (const std::string &s) : - Object (Type::eTypeString), - m_value (s) - { - } - - String (const std::string &&s) : - Object (Type::eTypeString), - m_value (s) - { - } - - void - SetValue (const std::string &string) - { - m_value = string; - } - - void Dump(std::ostream &s) const override - { - std::string quoted; - const size_t strsize = m_value.size(); - for (size_t i = 0; i < strsize ; ++i) - { - char ch = m_value[i]; - if (ch == '"') - quoted.push_back ('\\'); - quoted.push_back (ch); - } - s << '"' << quoted.c_str() << '"'; - } - - protected: - std::string m_value; - }; - - class Dictionary : public Object - { - public: - Dictionary () : - Object (Type::eTypeDictionary), - m_dict () - { - } - - virtual ~Dictionary() - { - } - - void - AddItem (std::string key, ObjectSP value) - { - m_dict.push_back(Pair(key, value)); - } - - void - AddIntegerItem (std::string key, uint64_t value) - { - AddItem (key, ObjectSP (new Integer(value))); - } - - void - AddFloatItem (std::string key, double value) - { - AddItem (key, ObjectSP (new Float(value))); - } - - void - AddStringItem (std::string key, std::string value) - { - AddItem (key, ObjectSP (new String(std::move(value)))); - } - - void - AddBytesAsHexASCIIString (std::string key, const uint8_t *src, size_t src_len) - { - if (src && src_len) - { - std::ostringstream strm; - for (size_t i = 0; i < src_len; i++) - strm << std::setfill('0') << std::hex << std::right << std::setw(2) << ((uint32_t)(src[i])); - AddItem (key, ObjectSP (new String(std::move(strm.str())))); - } - else - { - AddItem (key, ObjectSP (new String())); - } - } - - void - AddBooleanItem (std::string key, bool value) - { - AddItem (key, ObjectSP (new Boolean(value))); - } - - void Dump(std::ostream &s) const override - { - bool have_printed_one_elem = false; - s << "{"; - for (collection::const_iterator iter = m_dict.begin(); iter != m_dict.end(); ++iter) - { - if (have_printed_one_elem == false) - { - have_printed_one_elem = true; - } - else - { - s << ","; - } - s << "\"" << iter->first.c_str() << "\":"; - iter->second->Dump(s); - } - s << "}"; - } - - protected: - // Keep the dictionary as a vector so the dictionary doesn't reorder itself when you dump it - // We aren't accessing keys by name, so this won't affect performance - typedef std::pair<std::string, ObjectSP> Pair; - typedef std::vector<Pair> collection; - collection m_dict; - }; - - class Null : public Object - { - public: - Null () : - Object (Type::eTypeNull) - { - } - - virtual ~Null() - { - } - - bool - IsValid() const override - { - return false; - } - - void Dump(std::ostream &s) const override - { - s << "null"; - } - - protected: - }; - - class Generic : public Object - { - public: - explicit Generic(void *object = nullptr) - : Object(Type::eTypeGeneric) - , m_object(object) - { - } - - void - SetValue(void *value) - { - m_object = value; - } - - void * - GetValue() const - { - return m_object; - } - - bool - IsValid() const override - { - return m_object != nullptr; - } - - void Dump(std::ostream &s) const override; - - private: - void *m_object; - }; - -}; // class JSONGenerator - - - -#endif // __JSONGenerator_h_ diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 00a0c9bd4bb..2385246a200 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -29,7 +29,6 @@ #include "DNBDataRef.h" #include "DNBLog.h" #include "DNBThreadResumeActions.h" -#include "JSONGenerator.h" #include "RNBContext.h" #include "RNBServices.h" #include "RNBSocket.h" @@ -196,7 +195,6 @@ RNBRemote::CreatePacketTable () t.push_back (Packet (query_process_info, &RNBRemote::HandlePacket_qProcessInfo, NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other.")); // t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups")); t.push_back (Packet (json_query_thread_extended_info, &RNBRemote::HandlePacket_jThreadExtendedInfo, NULL, "jThreadExtendedInfo", "Replies with JSON data of thread extended information.")); - t.push_back (Packet (json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo , NULL, "jThreadsInfo", "Replies with JSON data with information about all threads.")); t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets")); t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specific packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command")); t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix")); @@ -2454,52 +2452,6 @@ gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, } } -struct StackMemory -{ - uint8_t bytes[2*sizeof(nub_addr_t)]; - nub_size_t length; -}; -typedef std::map<nub_addr_t, StackMemory> StackMemoryMap; - - -static void -ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap) -{ - DNBRegisterValue reg_value; - if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, ®_value)) - { - uint32_t frame_count = 0; - uint64_t fp = 0; - if (reg_value.info.size == 4) - fp = reg_value.value.uint32; - else - fp = reg_value.value.uint64; - while (fp != 0) - { - // Make sure we never recurse more than 256 times so we don't recurse too far or - // store up too much memory in the expedited cache - if (++frame_count > 256) - break; - - const nub_size_t read_size = reg_value.info.size*2; - StackMemory stack_memory; - stack_memory.length = read_size; - if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size) - break; - // Make sure we don't try to put the same stack memory in more than once - if (stack_mmap.find(fp) != stack_mmap.end()) - break; - // Put the entry into the cache - stack_mmap[fp] = stack_memory; - // Dereference the frame pointer to get to the previous frame pointer - if (reg_value.info.size == 4) - fp = ((uint32_t *)stack_memory.bytes)[0]; - else - fp = ((uint64_t *)stack_memory.bytes)[0]; - } - } -} - rnb_err_t RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) { @@ -2626,26 +2578,11 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) } else if (tid_stop_info.details.exception.type) { - ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';'; - ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';'; + ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";"; + ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";"; for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i) - ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';'; + ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";"; } - - // Add expedited stack memory so stack backtracing doesn't need to read anything from the - // frame pointer chain. - StackMemoryMap stack_mmap; - ReadStackMemory (pid, tid, stack_mmap); - if (!stack_mmap.empty()) - { - for (const auto &stack_memory : stack_mmap) - { - ostrm << "memory:" << HEXBASE << stack_memory.first << '='; - append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false); - ostrm << ';'; - } - } - return SendPacket (ostrm.str ()); } return SendPacket("E51"); @@ -4825,136 +4762,11 @@ get_integer_value_for_key_name_from_json (const char *key, const char *json_stri } rnb_err_t -RNBRemote::HandlePacket_jThreadsInfo (const char *p) -{ - JSONGenerator::Array threads_array; - - std::ostringstream json; - std::ostringstream reply_strm; - // If we haven't run the process yet, return an error. - if (m_ctx.HasValidProcessID()) - { - nub_process_t pid = m_ctx.ProcessID(); - - nub_size_t numthreads = DNBProcessGetNumThreads (pid); - for (nub_size_t i = 0; i < numthreads; ++i) - { - nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i); - - struct DNBThreadStopInfo tid_stop_info; - - JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary()); - - thread_dict_sp->AddIntegerItem("tid", tid); - - std::string reason_value("none"); - if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) - { - switch (tid_stop_info.reason) - { - case eStopTypeInvalid: - break; - case eStopTypeSignal: - if (tid_stop_info.details.signal.signo != 0) - reason_value = "signal"; - break; - case eStopTypeException: - if (tid_stop_info.details.exception.type != 0) - reason_value = "exception"; - break; - case eStopTypeExec: - reason_value = "exec"; - break; - } - if (tid_stop_info.reason == eStopTypeSignal) - { - thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo); - } - else if (tid_stop_info.reason == eStopTypeException && tid_stop_info.details.exception.type != 0) - { - thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type); - JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); - for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i) - { - medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i]))); - } - thread_dict_sp->AddItem("medata", medata_array_sp); - } - } - - thread_dict_sp->AddStringItem("reason", reason_value); - - const char *thread_name = DNBThreadGetName (pid, tid); - if (thread_name && thread_name[0]) - thread_dict_sp->AddStringItem("name", thread_name); - - - thread_identifier_info_data_t thread_ident_info; - if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) - { - if (thread_ident_info.dispatch_qaddr != 0) - thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr); - } - DNBRegisterValue reg_value; - - if (g_reg_entries != NULL) - { - JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary()); - - for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) - { - // Expedite all registers in the first register set that aren't - // contained in other registers - if (g_reg_entries[reg].nub_info.set == 1 && - g_reg_entries[reg].nub_info.value_regs == NULL) - { - if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) - continue; - - std::ostringstream reg_num; - reg_num << std::dec << g_reg_entries[reg].gdb_regnum; - // Encode native byte ordered bytes as hex ascii - registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size); - } - } - thread_dict_sp->AddItem("registers", registers_dict_sp); - } - - // Add expedited stack memory so stack backtracing doesn't need to read anything from the - // frame pointer chain. - StackMemoryMap stack_mmap; - ReadStackMemory (pid, tid, stack_mmap); - if (!stack_mmap.empty()) - { - JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); - - for (const auto &stack_memory : stack_mmap) - { - JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary()); - stack_memory_sp->AddIntegerItem("address", stack_memory.first); - stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length); - memory_array_sp->AddItem(stack_memory_sp); - } - thread_dict_sp->AddItem("memory", memory_array_sp); - } - threads_array.AddItem(thread_dict_sp); - } - - std::ostringstream strm; - threads_array.Dump (strm); - std::string binary_packet = binary_encode_string (strm.str()); - if (!binary_packet.empty()) - return SendPacket (binary_packet.c_str()); - } - return SendPacket ("E85"); - -} - -rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) { nub_process_t pid; std::ostringstream json; + std::ostringstream reply_strm; // If we haven't run the process yet, return an error. if (!m_ctx.HasValidProcessID()) { @@ -5184,7 +4996,8 @@ RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) json << "}"; std::string json_quoted = binary_encode_string (json.str()); - return SendPacket (json_quoted); + reply_strm << json_quoted; + return SendPacket (reply_strm.str()); } } return SendPacket ("OK"); diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h index 2094c8d82bd..1f4883ab9e0 100644 --- a/lldb/tools/debugserver/source/RNBRemote.h +++ b/lldb/tools/debugserver/source/RNBRemote.h @@ -103,7 +103,6 @@ public: query_gdb_server_version, // 'qGDBServerVersion' query_process_info, // 'qProcessInfo' json_query_thread_extended_info,// 'jThreadExtendedInfo' - json_query_threads_info, // 'jThreadsInfo' pass_signals_to_inferior, // 'QPassSignals' start_noack_mode, // 'QStartNoAckMode' prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID @@ -191,7 +190,6 @@ public: rnb_err_t HandlePacket_qSyncThreadStateSupported (const char *p); rnb_err_t HandlePacket_qThreadInfo (const char *p); rnb_err_t HandlePacket_jThreadExtendedInfo (const char *p); - rnb_err_t HandlePacket_jThreadsInfo (const char *p); rnb_err_t HandlePacket_qThreadExtraInfo (const char *p); rnb_err_t HandlePacket_qThreadStopInfo (const char *p); rnb_err_t HandlePacket_qHostInfo (const char *p); |

