diff options
Diffstat (limited to 'source/Plugins/OperatingSystem/Python')
| -rw-r--r-- | source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp | 678 | ||||
| -rw-r--r-- | source/Plugins/OperatingSystem/Python/OperatingSystemPython.h | 139 | 
2 files changed, 400 insertions, 417 deletions
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index dfb631e399f16..69826a0f638c6 100644 --- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -1,4 +1,4 @@ -//===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===// +//===-- OperatingSystemPython.cpp --------------------------------*- C++-*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -13,6 +13,10 @@  // C Includes  // C++ Includes  // Other libraries and framework includes +#include "Plugins/Process/Utility/DynamicRegisterInfo.h" +#include "Plugins/Process/Utility/RegisterContextDummy.h" +#include "Plugins/Process/Utility/RegisterContextMemory.h" +#include "Plugins/Process/Utility/ThreadMemory.h"  #include "lldb/Core/ArchSpec.h"  #include "lldb/Core/DataBufferHeap.h"  #include "lldb/Core/Debugger.h" @@ -29,395 +33,385 @@  #include "lldb/Target/Process.h"  #include "lldb/Target/StopInfo.h"  #include "lldb/Target/Target.h" -#include "lldb/Target/ThreadList.h"  #include "lldb/Target/Thread.h" -#include "Plugins/Process/Utility/DynamicRegisterInfo.h" -#include "Plugins/Process/Utility/RegisterContextDummy.h" -#include "Plugins/Process/Utility/RegisterContextMemory.h" -#include "Plugins/Process/Utility/ThreadMemory.h" +#include "lldb/Target/ThreadList.h"  using namespace lldb;  using namespace lldb_private; -void -OperatingSystemPython::Initialize() -{ -    PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, nullptr); +void OperatingSystemPython::Initialize() { +  PluginManager::RegisterPlugin(GetPluginNameStatic(), +                                GetPluginDescriptionStatic(), CreateInstance, +                                nullptr);  } -void -OperatingSystemPython::Terminate() -{ -    PluginManager::UnregisterPlugin (CreateInstance); +void OperatingSystemPython::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } -OperatingSystem * -OperatingSystemPython::CreateInstance (Process *process, bool force) -{ -    // Python OperatingSystem plug-ins must be requested by name, so force must be true -    FileSpec python_os_plugin_spec (process->GetPythonOSPluginPath()); -    if (python_os_plugin_spec && python_os_plugin_spec.Exists()) -    { -        std::unique_ptr<OperatingSystemPython> os_ap (new OperatingSystemPython (process, python_os_plugin_spec)); -        if (os_ap.get() && os_ap->IsValid()) -            return os_ap.release(); -    } -    return NULL; +OperatingSystem *OperatingSystemPython::CreateInstance(Process *process, +                                                       bool force) { +  // Python OperatingSystem plug-ins must be requested by name, so force must be +  // true +  FileSpec python_os_plugin_spec(process->GetPythonOSPluginPath()); +  if (python_os_plugin_spec && python_os_plugin_spec.Exists()) { +    std::unique_ptr<OperatingSystemPython> os_ap( +        new OperatingSystemPython(process, python_os_plugin_spec)); +    if (os_ap.get() && os_ap->IsValid()) +      return os_ap.release(); +  } +  return NULL;  } - -ConstString -OperatingSystemPython::GetPluginNameStatic() -{ -    static ConstString g_name("python"); -    return g_name; +ConstString OperatingSystemPython::GetPluginNameStatic() { +  static ConstString g_name("python"); +  return g_name;  } -const char * -OperatingSystemPython::GetPluginDescriptionStatic() -{ -    return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality."; +const char *OperatingSystemPython::GetPluginDescriptionStatic() { +  return "Operating system plug-in that gathers OS information from a python " +         "class that implements the necessary OperatingSystem functionality.";  } - -OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, const FileSpec &python_module_path) : -    OperatingSystem (process), -    m_thread_list_valobj_sp (), -    m_register_info_ap (), -    m_interpreter (NULL), -    m_python_object_sp () -{ -    if (!process) -        return; -    TargetSP target_sp = process->CalculateTarget(); -    if (!target_sp) -        return; -    m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); -    if (m_interpreter) -    { -         -        std::string os_plugin_class_name (python_module_path.GetFilename().AsCString("")); -        if (!os_plugin_class_name.empty()) -        { -            const bool init_session = false; -            const bool allow_reload = true; -            char python_module_path_cstr[PATH_MAX]; -            python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr)); -            Error error; -            if (m_interpreter->LoadScriptingModule (python_module_path_cstr, allow_reload, init_session, error)) -            { -                // Strip the ".py" extension if there is one -                size_t py_extension_pos = os_plugin_class_name.rfind(".py"); -                if (py_extension_pos != std::string::npos) -                    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"; -                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; -            } -        } +OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process, +                                             const FileSpec &python_module_path) +    : OperatingSystem(process), m_thread_list_valobj_sp(), m_register_info_ap(), +      m_interpreter(NULL), m_python_object_sp() { +  if (!process) +    return; +  TargetSP target_sp = process->CalculateTarget(); +  if (!target_sp) +    return; +  m_interpreter = +      target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); +  if (m_interpreter) { + +    std::string os_plugin_class_name( +        python_module_path.GetFilename().AsCString("")); +    if (!os_plugin_class_name.empty()) { +      const bool init_session = false; +      const bool allow_reload = true; +      char python_module_path_cstr[PATH_MAX]; +      python_module_path.GetPath(python_module_path_cstr, +                                 sizeof(python_module_path_cstr)); +      Error error; +      if (m_interpreter->LoadScriptingModule( +              python_module_path_cstr, allow_reload, init_session, error)) { +        // Strip the ".py" extension if there is one +        size_t py_extension_pos = os_plugin_class_name.rfind(".py"); +        if (py_extension_pos != std::string::npos) +          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"; +        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; +      }      } +  }  } -OperatingSystemPython::~OperatingSystemPython () -{ -} +OperatingSystemPython::~OperatingSystemPython() {} -DynamicRegisterInfo * -OperatingSystemPython::GetDynamicRegisterInfo () -{ -    if (m_register_info_ap.get() == NULL) -    { -        if (!m_interpreter || !m_python_object_sp) -            return NULL; -        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS)); -         -        if (log) -            log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID()); - -        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())); -        assert (m_register_info_ap->GetNumRegisters() > 0); -        assert (m_register_info_ap->GetNumRegisterSets() > 0); -    } -    return m_register_info_ap.get(); +DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() { +  if (m_register_info_ap.get() == NULL) { +    if (!m_interpreter || !m_python_object_sp) +      return NULL; +    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); + +    if (log) +      log->Printf("OperatingSystemPython::GetDynamicRegisterInfo() fetching " +                  "thread register definitions from python for pid %" PRIu64, +                  m_process->GetID()); + +    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())); +    assert(m_register_info_ap->GetNumRegisters() > 0); +    assert(m_register_info_ap->GetNumRegisterSets() > 0); +  } +  return m_register_info_ap.get();  }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -ConstString -OperatingSystemPython::GetPluginName() -{ -    return GetPluginNameStatic(); +ConstString OperatingSystemPython::GetPluginName() { +  return GetPluginNameStatic();  } -uint32_t -OperatingSystemPython::GetPluginVersion() -{ -    return 1; -} - -bool -OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, -                                         ThreadList &core_thread_list, -                                         ThreadList &new_thread_list) -{ -    if (!m_interpreter || !m_python_object_sp) -        return false; -     -    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS)); -     -    // First thing we have to do is to try to get the API lock, and the run lock. -    // We're going to change the thread content of the process, and we're going -    // to use python, which requires the API lock to do it. -    // -    // If someone already has the API lock, that is ok, we just want to avoid -    // external code from making new API calls while this call is happening. -    // -    // This is a recursive lock so we can grant it to any Python code called on -    // the stack below us. -    Target &target = m_process->GetTarget(); -    std::unique_lock<std::recursive_mutex> lock(target.GetAPIMutex(), std::defer_lock); -    lock.try_lock(); - -    if (log) -        log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID()); - -    // The threads that are in "new_thread_list" upon entry are the threads from the -    // lldb_private::Process subclass, no memory threads will be in this list. - -    auto interpreter_lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive -    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 -    // core_thread list. Any real threads/cores that weren't used should -    // later be put back into the "new_thread_list". -    std::vector<bool> core_used_map(num_cores, false); -    if (threads_list) -    { -        if (log) -        { -            StreamString strm; -            threads_list->Dump(strm); -            log->Printf("threads_list = %s", strm.GetString().c_str()); -        } - -        const uint32_t num_threads = threads_list->GetSize(); -        for (uint32_t i = 0; i < num_threads; ++i) -        { -            StructuredData::ObjectSP thread_dict_obj = threads_list->GetItemAtIndex(i); -            if (auto thread_dict = thread_dict_obj->GetAsDictionary()) -            { -                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); -            } -        } +uint32_t OperatingSystemPython::GetPluginVersion() { return 1; } + +bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list, +                                             ThreadList &core_thread_list, +                                             ThreadList &new_thread_list) { +  if (!m_interpreter || !m_python_object_sp) +    return false; + +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); + +  // First thing we have to do is to try to get the API lock, and the run lock. +  // We're going to change the thread content of the process, and we're going +  // to use python, which requires the API lock to do it. +  // +  // If someone already has the API lock, that is ok, we just want to avoid +  // external code from making new API calls while this call is happening. +  // +  // This is a recursive lock so we can grant it to any Python code called on +  // the stack below us. +  Target &target = m_process->GetTarget(); +  std::unique_lock<std::recursive_mutex> lock(target.GetAPIMutex(), +                                              std::defer_lock); +  lock.try_lock(); + +  if (log) +    log->Printf("OperatingSystemPython::UpdateThreadList() fetching thread " +                "data from python for pid %" PRIu64, +                m_process->GetID()); + +  // The threads that are in "new_thread_list" upon entry are the threads from +  // the +  // lldb_private::Process subclass, no memory threads will be in this list. + +  auto interpreter_lock = +      m_interpreter +          ->AcquireInterpreterLock(); // to make sure threads_list stays alive +  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 +  // core_thread list. Any real threads/cores that weren't used should +  // later be put back into the "new_thread_list". +  std::vector<bool> core_used_map(num_cores, false); +  if (threads_list) { +    if (log) { +      StreamString strm; +      threads_list->Dump(strm); +      log->Printf("threads_list = %s", strm.GetData());      } -    // Any real core threads that didn't end up backing a memory thread should -    // still be in the main thread list, and they should be inserted at the beginning -    // of the list -    uint32_t insert_idx = 0; -    for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) -    { -        if (core_used_map[core_idx] == false) -        { -            new_thread_list.InsertThread (core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx); -            ++insert_idx; -        } +    const uint32_t num_threads = threads_list->GetSize(); +    for (uint32_t i = 0; i < num_threads; ++i) { +      StructuredData::ObjectSP thread_dict_obj = +          threads_list->GetItemAtIndex(i); +      if (auto thread_dict = thread_dict_obj->GetAsDictionary()) { +        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); +      }      } +  } + +  // Any real core threads that didn't end up backing a memory thread should +  // still be in the main thread list, and they should be inserted at the +  // beginning +  // of the list +  uint32_t insert_idx = 0; +  for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) { +    if (core_used_map[core_idx] == false) { +      new_thread_list.InsertThread( +          core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx); +      ++insert_idx; +    } +  } -    return new_thread_list.GetSize(false) > 0; +  return new_thread_list.GetSize(false) > 0;  } -ThreadSP -OperatingSystemPython::CreateThreadFromThreadInfo(StructuredData::Dictionary &thread_dict, ThreadList &core_thread_list, -                                                  ThreadList &old_thread_list, std::vector<bool> &core_used_map, bool *did_create_ptr) -{ -    ThreadSP thread_sp; -    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) -    { -        // 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(); -        } -    } +ThreadSP OperatingSystemPython::CreateThreadFromThreadInfo( +    StructuredData::Dictionary &thread_dict, ThreadList &core_thread_list, +    ThreadList &old_thread_list, std::vector<bool> &core_used_map, +    bool *did_create_ptr) { +  ThreadSP thread_sp; +  tid_t tid = LLDB_INVALID_THREAD_ID; +  if (!thread_dict.GetValueForKeyAsInteger("tid", tid)) +    return ThreadSP(); -    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)); +  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) { +    // 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 (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) -            { -                thread_sp->SetBackingThread(backing_core_thread_sp); -            } -            else -            { -                thread_sp->SetBackingThread(core_thread_sp); -            } -        } +  } + +  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) { +        thread_sp->SetBackingThread(backing_core_thread_sp); +      } else { +        thread_sp->SetBackingThread(core_thread_sp); +      }      } -    return thread_sp; +  } +  return thread_sp;  } - - -void -OperatingSystemPython::ThreadWasSelected (Thread *thread) -{ -} +void OperatingSystemPython::ThreadWasSelected(Thread *thread) {}  RegisterContextSP -OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr) -{ -    RegisterContextSP reg_ctx_sp; -    if (!m_interpreter || !m_python_object_sp || !thread) -        return reg_ctx_sp; - -    if (!IsOperatingSystemPluginThread(thread->shared_from_this())) -        return reg_ctx_sp; -     -    // First thing we have to do is get the API lock, and the run lock.  We're going to change the thread -    // content of the process, and we're going to use python, which requires the API lock to do it. -    // So get & hold that.  This is a recursive lock so we can grant it to any Python code called on the stack below us. -    Target &target = m_process->GetTarget(); -    std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); +OperatingSystemPython::CreateRegisterContextForThread(Thread *thread, +                                                      addr_t reg_data_addr) { +  RegisterContextSP reg_ctx_sp; +  if (!m_interpreter || !m_python_object_sp || !thread) +    return reg_ctx_sp; -    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - -    auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure python objects stays alive -    if (reg_data_addr != LLDB_INVALID_ADDRESS) -    { -        // The registers data is in contiguous memory, just create the register -        // context using the address provided -        if (log) -            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", -                         thread->GetID(), -                         thread->GetProtocolID(), -                         reg_data_addr); -        reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr)); -    } -    else -    { -        // No register data address is provided, query the python plug-in to let -        // it make up the data as it sees fit -        if (log) -            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ") fetching register data from python", -                         thread->GetID(), -                         thread->GetProtocolID()); - -        StructuredData::StringSP reg_context_data = m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, thread->GetID()); -        if (reg_context_data) -        { -            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); -                if (reg_ctx_memory) -                { -                    reg_ctx_sp.reset(reg_ctx_memory); -                    reg_ctx_memory->SetAllRegisterData (data_sp); -                } -            } +  if (!IsOperatingSystemPluginThread(thread->shared_from_this())) +    return reg_ctx_sp; + +  // First thing we have to do is get the API lock, and the run lock.  We're +  // going to change the thread +  // content of the process, and we're going to use python, which requires the +  // API lock to do it. +  // So get & hold that.  This is a recursive lock so we can grant it to any +  // Python code called on the stack below us. +  Target &target = m_process->GetTarget(); +  std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); + +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + +  auto lock = +      m_interpreter +          ->AcquireInterpreterLock(); // to make sure python objects stays alive +  if (reg_data_addr != LLDB_INVALID_ADDRESS) { +    // The registers data is in contiguous memory, just create the register +    // context using the address provided +    if (log) +      log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid " +                  "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 +                  ") creating memory register context", +                  thread->GetID(), thread->GetProtocolID(), reg_data_addr); +    reg_ctx_sp.reset(new RegisterContextMemory( +        *thread, 0, *GetDynamicRegisterInfo(), reg_data_addr)); +  } else { +    // No register data address is provided, query the python plug-in to let +    // it make up the data as it sees fit +    if (log) +      log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid " +                  "= 0x%" PRIx64 ", 0x%" PRIx64 +                  ") fetching register data from python", +                  thread->GetID(), thread->GetProtocolID()); + +    StructuredData::StringSP reg_context_data = +        m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, +                                                    thread->GetID()); +    if (reg_context_data) { +      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); +        if (reg_ctx_memory) { +          reg_ctx_sp.reset(reg_ctx_memory); +          reg_ctx_memory->SetAllRegisterData(data_sp);          } +      }      } -    // if we still have no register data, fallback on a dummy context to avoid crashing -    if (!reg_ctx_sp) -    { -        if (log) -            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") forcing a dummy register context", thread->GetID()); -        reg_ctx_sp.reset(new RegisterContextDummy(*thread,0,target.GetArchitecture().GetAddressByteSize())); -    } -    return reg_ctx_sp; +  } +  // if we still have no register data, fallback on a dummy context to avoid +  // crashing +  if (!reg_ctx_sp) { +    if (log) +      log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid " +                  "= 0x%" PRIx64 ") forcing a dummy register context", +                  thread->GetID()); +    reg_ctx_sp.reset(new RegisterContextDummy( +        *thread, 0, target.GetArchitecture().GetAddressByteSize())); +  } +  return reg_ctx_sp;  }  StopInfoSP -OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread) -{ -    // We should have gotten the thread stop info from the dictionary of data for -    // the thread in the initial call to get_thread_info(), this should have been -    // cached so we can return it here -    StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP)); -    return stop_info_sp; +OperatingSystemPython::CreateThreadStopReason(lldb_private::Thread *thread) { +  // We should have gotten the thread stop info from the dictionary of data for +  // the thread in the initial call to get_thread_info(), this should have been +  // cached so we can return it here +  StopInfoSP +      stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP)); +  return stop_info_sp;  } -lldb::ThreadSP -OperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context) -{ -    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); -     -    if (log) -        log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context); -     -    if (m_interpreter && m_python_object_sp) -    { -        // First thing we have to do is get the API lock, and the run lock.  We're going to change the thread -        // content of the process, and we're going to use python, which requires the API lock to do it. -        // So get & hold that.  This is a recursive lock so we can grant it to any Python code called on the stack below us. -        Target &target = m_process->GetTarget(); -        std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); - -        auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive -        StructuredData::DictionarySP thread_info_dict = m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context); -        std::vector<bool> 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)); -            if (did_create) -                thread_list.AddThread(thread_sp); -            return thread_sp; -        } +lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid, +                                                   addr_t context) { +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + +  if (log) +    log->Printf("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 +                ", context = 0x%" PRIx64 ") fetching register data from python", +                tid, context); + +  if (m_interpreter && m_python_object_sp) { +    // First thing we have to do is get the API lock, and the run lock.  We're +    // going to change the thread +    // content of the process, and we're going to use python, which requires the +    // API lock to do it. +    // So get & hold that.  This is a recursive lock so we can grant it to any +    // Python code called on the stack below us. +    Target &target = m_process->GetTarget(); +    std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); + +    auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure +                                                         // thread_info_dict +                                                         // stays alive +    StructuredData::DictionarySP thread_info_dict = +        m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context); +    std::vector<bool> 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)); +      if (did_create) +        thread_list.AddThread(thread_sp); +      return thread_sp;      } -    return ThreadSP(); +  } +  return ThreadSP();  } - -  #endif // #ifndef LLDB_DISABLE_PYTHON diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h index 1b33c42cf0fef..1eec30ef38c7c 100644 --- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -21,87 +21,76 @@  class DynamicRegisterInfo; -namespace lldb_private -{ +namespace lldb_private {  class ScriptInterpreter;  } -class OperatingSystemPython : public lldb_private::OperatingSystem -{ +class OperatingSystemPython : public lldb_private::OperatingSystem {  public: -    OperatingSystemPython(lldb_private::Process *process, -                          const lldb_private::FileSpec &python_module_path); - -    ~OperatingSystemPython() override; - -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static lldb_private::OperatingSystem * -    CreateInstance (lldb_private::Process *process, bool force); -     -    static void -    Initialize(); -     -    static void -    Terminate(); -     -    static lldb_private::ConstString -    GetPluginNameStatic(); -     -    static const char * -    GetPluginDescriptionStatic(); -     -    //------------------------------------------------------------------ -    // lldb_private::PluginInterface Methods -    //------------------------------------------------------------------ -    lldb_private::ConstString -    GetPluginName() override; -     -    uint32_t -    GetPluginVersion() override; -     -    //------------------------------------------------------------------ -    // lldb_private::OperatingSystem Methods -    //------------------------------------------------------------------ -    bool -    UpdateThreadList(lldb_private::ThreadList &old_thread_list, -                     lldb_private::ThreadList &real_thread_list, -                     lldb_private::ThreadList &new_thread_list) override; -     -    void -    ThreadWasSelected(lldb_private::Thread *thread) override; - -    lldb::RegisterContextSP -    CreateRegisterContextForThread(lldb_private::Thread *thread, -                                   lldb::addr_t reg_data_addr) override; - -    lldb::StopInfoSP -    CreateThreadStopReason(lldb_private::Thread *thread) override; - -    //------------------------------------------------------------------ -    // Method for lazy creation of threads on demand -    //------------------------------------------------------------------ -    lldb::ThreadSP -    CreateThread(lldb::tid_t tid, lldb::addr_t context) override; +  OperatingSystemPython(lldb_private::Process *process, +                        const lldb_private::FileSpec &python_module_path); + +  ~OperatingSystemPython() override; + +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static lldb_private::OperatingSystem * +  CreateInstance(lldb_private::Process *process, bool force); + +  static void Initialize(); + +  static void Terminate(); + +  static lldb_private::ConstString GetPluginNameStatic(); + +  static const char *GetPluginDescriptionStatic(); + +  //------------------------------------------------------------------ +  // lldb_private::PluginInterface Methods +  //------------------------------------------------------------------ +  lldb_private::ConstString GetPluginName() override; + +  uint32_t GetPluginVersion() override; + +  //------------------------------------------------------------------ +  // lldb_private::OperatingSystem Methods +  //------------------------------------------------------------------ +  bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, +                        lldb_private::ThreadList &real_thread_list, +                        lldb_private::ThreadList &new_thread_list) override; + +  void ThreadWasSelected(lldb_private::Thread *thread) override; + +  lldb::RegisterContextSP +  CreateRegisterContextForThread(lldb_private::Thread *thread, +                                 lldb::addr_t reg_data_addr) override; + +  lldb::StopInfoSP +  CreateThreadStopReason(lldb_private::Thread *thread) override; + +  //------------------------------------------------------------------ +  // Method for lazy creation of threads on demand +  //------------------------------------------------------------------ +  lldb::ThreadSP CreateThread(lldb::tid_t tid, lldb::addr_t context) override;  protected: -    bool IsValid() const -    { -        return m_python_object_sp && m_python_object_sp->IsValid(); -    } - -    lldb::ThreadSP CreateThreadFromThreadInfo(lldb_private::StructuredData::Dictionary &thread_dict, -                                              lldb_private::ThreadList &core_thread_list, lldb_private::ThreadList &old_thread_list, -                                              std::vector<bool> &core_used_map, bool *did_create_ptr); - -    DynamicRegisterInfo * -    GetDynamicRegisterInfo (); - -    lldb::ValueObjectSP m_thread_list_valobj_sp; -    std::unique_ptr<DynamicRegisterInfo> m_register_info_ap; -    lldb_private::ScriptInterpreter *m_interpreter; -    lldb_private::StructuredData::ObjectSP m_python_object_sp; +  bool IsValid() const { +    return m_python_object_sp && m_python_object_sp->IsValid(); +  } + +  lldb::ThreadSP CreateThreadFromThreadInfo( +      lldb_private::StructuredData::Dictionary &thread_dict, +      lldb_private::ThreadList &core_thread_list, +      lldb_private::ThreadList &old_thread_list, +      std::vector<bool> &core_used_map, bool *did_create_ptr); + +  DynamicRegisterInfo *GetDynamicRegisterInfo(); + +  lldb::ValueObjectSP m_thread_list_valobj_sp; +  std::unique_ptr<DynamicRegisterInfo> m_register_info_ap; +  lldb_private::ScriptInterpreter *m_interpreter; +  lldb_private::StructuredData::ObjectSP m_python_object_sp;  };  #endif // LLDB_DISABLE_PYTHON  | 
