summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source')
-rw-r--r--lldb/tools/debugserver/source/JSONGenerator.h490
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp199
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h2
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, &reg_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, &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);
OpenPOWER on IntegriCloud