Index: include/lldb/Core/StructuredData.h =================================================================== --- include/lldb/Core/StructuredData.h +++ include/lldb/Core/StructuredData.h @@ -54,14 +54,22 @@ class Boolean; class String; class Dictionary; + class Generic; typedef std::shared_ptr ObjectSP; typedef std::shared_ptr ArraySP; + typedef std::shared_ptr IntegerSP; + typedef std::shared_ptr FloatSP; + typedef std::shared_ptr BooleanSP; + typedef std::shared_ptr StringSP; typedef std::shared_ptr DictionarySP; + typedef std::shared_ptr GenericSP; - enum class Type { + enum class Type + { eTypeInvalid = -1, eTypeNull = 0, + eTypeGeneric, eTypeArray, eTypeInteger, eTypeFloat, @@ -84,6 +92,12 @@ { } + virtual bool + IsValid() const + { + return true; + } + virtual void Clear () { @@ -150,9 +164,19 @@ return NULL; } + Generic * + GetAsGeneric() + { + if (m_type == Type::eTypeGeneric) + return (Generic *)this; + return NULL; + } + ObjectSP GetObjectForDotSeparatedPath (llvm::StringRef path); + void DumpToStdout() const; + virtual void Dump (Stream &s) const = 0; @@ -174,7 +198,7 @@ } size_t - GetSize() + GetSize() const { return m_items.size(); } @@ -188,13 +212,97 @@ } ObjectSP - GetItemAtIndex (size_t idx) + GetItemAtIndex(size_t idx) const { + assert(idx < GetSize()); if (idx < m_items.size()) return m_items[idx]; return ObjectSP(); } + template + bool + GetItemAtIndexAsInteger(size_t idx, IntType &result) const + { + ObjectSP value = GetItemAtIndex(idx); + if (auto int_value = value->GetAsInteger()) + { + result = static_cast(int_value->GetValue()); + return true; + } + return false; + } + + template + bool + GetItemAtIndexAsInteger(size_t idx, IntType &result, IntType default_val) const + { + bool success = GetItemAtIndexAsInteger(idx, result); + if (!success) + result = default_val; + return success; + } + + bool + GetItemAtIndexAsString(size_t idx, std::string &result) const + { + ObjectSP value = GetItemAtIndex(idx); + if (auto string_value = value->GetAsString()) + { + result = string_value->GetValue(); + return true; + } + return false; + } + + bool + GetItemAtIndexAsString(size_t idx, std::string &result, const std::string &default_val) const + { + bool success = GetItemAtIndexAsString(idx, result); + if (!success) + result = default_val; + return success; + } + + bool + GetItemAtIndexAsString(size_t idx, ConstString &result) const + { + ObjectSP value = GetItemAtIndex(idx); + if (!value) + return false; + if (auto string_value = value->GetAsString()) + { + result = ConstString(string_value->GetValue()); + return true; + } + return false; + } + + bool + GetItemAtIndexAsString(size_t idx, ConstString &result, const char *default_val) const + { + bool success = GetItemAtIndexAsString(idx, result); + if (!success) + result.SetCString(default_val); + return success; + } + + bool + GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const + { + ObjectSP value = GetItemAtIndex(idx); + result = value->GetAsDictionary(); + return (result != nullptr); + } + + bool + GetItemAtIndexAsArray(size_t idx, Array *&result) const + { + ObjectSP value = GetItemAtIndex(idx); + result = value->GetAsArray(); + return (result != nullptr); + } + void Push(ObjectSP item) { @@ -207,8 +315,7 @@ m_items.push_back(item); } - virtual void - Dump (Stream &s) const; + void Dump(Stream &s) const override; protected: typedef std::vector collection; @@ -241,8 +348,7 @@ return m_value; } - virtual void - Dump (Stream &s) const; + void Dump(Stream &s) const override; protected: uint64_t m_value; @@ -273,8 +379,7 @@ return m_value; } - virtual void - Dump (Stream &s) const; + void Dump(Stream &s) const override; protected: double m_value; @@ -305,8 +410,7 @@ return m_value; } - virtual void - Dump (Stream &s) const; + void Dump(Stream &s) const override; protected: bool m_value; @@ -335,8 +439,7 @@ return m_value; } - virtual void - Dump (Stream &s) const; + void Dump(Stream &s) const override; protected: std::string m_value; @@ -354,14 +457,15 @@ virtual ~Dictionary() { } + size_t - GetSize() + GetSize() const { return m_dict.size(); } ObjectSP - GetKeys() + GetKeys() const { ObjectSP object_sp(new Array ()); Array *array = object_sp->GetAsArray(); @@ -376,7 +480,7 @@ } ObjectSP - GetValueForKey (const char *key) + GetValueForKey(const char *key) const { ObjectSP value_sp; if (key) @@ -394,19 +498,105 @@ return value_sp; } + template bool - HasKey (const char *key) + GetValueForKeyAsInteger(const char *key, IntType &result) const { - ConstString key_cs (key); - collection::const_iterator search = m_dict.find(key_cs); - if (search != m_dict.end()) + ObjectSP value = GetValueForKey(key); + if (!value) + return false; + if (auto int_value = value->GetAsInteger()) { + result = static_cast(int_value->GetValue()); return true; } - else + return false; + } + + template + bool + GetValueForKeyAsInteger(const char *key, IntType &result, IntType default_val) const + { + bool success = GetValueForKeyAsInteger(key, result); + if (!success) + result = default_val; + return success; + } + + bool + GetValueForKeyAsString(const char *key, std::string &result) const + { + ObjectSP value = GetValueForKey(key); + if (!value) + return false; + if (auto string_value = value->GetAsString()) { + result = string_value->GetValue(); + return true; + } + return false; + } + + bool + GetValueForKeyAsString(const char *key, std::string &result, const std::string &default_val) const + { + bool success = GetValueForKeyAsString(key, result); + if (!success) + result = default_val; + return success; + } + + bool + GetValueForKeyAsString(const char *key, ConstString &result) const + { + ObjectSP value = GetValueForKey(key); + if (!value) return false; + if (auto string_value = value->GetAsString()) + { + result = ConstString(string_value->GetValue()); + return true; } + return false; + } + + bool + GetValueForKeyAsString(const char *key, ConstString &result, const char *default_val) const + { + bool success = GetValueForKeyAsString(key, result); + if (!success) + result.SetCString(default_val); + return success; + } + + bool + GetValueForKeyAsDictionary(const char *key, Dictionary *&result) const + { + result = nullptr; + ObjectSP value = GetValueForKey(key); + if (!value) + return false; + result = value->GetAsDictionary(); + return true; + } + + bool + GetValueForKeyAsArray(const char *key, Array *&result) const + { + result = nullptr; + ObjectSP value = GetValueForKey(key); + if (!value) + return false; + result = value->GetAsArray(); + return true; + } + + bool + HasKey(const char *key) const + { + ConstString key_cs(key); + collection::const_iterator search = m_dict.find(key_cs); + return search != m_dict.end(); } void @@ -448,8 +638,7 @@ AddItem (key, val_obj); } - virtual void - Dump (Stream &s) const; + void Dump(Stream &s) const override; protected: typedef std::map collection; @@ -468,12 +657,49 @@ { } - virtual void - Dump (Stream &s) const; + bool + IsValid() const override + { + return false; + } + + void Dump(Stream &s) const override; 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(Stream &s) const override; + + private: + void *m_object; + }; static ObjectSP ParseJSON (std::string json_text); Index: include/lldb/DataFormatters/TypeSummary.h =================================================================== --- include/lldb/DataFormatters/TypeSummary.h +++ include/lldb/DataFormatters/TypeSummary.h @@ -25,8 +25,8 @@ #include "lldb/Core/Error.h" #include "lldb/Core/FormatEntity.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" #include "lldb/Symbol/Type.h" namespace lldb_private { @@ -501,8 +501,8 @@ { std::string m_function_name; std::string m_python_script; - lldb::ScriptInterpreterObjectSP m_script_function_sp; - + StructuredData::ObjectSP m_script_function_sp; + ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags, const char *function_name, const char* python_script = NULL); Index: include/lldb/DataFormatters/TypeSynthetic.h =================================================================== --- include/lldb/DataFormatters/TypeSynthetic.h +++ include/lldb/DataFormatters/TypeSynthetic.h @@ -23,6 +23,7 @@ #include "lldb/lldb-public.h" #include "lldb/lldb-enumerations.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObject.h" namespace lldb_private { @@ -551,7 +552,7 @@ { private: std::string m_python_class; - lldb::ScriptInterpreterObjectSP m_wrapper_sp; + StructuredData::ObjectSP m_wrapper_sp; ScriptInterpreter *m_interpreter; public: Index: include/lldb/Interpreter/PythonDataObjects.h =================================================================== --- include/lldb/Interpreter/PythonDataObjects.h +++ include/lldb/Interpreter/PythonDataObjects.h @@ -17,12 +17,61 @@ // Project includes #include "lldb/lldb-defines.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/Flags.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/lldb-python.h" namespace lldb_private { - +class PythonString; +class PythonList; +class PythonDictionary; +class PythonObject; +class PythonInteger; + +class StructuredPythonObject : public StructuredData::Generic +{ + public: + StructuredPythonObject() + : StructuredData::Generic() + { + } + + StructuredPythonObject(void *obj) + : StructuredData::Generic(obj) + { + Py_XINCREF(GetValue()); + } + + virtual ~StructuredPythonObject() + { + if (Py_IsInitialized()) + Py_XDECREF(GetValue()); + SetValue(nullptr); + } + + bool + IsValid() const override + { + return GetValue() && GetValue() != Py_None; + } + + void Dump(Stream &s) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); +}; + +enum class PyObjectType +{ + Unknown, + None, + Integer, + Dictionary, + List, + String +}; + class PythonObject { public: @@ -42,8 +91,6 @@ { Reset (rhs.m_py_obj); } - - explicit PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp); virtual ~PythonObject () @@ -89,6 +136,8 @@ return m_py_obj; } + PyObjectType GetObjectType() const; + PythonString Repr (); @@ -102,7 +151,9 @@ bool IsNULLOrNone () const; - + + StructuredData::ObjectSP CreateStructuredObject() const; + protected: PyObject* m_py_obj; }; @@ -110,14 +161,12 @@ class PythonString: public PythonObject { public: - PythonString (); PythonString (PyObject *o); PythonString (const PythonObject &object); - PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp); PythonString (const char* string); virtual ~PythonString (); - + virtual bool Reset (PyObject* py_obj = NULL); @@ -127,8 +176,9 @@ size_t GetSize() const; - void - SetString (const char* string); + void SetString(const char *string); + + StructuredData::StringSP CreateStructuredString() const; }; class PythonInteger: public PythonObject @@ -138,18 +188,18 @@ PythonInteger (); PythonInteger (PyObject* py_obj); PythonInteger (const PythonObject &object); - PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp); PythonInteger (int64_t value); virtual ~PythonInteger (); virtual bool Reset (PyObject* py_obj = NULL); - - int64_t - GetInteger(); - + + int64_t GetInteger() const; + void SetInteger (int64_t value); + + StructuredData::IntegerSP CreateStructuredInteger() const; }; class PythonList: public PythonObject @@ -159,24 +209,23 @@ PythonList (bool create_empty); PythonList (PyObject* py_obj); PythonList (const PythonObject &object); - PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp); PythonList (uint32_t count); virtual ~PythonList (); virtual bool Reset (PyObject* py_obj = NULL); - - uint32_t - GetSize(); - - PythonObject - GetItemAtIndex (uint32_t index); - + + uint32_t GetSize() const; + + PythonObject GetItemAtIndex(uint32_t index) const; + void SetItemAtIndex (uint32_t index, const PythonObject &object); void AppendItem (const PythonObject &object); + + StructuredData::ArraySP CreateStructuredArray() const; }; class PythonDictionary: public PythonObject @@ -186,14 +235,13 @@ explicit PythonDictionary (bool create_empty); PythonDictionary (PyObject* object); PythonDictionary (const PythonObject &object); - PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp); virtual ~PythonDictionary (); virtual bool Reset (PyObject* object = NULL); - - uint32_t GetSize(); - + + uint32_t GetSize() const; + PythonObject GetItemForKey (const PythonString &key) const; @@ -222,6 +270,8 @@ void SetItemForKey (const PythonString &key, const PythonObject& value); + + StructuredData::DictionarySP CreateStructuredDictionary() const; }; } // namespace lldb_private Index: include/lldb/Interpreter/ScriptInterpreter.h =================================================================== --- include/lldb/Interpreter/ScriptInterpreter.h +++ include/lldb/Interpreter/ScriptInterpreter.h @@ -14,53 +14,12 @@ #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Utility/PseudoTerminal.h" namespace lldb_private { - -class ScriptInterpreterObject -{ -public: - ScriptInterpreterObject() : - m_object(NULL) - {} - - ScriptInterpreterObject(void* obj) : - m_object(obj) - {} - - ScriptInterpreterObject(const ScriptInterpreterObject& rhs) - : m_object(rhs.m_object) - {} - - virtual void* - GetObject() - { - return m_object; - } - - explicit operator bool () - { - return m_object != NULL; - } - - ScriptInterpreterObject& - operator = (const ScriptInterpreterObject& rhs) - { - if (this != &rhs) - m_object = rhs.m_object; - return *this; - } - - virtual - ~ScriptInterpreterObject() - {} - -protected: - void* m_object; -}; class ScriptInterpreterLocker { @@ -324,95 +283,80 @@ { return false; } - - virtual lldb::ScriptInterpreterObjectSP - CreateSyntheticScriptedProvider (const char *class_name, - lldb::ValueObjectSP valobj) + + virtual StructuredData::ObjectSP + CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ObjectSP(); } - - virtual lldb::ScriptInterpreterObjectSP - OSPlugin_CreatePluginObject (const char *class_name, - lldb::ProcessSP process_sp) + + virtual StructuredData::GenericSP + OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::GenericSP(); } - - virtual lldb::ScriptInterpreterObjectSP - OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) + + virtual StructuredData::DictionarySP + OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } - - virtual lldb::ScriptInterpreterObjectSP - OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) + + virtual StructuredData::ArraySP + OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ArraySP(); } - - virtual lldb::ScriptInterpreterObjectSP - OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, - lldb::tid_t thread_id) + + virtual StructuredData::StringSP + OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t thread_id) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::StringSP(); } - virtual lldb::ScriptInterpreterObjectSP - OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, - lldb::tid_t tid, - lldb::addr_t context) + virtual StructuredData::DictionarySP + OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } - - virtual lldb::ScriptInterpreterObjectSP - CreateScriptedThreadPlan (const char *class_name, - lldb::ThreadPlanSP thread_plan_sp) + + virtual StructuredData::ObjectSP + CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan_sp) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ObjectSP(); } virtual bool - ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp, - Event *event, - bool &script_error) + ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { script_error = true; return true; } virtual bool - ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp, - Event *event, - bool &script_error) + ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { script_error = true; return true; } virtual lldb::StateType - ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp, - bool &script_error) + ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) { script_error = true; return lldb::eStateStepping; } - virtual lldb::ScriptInterpreterObjectSP - LoadPluginModule (const FileSpec& file_spec, - lldb_private::Error& error) + virtual StructuredData::ObjectSP + LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ObjectSP(); } - - virtual lldb::ScriptInterpreterObjectSP - GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp, - Target* target, - const char* setting_name, - lldb_private::Error& error) + + virtual StructuredData::DictionarySP + GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Error &error) { - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } virtual Error @@ -464,13 +408,10 @@ { return; } - + virtual bool - GetScriptedSummary (const char *function_name, - lldb::ValueObjectSP valobj, - lldb::ScriptInterpreterObjectSP& callee_wrapper_sp, - const TypeSummaryOptions& options, - std::string& retval) + GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, + const TypeSummaryOptions &options, std::string &retval) { return false; } @@ -480,39 +421,39 @@ { // Clean up any ref counts to SBObjects that might be in global variables } - + virtual size_t - CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor) + CalculateNumChildren(const StructuredData::ObjectSP &implementor) { return 0; } - + virtual lldb::ValueObjectSP - GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx) + GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) { return lldb::ValueObjectSP(); } - + virtual int - GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name) + GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) { return UINT32_MAX; } - + virtual bool - UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) + UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) { return false; } - + virtual bool - MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) + MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) { return true; } - + virtual lldb::ValueObjectSP - GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor) + GetSyntheticValue(const StructuredData::ObjectSP &implementor) { return nullptr; } @@ -592,11 +533,8 @@ } virtual bool - LoadScriptingModule (const char* filename, - bool can_reload, - bool init_session, - lldb_private::Error& error, - lldb::ScriptInterpreterObjectSP* module_sp = nullptr) + LoadScriptingModule(const char *filename, bool can_reload, bool init_session, lldb_private::Error &error, + StructuredData::ObjectSP *module_sp = nullptr) { error.SetErrorString("loading unimplemented"); return false; @@ -607,12 +545,6 @@ { return false; } - - virtual lldb::ScriptInterpreterObjectSP - MakeScriptObject (void* object) - { - return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterObject(object)); - } virtual std::unique_ptr AcquireInterpreterLock (); Index: include/lldb/Interpreter/ScriptInterpreterPython.h =================================================================== --- include/lldb/Interpreter/ScriptInterpreterPython.h +++ include/lldb/Interpreter/ScriptInterpreterPython.h @@ -79,74 +79,43 @@ bool GenerateScriptAliasFunction (StringList &input, std::string& output) override; - - lldb::ScriptInterpreterObjectSP - CreateSyntheticScriptedProvider (const char *class_name, - lldb::ValueObjectSP valobj) override; - lldb::ScriptInterpreterObjectSP - CreateScriptedThreadPlan (const char *class_name, - lldb::ThreadPlanSP thread_plan) override; + StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) override; + + StructuredData::ObjectSP CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan) override; + + bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override; + bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override; + lldb::StateType ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) override; + + StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) override; + + StructuredData::DictionarySP OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; + + StructuredData::ArraySP OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; + + StructuredData::StringSP OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t thread_id) override; + + StructuredData::DictionarySP OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, + lldb::addr_t context) override; + + StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error) override; + + StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, + lldb_private::Error &error) override; + + size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor) override; + + lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override; + + int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override; + + bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override; + + bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override; + + lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; - bool - ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp, - Event *event, - bool &script_error) override; - bool - ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp, - Event *event, - bool &script_error) override; - lldb::StateType - ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp, - bool &script_error) override; - - lldb::ScriptInterpreterObjectSP - OSPlugin_CreatePluginObject (const char *class_name, - lldb::ProcessSP process_sp) override; - - lldb::ScriptInterpreterObjectSP - OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) override; - - lldb::ScriptInterpreterObjectSP - OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) override; - - lldb::ScriptInterpreterObjectSP - OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, - lldb::tid_t thread_id) override; - - lldb::ScriptInterpreterObjectSP - OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, - lldb::tid_t tid, - lldb::addr_t context) override; - - lldb::ScriptInterpreterObjectSP - LoadPluginModule (const FileSpec& file_spec, - lldb_private::Error& error) override; - - lldb::ScriptInterpreterObjectSP - GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp, - Target* target, - const char* setting_name, - lldb_private::Error& error) override; - - size_t - CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor) override; - - lldb::ValueObjectSP - GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx) override; - - int - GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name) override; - - bool - UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) override; - - bool - MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) override; - - lldb::ValueObjectSP - GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor) override; - bool RunScriptBasedCommand(const char* impl_function, const char* args, @@ -188,14 +157,10 @@ WatchpointCallbackFunction (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id); - - bool - GetScriptedSummary (const char *function_name, - lldb::ValueObjectSP valobj, - lldb::ScriptInterpreterObjectSP& callee_wrapper_sp, - const TypeSummaryOptions& options, - std::string& retval) override; - + + bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, + const TypeSummaryOptions &options, std::string &retval) override; + void Clear () override; @@ -240,20 +205,13 @@ ValueObject* value, std::string& output, Error& error) override; - - bool - LoadScriptingModule (const char* filename, - bool can_reload, - bool init_session, - lldb_private::Error& error, - lldb::ScriptInterpreterObjectSP* module_sp = nullptr) override; - + + bool LoadScriptingModule(const char *filename, bool can_reload, bool init_session, lldb_private::Error &error, + StructuredData::ObjectSP *module_sp = nullptr) override; + bool IsReservedWord (const char* word) override; - - lldb::ScriptInterpreterObjectSP - MakeScriptObject (void* object) override; - + std::unique_ptr AcquireInterpreterLock () override; @@ -372,35 +330,6 @@ ~SynchronicityHandler(); }; - class ScriptInterpreterPythonObject : public ScriptInterpreterObject - { - public: - ScriptInterpreterPythonObject() : - ScriptInterpreterObject() - {} - - ScriptInterpreterPythonObject(void* obj) : - ScriptInterpreterObject(obj) - { - Py_XINCREF(m_object); - } - - explicit operator bool () - { - return m_object && m_object != Py_None; - } - - - virtual - ~ScriptInterpreterPythonObject() - { - if (Py_IsInitialized()) - Py_XDECREF(m_object); - m_object = NULL; - } - private: - DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject); - }; public: class Locker : public ScriptInterpreterLocker { Index: include/lldb/Target/ThreadPlanPython.h =================================================================== --- include/lldb/Target/ThreadPlanPython.h +++ include/lldb/Target/ThreadPlanPython.h @@ -16,6 +16,7 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/UserID.h" #include "lldb/Host/Mutex.h" #include "lldb/Target/Process.h" @@ -68,8 +69,8 @@ GetPlanRunState (); private: - std::string m_class_name; - lldb::ScriptInterpreterObjectSP m_implementation_sp; + std::string m_class_name; + StructuredData::ObjectSP m_implementation_sp; DISALLOW_COPY_AND_ASSIGN(ThreadPlanPython); }; Index: include/lldb/lldb-forward.h =================================================================== --- include/lldb/lldb-forward.h +++ include/lldb/lldb-forward.h @@ -171,11 +171,6 @@ class ProcessLaunchInfo; class Property; struct PropertyDefinition; -class PythonArray; -class PythonDictionary; -class PythonInteger; -class PythonObject; -class PythonString; class RegisterCheckpoint; class RegisterContext; class RegisterLocation; @@ -185,7 +180,6 @@ class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; -class ScriptInterpreterObject; #ifndef LLDB_DISABLE_PYTHON class ScriptInterpreterPython; struct ScriptSummaryFormat; @@ -380,7 +374,6 @@ typedef std::shared_ptr QueueSP; typedef std::weak_ptr QueueWP; typedef std::shared_ptr QueueItemSP; - typedef std::shared_ptr ScriptInterpreterObjectSP; #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr ScriptSummaryFormatSP; #endif // #ifndef LLDB_DISABLE_PYTHON Index: source/Core/StructuredData.cpp =================================================================== --- source/Core/StructuredData.cpp +++ source/Core/StructuredData.cpp @@ -13,6 +13,8 @@ #include #include +#include "lldb/Core/StreamString.h" + using namespace lldb_private; @@ -350,7 +352,15 @@ } void -StructuredData::Array::Dump (Stream &s) const +StructuredData::Object::DumpToStdout() const +{ + StreamString stream; + Dump(stream); + printf("%s", stream.GetString().c_str()); +} + +void +StructuredData::Array::Dump(Stream &s) const { s << "["; const size_t arrsize = m_items.size(); @@ -427,3 +437,9 @@ { s << "null"; } + +void +StructuredData::Generic::Dump(Stream &s) const +{ + s << "0x" << m_object; +} Index: source/DataFormatters/TypeSynthetic.cpp =================================================================== --- source/DataFormatters/TypeSynthetic.cpp +++ source/DataFormatters/TypeSynthetic.cpp @@ -196,7 +196,7 @@ bool ScriptedSyntheticChildren::FrontEnd::IsValid () { - return m_wrapper_sp.get() != nullptr && m_wrapper_sp->operator bool() && m_interpreter != nullptr; + return (m_wrapper_sp && m_wrapper_sp->IsValid() && m_interpreter); } size_t Index: source/Interpreter/PythonDataObjects.cpp =================================================================== --- source/Interpreter/PythonDataObjects.cpp +++ source/Interpreter/PythonDataObjects.cpp @@ -23,19 +23,20 @@ #include "lldb/Host/File.h" #include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreterPython.h" using namespace lldb_private; using namespace lldb; +void +StructuredPythonObject::Dump(Stream &s) const +{ + s << "Python Obj: 0x" << GetValue(); +} + //---------------------------------------------------------------------- // PythonObject //---------------------------------------------------------------------- -PythonObject::PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - m_py_obj (nullptr) -{ - if (script_object_sp) - Reset ((PyObject *)script_object_sp->GetObject()); -} void PythonObject::Dump (Stream &strm) const @@ -62,6 +63,23 @@ strm.PutCString ("NULL"); } +PyObjectType +PythonObject::GetObjectType() const +{ + if (IsNULLOrNone()) + return PyObjectType::None; + + if (PyList_Check(m_py_obj)) + return PyObjectType::List; + if (PyDict_Check(m_py_obj)) + return PyObjectType::Dictionary; + if (PyString_Check(m_py_obj)) + return PyObjectType::String; + if (PyInt_Check(m_py_obj)) + return PyObjectType::Integer; + return PyObjectType::Unknown; +} + PythonString PythonObject::Repr () { @@ -90,6 +108,26 @@ return ((m_py_obj == nullptr) || (m_py_obj == Py_None)); } +StructuredData::ObjectSP +PythonObject::CreateStructuredObject() const +{ + switch (GetObjectType()) + { + case PyObjectType::Dictionary: + return PythonDictionary(m_py_obj).CreateStructuredDictionary(); + case PyObjectType::Integer: + return PythonInteger(m_py_obj).CreateStructuredInteger(); + case PyObjectType::List: + return PythonList(m_py_obj).CreateStructuredArray(); + case PyObjectType::String: + return PythonString(m_py_obj).CreateStructuredString(); + case PyObjectType::None: + return StructuredData::ObjectSP(); + default: + return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); + } +} + //---------------------------------------------------------------------- // PythonString //---------------------------------------------------------------------- @@ -106,13 +144,6 @@ Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string } -PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject() -{ - if (script_object_sp) - Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a string -} - PythonString::PythonString (const char* string) : PythonObject(PyString_FromString(string)) { @@ -159,6 +190,14 @@ PythonObject::Reset(PyString_FromString(string)); } +StructuredData::StringSP +PythonString::CreateStructuredString() const +{ + StructuredData::StringSP result(new StructuredData::String); + result->SetValue(GetString()); + return result; +} + //---------------------------------------------------------------------- // PythonInteger //---------------------------------------------------------------------- @@ -175,13 +214,6 @@ Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type } -PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject() -{ - if (script_object_sp) - Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a string -} - PythonInteger::PythonInteger (int64_t value) : PythonObject() { @@ -207,7 +239,7 @@ } int64_t -PythonInteger::GetInteger() +PythonInteger::GetInteger() const { if (m_py_obj) { @@ -225,6 +257,14 @@ PythonObject::Reset(PyLong_FromLongLong(value)); } +StructuredData::IntegerSP +PythonInteger::CreateStructuredInteger() const +{ + StructuredData::IntegerSP result(new StructuredData::Integer); + result->SetValue(GetInteger()); + return result; +} + //---------------------------------------------------------------------- // PythonList //---------------------------------------------------------------------- @@ -252,13 +292,6 @@ Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list } -PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject() -{ - if (script_object_sp) - Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a list -} - PythonList::~PythonList () { } @@ -274,7 +307,7 @@ } uint32_t -PythonList::GetSize() +PythonList::GetSize() const { if (m_py_obj) return PyList_GET_SIZE(m_py_obj); @@ -282,7 +315,7 @@ } PythonObject -PythonList::GetItemAtIndex (uint32_t index) +PythonList::GetItemAtIndex(uint32_t index) const { if (m_py_obj) return PythonObject(PyList_GetItem(m_py_obj, index)); @@ -303,6 +336,19 @@ PyList_Append(m_py_obj, object.get()); } +StructuredData::ArraySP +PythonList::CreateStructuredArray() const +{ + StructuredData::ArraySP result(new StructuredData::Array); + uint32_t count = GetSize(); + for (uint32_t i = 0; i < count; ++i) + { + PythonObject obj = GetItemAtIndex(i); + result->AddItem(StructuredData::ObjectSP(new StructuredPythonObject(obj.get()))); + } + return result; +} + //---------------------------------------------------------------------- // PythonDictionary //---------------------------------------------------------------------- @@ -325,13 +371,6 @@ Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary } -PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject () -{ - if (script_object_sp) - Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a dictionary -} - PythonDictionary::~PythonDictionary () { } @@ -347,7 +386,7 @@ } uint32_t -PythonDictionary::GetSize() +PythonDictionary::GetSize() const { if (m_py_obj) return PyDict_Size(m_py_obj); @@ -460,4 +499,21 @@ PyDict_SetItem(m_py_obj, key.get(), value.get()); } +StructuredData::DictionarySP +PythonDictionary::CreateStructuredDictionary() const +{ + StructuredData::DictionarySP result(new StructuredData::Dictionary); + PythonList keys(GetKeys()); + uint32_t num_keys = keys.GetSize(); + for (uint32_t i = 0; i < num_keys; ++i) + { + PythonObject key = keys.GetItemAtIndex(i); + PythonString key_str = key.Str(); + PythonObject value = GetItemForKey(key); + StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); + result->AddItem(key_str.GetString(), structured_value); + } + return result; +} + #endif Index: source/Interpreter/ScriptInterpreterPython.cpp =================================================================== --- source/Interpreter/ScriptInterpreterPython.cpp +++ source/Interpreter/ScriptInterpreterPython.cpp @@ -1350,15 +1350,15 @@ return true; } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp) +StructuredData::GenericSP +ScriptInterpreterPython::OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) { if (class_name == nullptr || class_name[0] == '\0') - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::GenericSP(); + if (!process_sp) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::GenericSP(); + void* ret_val; { @@ -1369,12 +1369,12 @@ m_dictionary_name.c_str(), process_sp); } - - return MakeScriptObject(ret_val); + + return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) +StructuredData::DictionarySP +ScriptInterpreterPython::OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) { Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, @@ -1383,13 +1383,17 @@ static char callee_name[] = "get_register_info"; if (!os_plugin_object_sp) - return lldb::ScriptInterpreterObjectSP(); - - PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); - + return StructuredData::DictionarySP(); + + StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); + if (!generic) + return nullptr; + + PyObject *implementor = (PyObject *)generic->GetValue(); + if (implementor == nullptr || implementor == Py_None) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::DictionarySP(); + PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); if (PyErr_Occurred()) @@ -1400,7 +1404,7 @@ if (pmeth == nullptr || pmeth == Py_None) { Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } if (PyCallable_Check(pmeth) == 0) @@ -1411,7 +1415,7 @@ } Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } if (PyErr_Occurred()) @@ -1430,27 +1434,31 @@ PyErr_Print(); PyErr_Clear(); } - - return MakeScriptObject(py_return); + + PythonDictionary result_dict(py_return); + return result_dict.CreateStructuredDictionary(); } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) +StructuredData::ArraySP +ScriptInterpreterPython::OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) { Locker py_lock (this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); static char callee_name[] = "get_thread_info"; - + if (!os_plugin_object_sp) - return lldb::ScriptInterpreterObjectSP(); - - PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); - + return StructuredData::ArraySP(); + + StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); + if (!generic) + return nullptr; + PyObject *implementor = (PyObject *)generic->GetValue(); + if (implementor == nullptr || implementor == Py_None) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::ArraySP(); + PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); if (PyErr_Occurred()) @@ -1461,7 +1469,7 @@ if (pmeth == nullptr || pmeth == Py_None) { Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ArraySP(); } if (PyCallable_Check(pmeth) == 0) @@ -1472,7 +1480,7 @@ } Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ArraySP(); } if (PyErr_Occurred()) @@ -1491,8 +1499,9 @@ PyErr_Print(); PyErr_Clear(); } - - return MakeScriptObject(py_return); + + PythonList ResultList(py_return); + return ResultList.CreateStructuredArray(); } // GetPythonValueFormatString provides a system independent type safe way to @@ -1521,9 +1530,8 @@ template <> const char *GetPythonValueFormatString (float t) { return "f"; } template <> const char *GetPythonValueFormatString (double t) { return "d"; } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, - lldb::tid_t tid) +StructuredData::StringSP +ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) { Locker py_lock (this, Locker::AcquireLock | Locker::NoSTDIN, @@ -1533,12 +1541,15 @@ static char *param_format = const_cast(GetPythonValueFormatString(tid)); if (!os_plugin_object_sp) - return lldb::ScriptInterpreterObjectSP(); - - PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); - + return StructuredData::StringSP(); + + StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); + if (!generic) + return nullptr; + PyObject *implementor = (PyObject *)generic->GetValue(); + if (implementor == nullptr || implementor == Py_None) - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::StringSP(); PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); @@ -1550,7 +1561,7 @@ if (pmeth == nullptr || pmeth == Py_None) { Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::StringSP(); } if (PyCallable_Check(pmeth) == 0) @@ -1561,7 +1572,7 @@ } Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::StringSP(); } if (PyErr_Occurred()) @@ -1580,14 +1591,12 @@ PyErr_Print(); PyErr_Clear(); } - - return MakeScriptObject(py_return); + PythonString result_string(py_return); + return result_string.CreateStructuredString(); } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, - lldb::tid_t tid, - lldb::addr_t context) +StructuredData::DictionarySP +ScriptInterpreterPython::OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context) { Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, @@ -1599,13 +1608,16 @@ param_format += GetPythonValueFormatString(context); if (!os_plugin_object_sp) - return lldb::ScriptInterpreterObjectSP(); - - PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); - + return StructuredData::DictionarySP(); + + StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); + if (!generic) + return nullptr; + PyObject *implementor = (PyObject *)generic->GetValue(); + if (implementor == nullptr || implementor == Py_None) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::DictionarySP(); + PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); if (PyErr_Occurred()) @@ -1616,7 +1628,7 @@ if (pmeth == nullptr || pmeth == Py_None) { Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } if (PyCallable_Check(pmeth) == 0) @@ -1627,7 +1639,7 @@ } Py_XDECREF(pmeth); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::DictionarySP(); } if (PyErr_Occurred()) @@ -1646,27 +1658,27 @@ PyErr_Print(); PyErr_Clear(); } - - return MakeScriptObject(py_return); + + PythonDictionary result_dict(py_return); + return result_dict.CreateStructuredDictionary(); } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::CreateScriptedThreadPlan (const char *class_name, - lldb::ThreadPlanSP thread_plan_sp) +StructuredData::ObjectSP +ScriptInterpreterPython::CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan_sp) { if (class_name == nullptr || class_name[0] == '\0') - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::ObjectSP(); + if (!thread_plan_sp.get()) - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ObjectSP(); Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger(); ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter(); ScriptInterpreterPython *python_interpreter = static_cast(script_interpreter); if (!script_interpreter) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::ObjectSP(); + void* ret_val; { @@ -1676,20 +1688,21 @@ python_interpreter->m_dictionary_name.c_str(), thread_plan_sp); } - - return MakeScriptObject(ret_val); + + return StructuredData::ObjectSP(new StructuredPythonObject(ret_val)); } bool -ScriptInterpreterPython::ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp, - Event *event, - bool &script_error) +ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { bool explains_stop = true; + StructuredData::Generic *generic = nullptr; if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - explains_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "explains_stop", event, script_error); + explains_stop = g_swig_call_thread_plan(generic->GetValue(), "explains_stop", event, script_error); if (script_error) return true; } @@ -1697,15 +1710,16 @@ } bool -ScriptInterpreterPython::ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp, - Event *event, - bool &script_error) +ScriptInterpreterPython::ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { bool should_stop = true; + StructuredData::Generic *generic = nullptr; if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - should_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_stop", event, script_error); + should_stop = g_swig_call_thread_plan(generic->GetValue(), "should_stop", event, script_error); if (script_error) return true; } @@ -1713,14 +1727,16 @@ } lldb::StateType -ScriptInterpreterPython::ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp, - bool &script_error) +ScriptInterpreterPython::ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) { bool should_step = false; + StructuredData::Generic *generic = nullptr; if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - should_step = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_step", NULL, script_error); + should_step = g_swig_call_thread_plan(generic->GetValue(), "should_step", NULL, script_error); if (script_error) should_step = true; } @@ -1730,72 +1746,69 @@ return lldb::eStateRunning; } - -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec, - lldb_private::Error& error) +StructuredData::ObjectSP +ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error) { if (!file_spec.Exists()) { error.SetErrorString("no such file"); - return lldb::ScriptInterpreterObjectSP(); + return StructuredData::ObjectSP(); } - ScriptInterpreterObjectSP module_sp; - + StructuredData::ObjectSP module_sp; + if (LoadScriptingModule(file_spec.GetPath().c_str(),true,true,error,&module_sp)) return module_sp; - - return lldb::ScriptInterpreterObjectSP(); + + return StructuredData::ObjectSP(); } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp, - Target* target, - const char* setting_name, - lldb_private::Error& error) +StructuredData::DictionarySP +ScriptInterpreterPython::GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, + lldb_private::Error &error) { - if (!plugin_module_sp || !target || !setting_name || !setting_name[0]) - return lldb::ScriptInterpreterObjectSP(); - - if (!g_swig_plugin_get) - return lldb::ScriptInterpreterObjectSP(); - + if (!plugin_module_sp || !target || !setting_name || !setting_name[0] || !g_swig_plugin_get) + return StructuredData::DictionarySP(); + StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric(); + if (!generic) + return StructuredData::DictionarySP(); + PyObject *reply_pyobj = nullptr; { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); TargetSP target_sp(target->shared_from_this()); - reply_pyobj = (PyObject*)g_swig_plugin_get(plugin_module_sp->GetObject(),setting_name,target_sp); + reply_pyobj = (PyObject *)g_swig_plugin_get(generic->GetValue(), setting_name, target_sp); } - - return MakeScriptObject(reply_pyobj); + + PythonDictionary py_dict(reply_pyobj); + + return py_dict.CreateStructuredDictionary(); } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name, - lldb::ValueObjectSP valobj) +StructuredData::ObjectSP +ScriptInterpreterPython::CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) { if (class_name == nullptr || class_name[0] == '\0') - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::ObjectSP(); + if (!valobj.get()) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::ObjectSP(); + ExecutionContext exe_ctx (valobj->GetExecutionContextRef()); Target *target = exe_ctx.GetTargetPtr(); if (!target) - return lldb::ScriptInterpreterObjectSP(); - + return StructuredData::ObjectSP(); + Debugger &debugger = target->GetDebugger(); ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter(); ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter; if (!script_interpreter) - return lldb::ScriptInterpreterObjectSP(); - - void* ret_val; + return StructuredData::ObjectSP(); + + void *ret_val = nullptr; { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); @@ -1803,8 +1816,8 @@ python_interpreter->m_dictionary_name.c_str(), valobj); } - - return MakeScriptObject(ret_val); + + return StructuredData::ObjectSP(new StructuredPythonObject(ret_val)); } bool @@ -1871,11 +1884,9 @@ } bool -ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name, - lldb::ValueObjectSP valobj, - lldb::ScriptInterpreterObjectSP& callee_wrapper_sp, - const TypeSummaryOptions& options, - std::string& retval) +ScriptInterpreterPython::GetScriptedSummary(const char *python_function_name, lldb::ValueObjectSP valobj, + StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, + std::string &retval) { Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); @@ -1885,13 +1896,19 @@ retval.assign(""); return false; } - - void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : nullptr); + + void *old_callee = nullptr; + StructuredData::Generic *generic = nullptr; + if (callee_wrapper_sp) + { + generic = callee_wrapper_sp->GetAsGeneric(); + if (generic) + old_callee = generic->GetValue(); + } void* new_callee = old_callee; bool ret_val; - if (python_function_name - && *python_function_name) + if (python_function_name && *python_function_name) { { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); @@ -1915,10 +1932,9 @@ } if (new_callee && old_callee != new_callee) - callee_wrapper_sp = MakeScriptObject(new_callee); - + callee_wrapper_sp.reset(new StructuredPythonObject(new_callee)); + return ret_val; - } void @@ -2044,13 +2060,14 @@ } size_t -ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp) +ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &implementor_sp) { if (!implementor_sp) return 0; - - void* implementor = implementor_sp->GetObject(); - + StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); + if (!generic) + return 0; + void *implementor = generic->GetValue(); if (!implementor) return 0; @@ -2068,13 +2085,15 @@ } lldb::ValueObjectSP -ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor_sp, uint32_t idx) +ScriptInterpreterPython::GetChildAtIndex(const StructuredData::ObjectSP &implementor_sp, uint32_t idx) { if (!implementor_sp) return lldb::ValueObjectSP(); - - void* implementor = implementor_sp->GetObject(); - + + StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); + if (!generic) + return lldb::ValueObjectSP(); + void *implementor = generic->GetValue(); if (!implementor) return lldb::ValueObjectSP(); @@ -2104,13 +2123,15 @@ } int -ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor_sp, const char* child_name) +ScriptInterpreterPython::GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor_sp, const char *child_name) { if (!implementor_sp) return UINT32_MAX; - - void* implementor = implementor_sp->GetObject(); - + + StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); + if (!generic) + return UINT32_MAX; + void *implementor = generic->GetValue(); if (!implementor) return UINT32_MAX; @@ -2128,15 +2149,17 @@ } bool -ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp) +ScriptInterpreterPython::UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp) { bool ret_val = false; if (!implementor_sp) return ret_val; - - void* implementor = implementor_sp->GetObject(); - + + StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); + if (!generic) + return ret_val; + void *implementor = generic->GetValue(); if (!implementor) return ret_val; @@ -2152,15 +2175,17 @@ } bool -ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp) +ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp) { bool ret_val = false; if (!implementor_sp) return ret_val; - - void* implementor = implementor_sp->GetObject(); - + + StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); + if (!generic) + return ret_val; + void *implementor = generic->GetValue(); if (!implementor) return ret_val; @@ -2176,15 +2201,17 @@ } lldb::ValueObjectSP -ScriptInterpreterPython::GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor_sp) +ScriptInterpreterPython::GetSyntheticValue(const StructuredData::ObjectSP &implementor_sp) { lldb::ValueObjectSP ret_val(nullptr); if (!implementor_sp) return ret_val; - - void* implementor = implementor_sp->GetObject(); - + + StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); + if (!generic) + return ret_val; + void *implementor = generic->GetValue(); if (!implementor) return ret_val; @@ -2442,11 +2469,8 @@ } bool -ScriptInterpreterPython::LoadScriptingModule (const char* pathname, - bool can_reload, - bool init_session, - lldb_private::Error& error, - lldb::ScriptInterpreterObjectSP* module_sp) +ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_reload, bool init_session, lldb_private::Error &error, + StructuredData::ObjectSP *module_sp) { if (!pathname || !pathname[0]) { @@ -2577,7 +2601,7 @@ command_stream.Printf("%s",basename.c_str()); void* module_pyobj = nullptr; if (ExecuteOneLineWithReturn(command_stream.GetData(),ScriptInterpreter::eScriptReturnTypeOpaqueObject,&module_pyobj) && module_pyobj) - *module_sp = MakeScriptObject(module_pyobj); + module_sp->reset(new StructuredPythonObject(module_pyobj)); } return true; @@ -2599,12 +2623,6 @@ return false; } -lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::MakeScriptObject (void* object) -{ - return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterPythonObject(object)); -} - ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro) : m_debugger_sp(debugger_sp), Index: source/Plugins/OperatingSystem/Python/OperatingSystemPython.h =================================================================== --- source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -14,11 +14,16 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Target/OperatingSystem.h" class DynamicRegisterInfo; +namespace lldb_private +{ +class ScriptInterpreter; +} + class OperatingSystemPython : public lldb_private::OperatingSystem { public: @@ -86,15 +91,12 @@ bool IsValid() const { - return m_python_object_sp && m_python_object_sp->GetObject() != NULL; + return m_python_object_sp && m_python_object_sp->IsValid(); } - - lldb::ThreadSP - CreateThreadFromThreadInfo (lldb_private::PythonDictionary &thread_dict, - lldb_private::ThreadList &core_thread_list, - lldb_private::ThreadList &old_thread_list, - std::vector &core_used_map, - bool *did_create_ptr); + + lldb::ThreadSP CreateThreadFromThreadInfo(lldb_private::StructuredData::Dictionary &thread_dict, + lldb_private::ThreadList &core_thread_list, lldb_private::ThreadList &old_thread_list, + std::vector &core_used_map, bool *did_create_ptr); DynamicRegisterInfo * GetDynamicRegisterInfo (); @@ -102,8 +104,7 @@ lldb::ValueObjectSP m_thread_list_valobj_sp; std::unique_ptr m_register_info_ap; lldb_private::ScriptInterpreter *m_interpreter; - lldb::ScriptInterpreterObjectSP m_python_object_sp; - + lldb_private::StructuredData::ObjectSP m_python_object_sp; }; #endif // #ifndef liblldb_OperatingSystemPython_h_ Index: source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp =================================================================== --- source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -22,9 +22,10 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/PythonDataObjects.h" +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/VariableList.h" @@ -116,8 +117,9 @@ os_plugin_class_name.erase (py_extension_pos); // Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn" os_plugin_class_name += ".OperatingSystemPlugIn"; - ScriptInterpreterObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess()); - if (object_sp && object_sp->GetObject()) + StructuredData::ObjectSP object_sp = + m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess()); + if (object_sp && object_sp->IsValid()) m_python_object_sp = object_sp; } } @@ -139,12 +141,12 @@ if (log) log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID()); - - PythonDictionary dictionary(m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp)); + + StructuredData::DictionarySP dictionary = m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp); if (!dictionary) return NULL; - - m_register_info_ap.reset (new DynamicRegisterInfo (dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder())); + + m_register_info_ap.reset(new DynamicRegisterInfo(*dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder())); assert (m_register_info_ap->GetNumRegisters() > 0); assert (m_register_info_ap->GetNumRegisterSets() > 0); } @@ -189,8 +191,8 @@ // lldb_private::Process subclass, no memory threads will be in this list. auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive - PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp)); - + StructuredData::ArraySP threads_list = m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp); + const uint32_t num_cores = core_thread_list.GetSize(false); // Make a map so we can keep track of which cores were used from the @@ -202,22 +204,19 @@ if (log) { StreamString strm; - threads_list.Dump(strm); + threads_list->Dump(strm); log->Printf("threads_list = %s", strm.GetString().c_str()); } - uint32_t i; - const uint32_t num_threads = threads_list.GetSize(); - if (num_threads > 0) + + const uint32_t num_threads = threads_list->GetSize(); + for (uint32_t i = 0; i < num_threads; ++i) { - for (i=0; iGetItemAtIndex(i); + if (auto thread_dict = thread_dict_obj->GetAsDictionary()) { - PythonDictionary thread_dict(threads_list.GetItemAtIndex(i)); - if (thread_dict) - { - ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, core_thread_list, old_thread_list, core_used_map, NULL)); - if (thread_sp) - new_thread_list.AddThread(thread_sp); - } + ThreadSP thread_sp(CreateThreadFromThreadInfo(*thread_dict, core_thread_list, old_thread_list, core_used_map, NULL)); + if (thread_sp) + new_thread_list.AddThread(thread_sp); } } } @@ -239,79 +238,63 @@ } ThreadSP -OperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict, - ThreadList &core_thread_list, - ThreadList &old_thread_list, - std::vector &core_used_map, - bool *did_create_ptr) +OperatingSystemPython::CreateThreadFromThreadInfo(StructuredData::Dictionary &thread_dict, ThreadList &core_thread_list, + ThreadList &old_thread_list, std::vector &core_used_map, bool *did_create_ptr) { ThreadSP thread_sp; - if (thread_dict) + tid_t tid = LLDB_INVALID_THREAD_ID; + if (!thread_dict.GetValueForKeyAsInteger("tid", tid)) + return ThreadSP(); + + uint32_t core_number; + addr_t reg_data_addr; + std::string name; + std::string queue; + + thread_dict.GetValueForKeyAsInteger("core", core_number, UINT32_MAX); + thread_dict.GetValueForKeyAsInteger("register_data_addr", reg_data_addr, LLDB_INVALID_ADDRESS); + thread_dict.GetValueForKeyAsString("name", name); + thread_dict.GetValueForKeyAsString("queue", queue); + + // See if a thread already exists for "tid" + thread_sp = old_thread_list.FindThreadByID(tid, false); + if (thread_sp) { - PythonString tid_pystr("tid"); - const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID); - if (tid != LLDB_INVALID_THREAD_ID) + // A thread already does exist for "tid", make sure it was an operating system + // plug-in generated thread. + if (!IsOperatingSystemPluginThread(thread_sp)) { - PythonString core_pystr("core"); - PythonString name_pystr("name"); - PythonString queue_pystr("queue"); - //PythonString state_pystr("state"); - //PythonString stop_reason_pystr("stop_reason"); - PythonString reg_data_addr_pystr ("register_data_addr"); - - const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX); - const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS); - const char *name = thread_dict.GetItemForKeyAsString (name_pystr); - const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr); - //const char *state = thread_dict.GetItemForKeyAsString (state_pystr); - //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr); - - // See if a thread already exists for "tid" - thread_sp = old_thread_list.FindThreadByID (tid, false); - if (thread_sp) - { - // A thread already does exist for "tid", make sure it was an operating system - // plug-in generated thread. - if (!IsOperatingSystemPluginThread(thread_sp)) - { - // We have thread ID overlap between the protocol threads and the - // operating system threads, clear the thread so we create an - // operating system thread for this. - thread_sp.reset(); - } - } - - if (!thread_sp) + // We have thread ID overlap between the protocol threads and the + // operating system threads, clear the thread so we create an + // operating system thread for this. + thread_sp.reset(); + } + } + + if (!thread_sp) + { + if (did_create_ptr) + *did_create_ptr = true; + thread_sp.reset(new ThreadMemory(*m_process, tid, name.c_str(), queue.c_str(), reg_data_addr)); + } + + if (core_number < core_thread_list.GetSize(false)) + { + ThreadSP core_thread_sp(core_thread_list.GetThreadAtIndex(core_number, false)); + if (core_thread_sp) + { + // Keep track of which cores were set as the backing thread for memory threads... + if (core_number < core_used_map.size()) + core_used_map[core_number] = true; + + ThreadSP backing_core_thread_sp(core_thread_sp->GetBackingThread()); + if (backing_core_thread_sp) { - if (did_create_ptr) - *did_create_ptr = true; - thread_sp.reset (new ThreadMemory (*m_process, - tid, - name, - queue, - reg_data_addr)); - + thread_sp->SetBackingThread(backing_core_thread_sp); } - - if (core_number < core_thread_list.GetSize(false)) + else { - ThreadSP core_thread_sp (core_thread_list.GetThreadAtIndex(core_number, false)); - if (core_thread_sp) - { - // Keep track of which cores were set as the backing thread for memory threads... - if (core_number < core_used_map.size()) - core_used_map[core_number] = true; - - ThreadSP backing_core_thread_sp (core_thread_sp->GetBackingThread()); - if (backing_core_thread_sp) - { - thread_sp->SetBackingThread(backing_core_thread_sp); - } - else - { - thread_sp->SetBackingThread(core_thread_sp); - } - } + thread_sp->SetBackingThread(core_thread_sp); } } } @@ -364,11 +347,11 @@ thread->GetID(), thread->GetProtocolID()); - PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID())); + StructuredData::StringSP reg_context_data = m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, thread->GetID()); if (reg_context_data) { - DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(), - reg_context_data.GetSize())); + std::string value = reg_context_data->GetValue(); + DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length())); if (data_sp->GetByteSize()) { RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS); @@ -417,14 +400,14 @@ Mutex::Locker api_locker (target.GetAPIMutex()); auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive - PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context)); + StructuredData::DictionarySP thread_info_dict = m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context); std::vector core_used_map; if (thread_info_dict) { ThreadList core_threads(m_process); ThreadList &thread_list = m_process->GetThreadList(); bool did_create = false; - ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, core_used_map, &did_create)); + ThreadSP thread_sp(CreateThreadFromThreadInfo(*thread_info_dict, core_threads, thread_list, core_used_map, &did_create)); if (did_create) thread_list.AddThread(thread_sp); return thread_sp; Index: source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -19,21 +19,19 @@ // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/StructuredData.h" class DynamicRegisterInfo { public: DynamicRegisterInfo (); - DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, - lldb::ByteOrder byte_order); - + DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, lldb::ByteOrder byte_order); + virtual ~DynamicRegisterInfo (); - size_t - SetRegisterInfo (const lldb_private::PythonDictionary &dict, - lldb::ByteOrder byte_order); + size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, lldb::ByteOrder byte_order); void AddRegister (lldb_private::RegisterInfo ®_info, Index: source/Plugins/Process/Utility/DynamicRegisterInfo.cpp =================================================================== --- source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -18,12 +18,9 @@ #include "lldb/Host/StringConvert.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredData.h" #include "lldb/DataFormatters/FormatManager.h" -#ifndef LLDB_DISABLE_PYTHON -#include "lldb/Interpreter/PythonDataObjects.h" -#endif - using namespace lldb; using namespace lldb_private; @@ -39,15 +36,15 @@ { } -DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) : - m_regs (), - m_sets (), - m_set_reg_nums (), - m_set_names (), - m_value_regs_map (), - m_invalidate_regs_map (), - m_reg_data_byte_size (0), - m_finalized (false) +DynamicRegisterInfo::DynamicRegisterInfo(const StructuredData::Dictionary &dict, ByteOrder byte_order) + : m_regs() + , m_sets() + , m_set_reg_nums() + , m_set_names() + , m_value_regs_map() + , m_invalidate_regs_map() + , m_reg_data_byte_size(0) + , m_finalized(false) { SetRegisterInfo (dict, byte_order); } @@ -56,23 +53,20 @@ { } - size_t -DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict, - ByteOrder byte_order) +DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, ByteOrder byte_order) { assert(!m_finalized); -#ifndef LLDB_DISABLE_PYTHON - PythonList sets (dict.GetItemForKey("sets")); - if (sets) + StructuredData::Array *sets = nullptr; + if (dict.GetValueForKeyAsArray("sets", sets)) { - const uint32_t num_sets = sets.GetSize(); + const uint32_t num_sets = sets->GetSize(); for (uint32_t i=0; iGetItemAtIndexAsString(i, set_name_str)) + set_name.SetCString(set_name_str.c_str()); if (set_name) { RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; @@ -87,346 +81,310 @@ } m_set_reg_nums.resize(m_sets.size()); } - PythonList regs (dict.GetItemForKey("registers")); - if (regs) - { - const uint32_t num_regs = regs.GetSize(); - PythonString name_pystr("name"); - PythonString altname_pystr("alt-name"); - PythonString bitsize_pystr("bitsize"); - PythonString offset_pystr("offset"); - PythonString encoding_pystr("encoding"); - PythonString format_pystr("format"); - PythonString set_pystr("set"); - PythonString gcc_pystr("gcc"); - PythonString dwarf_pystr("dwarf"); - PythonString generic_pystr("generic"); - PythonString slice_pystr("slice"); - PythonString composite_pystr("composite"); - PythonString invalidate_regs_pystr("invalidate-regs"); - + StructuredData::Array *regs = nullptr; + if (!dict.GetValueForKeyAsArray("registers", regs)) + return 0; + + const uint32_t num_regs = regs->GetSize(); // typedef std::map > InvalidateNameMap; // InvalidateNameMap invalidate_map; - for (uint32_t i=0; iGetItemAtIndexAsDictionary(i, reg_info_dict)) { - PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); - if (reg_info_dict) - { - // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, - RegisterInfo reg_info; - std::vector value_regs; - std::vector invalidate_regs; - memset(®_info, 0, sizeof(reg_info)); - - reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); - if (reg_info.name == NULL) - { - Clear(); - printf("error: registers must have valid names\n"); - reg_info_dict.Dump(); - return 0; - } - - reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString(); - - reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX); + Clear(); + printf("error: items in the 'registers' array must be dictionaries\n"); + regs->DumpToStdout(); + return 0; + } + + // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, + // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, + RegisterInfo reg_info; + std::vector value_regs; + std::vector invalidate_regs; + memset(®_info, 0, sizeof(reg_info)); + + ConstString name_val; + ConstString alt_name_val; + if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) + { + Clear(); + printf("error: registers must have valid names and offsets\n"); + reg_info_dict->DumpToStdout(); + return 0; + } + reg_info.name = name_val.GetCString(); + reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr); + reg_info.alt_name = alt_name_val.GetCString(); - if (reg_info.byte_offset == UINT32_MAX) + reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX); + + if (reg_info.byte_offset == UINT32_MAX) + { + // No offset for this register, see if the register has a value expression + // which indicates this register is part of another register. Value expressions + // are things like "rax[31:0]" which state that the current register's value + // is in a concrete register "rax" in bits 31:0. If there is a value expression + // we can calculate the offset + bool success = false; + std::string slice_str; + if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) + { + // Slices use the following format: + // REGNAME[MSBIT:LSBIT] + // REGNAME - name of the register to grab a slice of + // MSBIT - the most significant bit at which the current register value starts at + // LSBIT - the least significant bit at which the current register value ends at + static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); + RegularExpression::Match regex_match(3); + if (g_bitfield_regex.Execute(slice_str.c_str(), ®ex_match)) { - // No offset for this register, see if the register has a value expression - // which indicates this register is part of another register. Value expressions - // are things like "rax[31:0]" which state that the current register's value - // is in a concrete register "rax" in bits 31:0. If there is a value expression - // we can calculate the offset - bool success = false; - const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr); - if (slice_cstr) + llvm::StringRef reg_name_str; + std::string msbit_str; + std::string lsbit_str; + if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) && + regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) && + regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str)) { - // Slices use the following format: - // REGNAME[MSBIT:LSBIT] - // REGNAME - name of the register to grab a slice of - // MSBIT - the most significant bit at which the current register value starts at - // LSBIT - the least significant bit at which the current register value ends at - static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); - RegularExpression::Match regex_match(3); - if (g_bitfield_regex.Execute(slice_cstr, ®ex_match)) + const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); + const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); + if (msbit != UINT32_MAX && lsbit != UINT32_MAX) { - llvm::StringRef reg_name_str; - std::string msbit_str; - std::string lsbit_str; - if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) && - regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) && - regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str)) + if (msbit > lsbit) { - const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); - const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); - if (msbit != UINT32_MAX && lsbit != UINT32_MAX) + const uint32_t msbyte = msbit / 8; + const uint32_t lsbyte = lsbit / 8; + + ConstString containing_reg_name(reg_name_str); + + RegisterInfo *containing_reg_info = GetRegisterInfo(containing_reg_name); + if (containing_reg_info) { - if (msbit > lsbit) + const uint32_t max_bit = containing_reg_info->byte_size * 8; + if (msbit < max_bit && lsbit < max_bit) { - const uint32_t msbyte = msbit / 8; - const uint32_t lsbyte = lsbit / 8; + m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); - ConstString containing_reg_name(reg_name_str); - - RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name); - if (containing_reg_info) + if (byte_order == eByteOrderLittle) + { + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; + } + else if (byte_order == eByteOrderBig) { - const uint32_t max_bit = containing_reg_info->byte_size * 8; - if (msbit < max_bit && lsbit < max_bit) - { - m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); - m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); - - if (byte_order == eByteOrderLittle) - { - success = true; - reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; - } - else if (byte_order == eByteOrderBig) - { - success = true; - reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; - } - else - { - assert(!"Invalid byte order"); - } - } - else - { - if (msbit > max_bit) - printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit); - else - printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit); - } + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; } else { - printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); + assert(!"Invalid byte order"); } } else { - printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); + if (msbit > max_bit) + printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, + max_bit); + else + printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, + max_bit); } } else { - printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); + printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); } } else { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); - + printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); } } else { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to match against register bitfield regex\n"); + printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); } } else { - PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr)); - if (composite_reg_list) + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); + } + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to match against register bitfield regex\n"); + } + } + else + { + StructuredData::Array *composite_reg_list = nullptr; + if (reg_info_dict->GetValueForKeyAsArray("composite", composite_reg_list)) + { + const size_t num_composite_regs = composite_reg_list->GetSize(); + if (num_composite_regs > 0) + { + uint32_t composite_offset = UINT32_MAX; + for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; ++composite_idx) { - const size_t num_composite_regs = composite_reg_list.GetSize(); - if (num_composite_regs > 0) + ConstString composite_reg_name; + if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr)) { - uint32_t composite_offset = UINT32_MAX; - for (uint32_t composite_idx=0; composite_idx composite_reg_info->byte_offset) - composite_offset = composite_reg_info->byte_offset; - m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); - m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); - } - else - { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); - } - } - else - { - printf("error: 'composite' key contained an empty string\n"); - } - } - else - { - printf("error: 'composite' list value wasn't a python string\n"); - } - } - if (composite_offset != UINT32_MAX) + RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name); + if (composite_reg_info) { - reg_info.byte_offset = composite_offset; - success = m_value_regs_map.find(i) != m_value_regs_map.end(); + composite_offset = std::min(composite_offset, composite_reg_info->byte_offset); + m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); } else { - printf("error: 'composite' registers must specify at least one real register\n"); + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); } } else { - printf("error: 'composite' list was empty\n"); + printf("error: 'composite' list value wasn't a python string\n"); } } + if (composite_offset != UINT32_MAX) + { + reg_info.byte_offset = composite_offset; + success = m_value_regs_map.find(i) != m_value_regs_map.end(); + } + else + { + printf("error: 'composite' registers must specify at least one real register\n"); + } } - - - if (!success) + else { - Clear(); - reg_info_dict.Dump(); - return 0; + printf("error: 'composite' list was empty\n"); } } - const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); - if (bitsize == 0) - { - Clear(); - printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n"); - reg_info_dict.Dump(); - return 0; - } + } - reg_info.byte_size = bitsize / 8; - - const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); - if (format_cstr) - { - if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) - { - Clear(); - printf("error: invalid 'format' value in register dictionary\n"); - reg_info_dict.Dump(); - return 0; - } - } - else - { - reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex); - } - - const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); - if (encoding_cstr) - reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); - else - reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint); + if (!success) + { + Clear(); + reg_info_dict->DumpToStdout(); + return 0; + } + } - const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); - if (static_cast(set) >= m_sets.size()) - { - Clear(); - printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set); - reg_info_dict.Dump(); - return 0; - } + int64_t bitsize = 0; + if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) + { + Clear(); + printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n"); + reg_info_dict->DumpToStdout(); + return 0; + } - // Fill in the register numbers - reg_info.kinds[lldb::eRegisterKindLLDB] = i; - reg_info.kinds[lldb::eRegisterKindGDB] = i; - reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM); - reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM); - const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr); - if (generic_cstr) - reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); - else - reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); + reg_info.byte_size = bitsize / 8; + + std::string format_str; + if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) + { + if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL).Fail()) + { + Clear(); + printf("error: invalid 'format' value in register dictionary\n"); + reg_info_dict->DumpToStdout(); + return 0; + } + } + else + { + reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, eFormatHex); + } + + std::string encoding_str; + if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str)) + reg_info.encoding = Args::StringToEncoding(encoding_str.c_str(), eEncodingUint); + else + reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, eEncodingUint); - // Check if this register invalidates any other register values when it is modified - PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr)); - if (invalidate_reg_list) + size_t set = 0; + if (!reg_info_dict->GetValueForKeyAsInteger("set", set, -1) || set >= m_sets.size()) + { + Clear(); + printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set); + reg_info_dict->DumpToStdout(); + return 0; + } + + // Fill in the register numbers + reg_info.kinds[lldb::eRegisterKindLLDB] = i; + reg_info.kinds[lldb::eRegisterKindGDB] = i; + reg_info_dict->GetValueForKeyAsInteger("gcc", reg_info.kinds[lldb::eRegisterKindGCC], LLDB_INVALID_REGNUM); + reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM); + std::string generic_str; + if (reg_info_dict->GetValueForKeyAsString("generic", generic_str)) + reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str()); + else + reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM); + + // Check if this register invalidates any other register values when it is modified + StructuredData::Array *invalidate_reg_list = nullptr; + if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list)) + { + const size_t num_regs = invalidate_reg_list->GetSize(); + if (num_regs > 0) + { + for (uint32_t idx = 0; idx < num_regs; ++idx) { - const size_t num_regs = invalidate_reg_list.GetSize(); - if (num_regs > 0) + ConstString invalidate_reg_name; + uint64_t invalidate_reg_num; + if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name)) { - for (uint32_t idx=0; idxkinds[eRegisterKindLLDB]); - } - else - { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name); - } - } - else - { - printf("error: 'invalidate-regs' list value was an empty string\n"); - } - } - else - { - PythonInteger invalidate_reg_num(invalidate_reg_object); - - if (invalidate_reg_num) - { - const int64_t r = invalidate_reg_num.GetInteger(); - if (r != static_cast(UINT64_MAX)) - m_invalidate_regs_map[i].push_back(r); - else - printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); - } - else - { - printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); - } - } + m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", + invalidate_reg_name.GetCString(), reg_info.name); } } + else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num)) + { + if (invalidate_reg_num != UINT64_MAX) + m_invalidate_regs_map[i].push_back(invalidate_reg_num); + else + printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); + } else { - printf("error: 'invalidate-regs' contained an empty list\n"); + printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); } } - - // Calculate the register offset - const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; - - m_regs.push_back (reg_info); - m_set_reg_nums[set].push_back(i); - } else { - Clear(); - printf("error: items in the 'registers' array must be dictionaries\n"); - regs.Dump(); - return 0; + printf("error: 'invalidate-regs' contained an empty list\n"); } } - Finalize (); + + // Calculate the register offset + const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; + if (m_reg_data_byte_size < end_reg_offset) + m_reg_data_byte_size = end_reg_offset; + + m_regs.push_back(reg_info); + m_set_reg_nums[set].push_back(i); } -#endif + Finalize(); return m_regs.size(); } Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.h =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -303,9 +303,6 @@ bool ParsePythonTargetDefinition(const lldb_private::FileSpec &target_definition_fspec); - - bool - ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array); const lldb::DataBufferSP GetAuxvData() override; Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -52,9 +52,6 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" -#ifndef LLDB_DISABLE_PYTHON -#include "lldb/Interpreter/PythonDataObjects.h" -#endif #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" @@ -337,41 +334,47 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec) { -#ifndef LLDB_DISABLE_PYTHON ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); Error error; - lldb::ScriptInterpreterObjectSP module_object_sp (interpreter->LoadPluginModule(target_definition_fspec, error)); + StructuredData::ObjectSP module_object_sp(interpreter->LoadPluginModule(target_definition_fspec, error)); if (module_object_sp) { - lldb::ScriptInterpreterObjectSP target_definition_sp (interpreter->GetDynamicSettings(module_object_sp, - &GetTarget(), - "gdb-server-target-definition", - error)); - - PythonDictionary target_dict(target_definition_sp); + StructuredData::DictionarySP target_definition_sp( + interpreter->GetDynamicSettings(module_object_sp, &GetTarget(), "gdb-server-target-definition", error)); - if (target_dict) + if (target_definition_sp) { - PythonDictionary host_info_dict (target_dict.GetItemForKey("host-info")); - if (host_info_dict) + StructuredData::ObjectSP target_object(target_definition_sp->GetValueForKey("host-info")); + if (target_object) { - ArchSpec host_arch (host_info_dict.GetItemForKeyAsString(PythonString("triple"))); - - if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) + if (auto host_info_dict = target_object->GetAsDictionary()) { - GetTarget().SetArchitecture(host_arch); + StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple"); + if (auto triple_string_value = triple_value->GetAsString()) + { + std::string triple_string = triple_string_value->GetValue(); + ArchSpec host_arch(triple_string.c_str()); + if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) + { + GetTarget().SetArchitecture(host_arch); + } + } } - } - m_breakpoint_pc_offset = target_dict.GetItemForKeyAsInteger("breakpoint-pc-offset", 0); + m_breakpoint_pc_offset = 0; + StructuredData::ObjectSP breakpoint_pc_offset_value = target_definition_sp->GetValueForKey("breakpoint-pc-offset"); + if (breakpoint_pc_offset_value) + { + if (auto breakpoint_pc_int_value = breakpoint_pc_offset_value->GetAsInteger()) + m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue(); + } - if (m_register_info.SetRegisterInfo (target_dict, GetTarget().GetArchitecture().GetByteOrder()) > 0) + if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture().GetByteOrder()) > 0) { return true; } } } -#endif return false; } Index: source/Target/ThreadPlanPython.cpp =================================================================== --- source/Target/ThreadPlanPython.cpp +++ source/Target/ThreadPlanPython.cpp @@ -20,7 +20,6 @@ #include "lldb/Core/State.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h"