diff options
Diffstat (limited to 'source/Plugins/OperatingSystem/Go')
| -rw-r--r-- | source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp | 825 | ||||
| -rw-r--r-- | source/Plugins/OperatingSystem/Go/OperatingSystemGo.h | 83 | 
2 files changed, 420 insertions, 488 deletions
| diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp index ec0b7014d4d4..c5a3ddee4843 100644 --- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp +++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp @@ -15,6 +15,9 @@  // Project includes  #include "OperatingSystemGo.h" +#include "Plugins/Process/Utility/DynamicRegisterInfo.h" +#include "Plugins/Process/Utility/RegisterContextMemory.h" +#include "Plugins/Process/Utility/ThreadMemory.h"  #include "lldb/Core/DataBufferHeap.h"  #include "lldb/Core/Debugger.h"  #include "lldb/Core/Module.h" @@ -24,10 +27,10 @@  #include "lldb/Core/StreamString.h"  #include "lldb/Core/ValueObjectVariable.h"  #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/OptionValueProperties.h" -#include "lldb/Interpreter/Options.h"  #include "lldb/Interpreter/OptionGroupBoolean.h"  #include "lldb/Interpreter/OptionGroupUInt64.h" +#include "lldb/Interpreter/OptionValueProperties.h" +#include "lldb/Interpreter/Options.h"  #include "lldb/Interpreter/Property.h"  #include "lldb/Symbol/ObjectFile.h"  #include "lldb/Symbol/Type.h" @@ -35,536 +38,462 @@  #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/RegisterContextMemory.h" -#include "Plugins/Process/Utility/ThreadMemory.h" +#include "lldb/Target/ThreadList.h"  using namespace lldb;  using namespace lldb_private; -namespace -{ +namespace { -static PropertyDefinition g_properties[] = {{"enable", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, -                                             "Specify whether goroutines should be treated as threads."}, -                                            {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; +static PropertyDefinition g_properties[] = { +    {"enable", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, +     "Specify whether goroutines should be treated as threads."}, +    {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; -enum -{ -    ePropertyEnableGoroutines, +enum { +  ePropertyEnableGoroutines,  }; -class PluginProperties : public Properties -{ +class PluginProperties : public Properties {  public: -    PluginProperties() -        : Properties() -    { -        m_collection_sp.reset(new OptionValueProperties(GetSettingName())); -        m_collection_sp->Initialize(g_properties); -    } - -    ~PluginProperties() override = default; - -    static ConstString -    GetSettingName() -    { -        return OperatingSystemGo::GetPluginNameStatic(); -    } - -    bool -    GetEnableGoroutines() -    { -        const uint32_t idx = ePropertyEnableGoroutines; -        return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value); -    } - -    bool -    SetEnableGoroutines(bool enable) -    { -        const uint32_t idx = ePropertyEnableGoroutines; -        return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, enable); -    } +  PluginProperties() : Properties() { +    m_collection_sp.reset(new OptionValueProperties(GetSettingName())); +    m_collection_sp->Initialize(g_properties); +  } + +  ~PluginProperties() override = default; + +  static ConstString GetSettingName() { +    return OperatingSystemGo::GetPluginNameStatic(); +  } + +  bool GetEnableGoroutines() { +    const uint32_t idx = ePropertyEnableGoroutines; +    return m_collection_sp->GetPropertyAtIndexAsBoolean( +        NULL, idx, g_properties[idx].default_uint_value); +  } + +  bool SetEnableGoroutines(bool enable) { +    const uint32_t idx = ePropertyEnableGoroutines; +    return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, enable); +  }  };  typedef std::shared_ptr<PluginProperties> OperatingSystemGoPropertiesSP; -static const OperatingSystemGoPropertiesSP & -GetGlobalPluginProperties() -{ -    static OperatingSystemGoPropertiesSP g_settings_sp; -    if (!g_settings_sp) -        g_settings_sp.reset(new PluginProperties()); -    return g_settings_sp; +static const OperatingSystemGoPropertiesSP &GetGlobalPluginProperties() { +  static OperatingSystemGoPropertiesSP g_settings_sp; +  if (!g_settings_sp) +    g_settings_sp.reset(new PluginProperties()); +  return g_settings_sp;  } -class RegisterContextGo : public RegisterContextMemory -{ +class RegisterContextGo : public RegisterContextMemory {  public: -    RegisterContextGo(lldb_private::Thread &thread, uint32_t concrete_frame_idx, DynamicRegisterInfo ®_info, -                      lldb::addr_t reg_data_addr) -        : RegisterContextMemory(thread, concrete_frame_idx, reg_info, reg_data_addr) -    { -        const RegisterInfo *sp = reg_info.GetRegisterInfoAtIndex( -            reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP)); -        const RegisterInfo *pc = reg_info.GetRegisterInfoAtIndex( -            reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC)); -        size_t byte_size = std::max(sp->byte_offset + sp->byte_size, pc->byte_offset + pc->byte_size); - -        DataBufferSP reg_data_sp(new DataBufferHeap(byte_size, 0)); -        m_reg_data.SetData(reg_data_sp); +  RegisterContextGo(lldb_private::Thread &thread, uint32_t concrete_frame_idx, +                    DynamicRegisterInfo ®_info, lldb::addr_t reg_data_addr) +      : RegisterContextMemory(thread, concrete_frame_idx, reg_info, +                              reg_data_addr) { +    const RegisterInfo *sp = reg_info.GetRegisterInfoAtIndex( +        reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, +                                                     LLDB_REGNUM_GENERIC_SP)); +    const RegisterInfo *pc = reg_info.GetRegisterInfoAtIndex( +        reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, +                                                     LLDB_REGNUM_GENERIC_PC)); +    size_t byte_size = std::max(sp->byte_offset + sp->byte_size, +                                pc->byte_offset + pc->byte_size); + +    DataBufferSP reg_data_sp(new DataBufferHeap(byte_size, 0)); +    m_reg_data.SetData(reg_data_sp); +  } + +  ~RegisterContextGo() override = default; + +  bool ReadRegister(const lldb_private::RegisterInfo *reg_info, +                    lldb_private::RegisterValue ®_value) override { +    switch (reg_info->kinds[eRegisterKindGeneric]) { +    case LLDB_REGNUM_GENERIC_SP: +    case LLDB_REGNUM_GENERIC_PC: +      return RegisterContextMemory::ReadRegister(reg_info, reg_value); +    default: +      reg_value.SetValueToInvalid(); +      return true;      } - -    ~RegisterContextGo() override = default; - -    bool -    ReadRegister(const lldb_private::RegisterInfo *reg_info, -                 lldb_private::RegisterValue ®_value) override -    { -        switch (reg_info->kinds[eRegisterKindGeneric]) -        { -            case LLDB_REGNUM_GENERIC_SP: -            case LLDB_REGNUM_GENERIC_PC: -                return RegisterContextMemory::ReadRegister(reg_info, reg_value); -            default: -                reg_value.SetValueToInvalid(); -                return true; -        } -    } - -    bool -    WriteRegister(const lldb_private::RegisterInfo *reg_info, -                  const lldb_private::RegisterValue ®_value) override -    { -        switch (reg_info->kinds[eRegisterKindGeneric]) -        { -            case LLDB_REGNUM_GENERIC_SP: -            case LLDB_REGNUM_GENERIC_PC: -                return RegisterContextMemory::WriteRegister(reg_info, reg_value); -            default: -                return false; -        } +  } + +  bool WriteRegister(const lldb_private::RegisterInfo *reg_info, +                     const lldb_private::RegisterValue ®_value) override { +    switch (reg_info->kinds[eRegisterKindGeneric]) { +    case LLDB_REGNUM_GENERIC_SP: +    case LLDB_REGNUM_GENERIC_PC: +      return RegisterContextMemory::WriteRegister(reg_info, reg_value); +    default: +      return false;      } +  }  private: -    DISALLOW_COPY_AND_ASSIGN(RegisterContextGo); +  DISALLOW_COPY_AND_ASSIGN(RegisterContextGo);  };  } // anonymous namespace -struct OperatingSystemGo::Goroutine -{ -    uint64_t m_lostack; -    uint64_t m_histack; -    uint64_t m_goid; -    addr_t m_gobuf; -    uint32_t m_status; +struct OperatingSystemGo::Goroutine { +  uint64_t m_lostack; +  uint64_t m_histack; +  uint64_t m_goid; +  addr_t m_gobuf; +  uint32_t m_status;  }; -void -OperatingSystemGo::Initialize() -{ -    PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, -                                  DebuggerInitialize); +void OperatingSystemGo::Initialize() { +  PluginManager::RegisterPlugin(GetPluginNameStatic(), +                                GetPluginDescriptionStatic(), CreateInstance, +                                DebuggerInitialize);  } -void -OperatingSystemGo::DebuggerInitialize(Debugger &debugger) -{ -    if (!PluginManager::GetSettingForOperatingSystemPlugin(debugger, PluginProperties::GetSettingName())) -    { -        const bool is_global_setting = true; -        PluginManager::CreateSettingForOperatingSystemPlugin( -            debugger, GetGlobalPluginProperties()->GetValueProperties(), -            ConstString("Properties for the goroutine thread plug-in."), is_global_setting); -    } +void OperatingSystemGo::DebuggerInitialize(Debugger &debugger) { +  if (!PluginManager::GetSettingForOperatingSystemPlugin( +          debugger, PluginProperties::GetSettingName())) { +    const bool is_global_setting = true; +    PluginManager::CreateSettingForOperatingSystemPlugin( +        debugger, GetGlobalPluginProperties()->GetValueProperties(), +        ConstString("Properties for the goroutine thread plug-in."), +        is_global_setting); +  }  } -void -OperatingSystemGo::Terminate() -{ -    PluginManager::UnregisterPlugin(CreateInstance); +void OperatingSystemGo::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } -OperatingSystem * -OperatingSystemGo::CreateInstance(Process *process, bool force) -{ -    if (!force) -    { -        TargetSP target_sp = process->CalculateTarget(); -        if (!target_sp) -            return nullptr; -        ModuleList &module_list = target_sp->GetImages(); -        std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); -        const size_t num_modules = module_list.GetSize(); -        bool found_go_runtime = false; -        for (size_t i = 0; i < num_modules; ++i) -        { -            Module *module = module_list.GetModulePointerAtIndexUnlocked(i); -            const SectionList *section_list = module->GetSectionList(); -            if (section_list) -            { -                SectionSP section_sp(section_list->FindSectionByType(eSectionTypeGoSymtab, true)); -                if (section_sp) -                { -                    found_go_runtime = true; -                    break; -                } -            } +OperatingSystem *OperatingSystemGo::CreateInstance(Process *process, +                                                   bool force) { +  if (!force) { +    TargetSP target_sp = process->CalculateTarget(); +    if (!target_sp) +      return nullptr; +    ModuleList &module_list = target_sp->GetImages(); +    std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); +    const size_t num_modules = module_list.GetSize(); +    bool found_go_runtime = false; +    for (size_t i = 0; i < num_modules; ++i) { +      Module *module = module_list.GetModulePointerAtIndexUnlocked(i); +      const SectionList *section_list = module->GetSectionList(); +      if (section_list) { +        SectionSP section_sp( +            section_list->FindSectionByType(eSectionTypeGoSymtab, true)); +        if (section_sp) { +          found_go_runtime = true; +          break;          } -        if (!found_go_runtime) -            return nullptr; +      }      } -    return new OperatingSystemGo(process); +    if (!found_go_runtime) +      return nullptr; +  } +  return new OperatingSystemGo(process);  }  OperatingSystemGo::OperatingSystemGo(lldb_private::Process *process) -    : OperatingSystem(process) -    , m_reginfo(new DynamicRegisterInfo) -{ -} +    : OperatingSystem(process), m_reginfo(new DynamicRegisterInfo) {}  OperatingSystemGo::~OperatingSystemGo() = default; -ConstString -OperatingSystemGo::GetPluginNameStatic() -{ -    static ConstString g_name("goroutines"); -    return g_name; +ConstString OperatingSystemGo::GetPluginNameStatic() { +  static ConstString g_name("goroutines"); +  return g_name;  } -const char * -OperatingSystemGo::GetPluginDescriptionStatic() -{ -    return "Operating system plug-in that reads runtime data-structures for goroutines."; +const char *OperatingSystemGo::GetPluginDescriptionStatic() { +  return "Operating system plug-in that reads runtime data-structures for " +         "goroutines.";  } -bool -OperatingSystemGo::Init(ThreadList &threads) -{ -    if (threads.GetSize(false) < 1) -        return false; -    TargetSP target_sp = m_process->CalculateTarget(); -    if (!target_sp) -        return false; -    // Go 1.6 stores goroutines in a slice called runtime.allgs -    ValueObjectSP allgs_sp = FindGlobal(target_sp, "runtime.allgs"); -    if (allgs_sp) -    { -        m_allg_sp = allgs_sp->GetChildMemberWithName(ConstString("array"), true); -        m_allglen_sp = allgs_sp->GetChildMemberWithName(ConstString("len"), true); -    } -    else -    { -        // Go 1.4 stores goroutines in the variable runtime.allg. -        m_allg_sp = FindGlobal(target_sp, "runtime.allg"); -        m_allglen_sp = FindGlobal(target_sp, "runtime.allglen"); -    } - -    if (m_allg_sp && !m_allglen_sp) -    { -        StreamSP error_sp = target_sp->GetDebugger().GetAsyncErrorStream(); -        error_sp->Printf("Unsupported Go runtime version detected."); -        return false; +bool OperatingSystemGo::Init(ThreadList &threads) { +  if (threads.GetSize(false) < 1) +    return false; +  TargetSP target_sp = m_process->CalculateTarget(); +  if (!target_sp) +    return false; +  // Go 1.6 stores goroutines in a slice called runtime.allgs +  ValueObjectSP allgs_sp = FindGlobal(target_sp, "runtime.allgs"); +  if (allgs_sp) { +    m_allg_sp = allgs_sp->GetChildMemberWithName(ConstString("array"), true); +    m_allglen_sp = allgs_sp->GetChildMemberWithName(ConstString("len"), true); +  } else { +    // Go 1.4 stores goroutines in the variable runtime.allg. +    m_allg_sp = FindGlobal(target_sp, "runtime.allg"); +    m_allglen_sp = FindGlobal(target_sp, "runtime.allglen"); +  } + +  if (m_allg_sp && !m_allglen_sp) { +    StreamSP error_sp = target_sp->GetDebugger().GetAsyncErrorStream(); +    error_sp->Printf("Unsupported Go runtime version detected."); +    return false; +  } + +  if (!m_allg_sp) +    return false; + +  RegisterContextSP real_registers_sp = +      threads.GetThreadAtIndex(0, false)->GetRegisterContext(); + +  std::unordered_map<size_t, ConstString> register_sets; +  for (size_t set_idx = 0; set_idx < real_registers_sp->GetRegisterSetCount(); +       ++set_idx) { +    const RegisterSet *set = real_registers_sp->GetRegisterSet(set_idx); +    ConstString name(set->name); +    for (size_t reg_idx = 0; reg_idx < set->num_registers; ++reg_idx) { +      register_sets[reg_idx] = name;      } +  } +  TypeSP gobuf_sp = FindType(target_sp, "runtime.gobuf"); +  if (!gobuf_sp) { +    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); -    if (!m_allg_sp) -        return false; - -    RegisterContextSP real_registers_sp = threads.GetThreadAtIndex(0, false)->GetRegisterContext(); - -    std::unordered_map<size_t, ConstString> register_sets; -    for (size_t set_idx = 0; set_idx < real_registers_sp->GetRegisterSetCount(); ++set_idx) -    { -        const RegisterSet *set = real_registers_sp->GetRegisterSet(set_idx); -        ConstString name(set->name); -        for (size_t reg_idx = 0; reg_idx < set->num_registers; ++reg_idx) -        { -            register_sets[reg_idx] = name; -        } +    if (log) +      log->Printf("OperatingSystemGo unable to find struct Gobuf"); +    return false; +  } +  CompilerType gobuf_type(gobuf_sp->GetLayoutCompilerType()); +  for (size_t idx = 0; idx < real_registers_sp->GetRegisterCount(); ++idx) { +    RegisterInfo reg = *real_registers_sp->GetRegisterInfoAtIndex(idx); +    int field_index = -1; +    if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) { +      field_index = 0; +    } else if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC) { +      field_index = 1;      } -    TypeSP gobuf_sp = FindType(target_sp, "runtime.gobuf"); -    if (!gobuf_sp) -    { -        Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - -        if (log) -            log->Printf("OperatingSystemGo unable to find struct Gobuf"); -        return false; +    if (field_index == -1) { +      reg.byte_offset = ~0; +    } else { +      std::string field_name; +      uint64_t bit_offset = 0; +      CompilerType field_type = gobuf_type.GetFieldAtIndex( +          field_index, field_name, &bit_offset, nullptr, nullptr); +      reg.byte_size = field_type.GetByteSize(nullptr); +      reg.byte_offset = bit_offset / 8;      } -    CompilerType gobuf_type(gobuf_sp->GetLayoutCompilerType()); -    for (size_t idx = 0; idx < real_registers_sp->GetRegisterCount(); ++idx) -    { -        RegisterInfo reg = *real_registers_sp->GetRegisterInfoAtIndex(idx); -        int field_index = -1; -        if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) -        { -            field_index = 0; -        } -        else if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC) -        { -            field_index = 1; -        } -        if (field_index == -1) -        { -            reg.byte_offset = ~0; -        } -        else -        { -            std::string field_name; -            uint64_t bit_offset = 0; -            CompilerType field_type = -                gobuf_type.GetFieldAtIndex(field_index, field_name, &bit_offset, nullptr, nullptr); -            reg.byte_size = field_type.GetByteSize(nullptr); -            reg.byte_offset = bit_offset / 8; -        } -        ConstString name(reg.name); -        ConstString alt_name(reg.alt_name); -        m_reginfo->AddRegister(reg, name, alt_name, register_sets[idx]); -    } -    return true; +    ConstString name(reg.name); +    ConstString alt_name(reg.alt_name); +    m_reginfo->AddRegister(reg, name, alt_name, register_sets[idx]); +  } +  return true;  }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -ConstString -OperatingSystemGo::GetPluginName() -{ -    return GetPluginNameStatic(); -} +ConstString OperatingSystemGo::GetPluginName() { return GetPluginNameStatic(); } -uint32_t -OperatingSystemGo::GetPluginVersion() -{ -    return 1; -} - -bool -OperatingSystemGo::UpdateThreadList(ThreadList &old_thread_list, ThreadList &real_thread_list, -                                    ThreadList &new_thread_list) -{ -    new_thread_list = real_thread_list; -    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); +uint32_t OperatingSystemGo::GetPluginVersion() { return 1; } -    if (!(m_allg_sp || Init(real_thread_list)) || (m_allg_sp && !m_allglen_sp) || -        !GetGlobalPluginProperties()->GetEnableGoroutines()) -    { -        return new_thread_list.GetSize(false) > 0; -    } +bool OperatingSystemGo::UpdateThreadList(ThreadList &old_thread_list, +                                         ThreadList &real_thread_list, +                                         ThreadList &new_thread_list) { +  new_thread_list = real_thread_list; +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); -    if (log) -        log->Printf("OperatingSystemGo::UpdateThreadList(%d, %d, %d) fetching thread data from Go for pid %" PRIu64, -                    old_thread_list.GetSize(false), real_thread_list.GetSize(false), new_thread_list.GetSize(0), -                    m_process->GetID()); -    uint64_t allglen = m_allglen_sp->GetValueAsUnsigned(0); -    if (allglen == 0) -    { -        return new_thread_list.GetSize(false) > 0; +  if (!(m_allg_sp || Init(real_thread_list)) || (m_allg_sp && !m_allglen_sp) || +      !GetGlobalPluginProperties()->GetEnableGoroutines()) { +    return new_thread_list.GetSize(false) > 0; +  } + +  if (log) +    log->Printf("OperatingSystemGo::UpdateThreadList(%d, %d, %d) fetching " +                "thread data from Go for pid %" PRIu64, +                old_thread_list.GetSize(false), real_thread_list.GetSize(false), +                new_thread_list.GetSize(0), m_process->GetID()); +  uint64_t allglen = m_allglen_sp->GetValueAsUnsigned(0); +  if (allglen == 0) { +    return new_thread_list.GetSize(false) > 0; +  } +  std::vector<Goroutine> goroutines; +  // 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. + +  Error err; +  for (uint64_t i = 0; i < allglen; ++i) { +    goroutines.push_back(CreateGoroutineAtIndex(i, err)); +    if (err.Fail()) { +      err.PutToLog(log, "OperatingSystemGo::UpdateThreadList"); +      return new_thread_list.GetSize(false) > 0;      } -    std::vector<Goroutine> goroutines; -    // 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. - -    Error err; -    for (uint64_t i = 0; i < allglen; ++i) -    { -        goroutines.push_back(CreateGoroutineAtIndex(i, err)); -        if (err.Fail()) -        { -            err.PutToLog(log, "OperatingSystemGo::UpdateThreadList"); -            return new_thread_list.GetSize(false) > 0; -        } +  } +  // Make a map so we can match goroutines with backing threads. +  std::map<uint64_t, ThreadSP> stack_map; +  for (uint32_t i = 0; i < real_thread_list.GetSize(false); ++i) { +    ThreadSP thread = real_thread_list.GetThreadAtIndex(i, false); +    stack_map[thread->GetRegisterContext()->GetSP()] = thread; +  } +  for (const Goroutine &goroutine : goroutines) { +    if (0 /* Gidle */ == goroutine.m_status || +        6 /* Gdead */ == goroutine.m_status) { +      continue;      } -    // Make a map so we can match goroutines with backing threads. -    std::map<uint64_t, ThreadSP> stack_map; -    for (uint32_t i = 0; i < real_thread_list.GetSize(false); ++i) -    { -        ThreadSP thread = real_thread_list.GetThreadAtIndex(i, false); -        stack_map[thread->GetRegisterContext()->GetSP()] = thread; +    ThreadSP memory_thread = +        old_thread_list.FindThreadByID(goroutine.m_goid, false); +    if (memory_thread && IsOperatingSystemPluginThread(memory_thread) && +        memory_thread->IsValid()) { +      memory_thread->ClearBackingThread(); +    } else { +      memory_thread.reset(new ThreadMemory( +          *m_process, goroutine.m_goid, nullptr, nullptr, goroutine.m_gobuf));      } -    for (const Goroutine &goroutine : goroutines) -    { -        if (0 /* Gidle */ == goroutine.m_status || 6 /* Gdead */ == goroutine.m_status) -        { -            continue; +    // Search for the backing thread if the goroutine is running. +    if (2 == (goroutine.m_status & 0xfff)) { +      auto backing_it = stack_map.lower_bound(goroutine.m_lostack); +      if (backing_it != stack_map.end()) { +        if (goroutine.m_histack >= backing_it->first) { +          if (log) +            log->Printf( +                "OperatingSystemGo::UpdateThreadList found backing thread " +                "%" PRIx64 " (%" PRIx64 ") for thread %" PRIx64 "", +                backing_it->second->GetID(), +                backing_it->second->GetProtocolID(), memory_thread->GetID()); +          memory_thread->SetBackingThread(backing_it->second); +          new_thread_list.RemoveThreadByID(backing_it->second->GetID(), false);          } -        ThreadSP memory_thread = old_thread_list.FindThreadByID(goroutine.m_goid, false); -        if (memory_thread && IsOperatingSystemPluginThread(memory_thread) && memory_thread->IsValid()) -        { -            memory_thread->ClearBackingThread(); -        } -        else -        { -            memory_thread.reset(new ThreadMemory(*m_process, goroutine.m_goid, nullptr, nullptr, goroutine.m_gobuf)); -        } -        // Search for the backing thread if the goroutine is running. -        if (2 == (goroutine.m_status & 0xfff)) -        { -            auto backing_it = stack_map.lower_bound(goroutine.m_lostack); -            if (backing_it != stack_map.end()) -            { -                if (goroutine.m_histack >= backing_it->first) -                { -                    if (log) -                        log->Printf("OperatingSystemGo::UpdateThreadList found backing thread %" PRIx64 " (%" PRIx64 -                                    ") for thread %" PRIx64 "", -                                    backing_it->second->GetID(), backing_it->second->GetProtocolID(), -                                    memory_thread->GetID()); -                    memory_thread->SetBackingThread(backing_it->second); -                    new_thread_list.RemoveThreadByID(backing_it->second->GetID(), false); -                } -            } -        } -        new_thread_list.AddThread(memory_thread); +      }      } +    new_thread_list.AddThread(memory_thread); +  } -    return new_thread_list.GetSize(false) > 0; +  return new_thread_list.GetSize(false) > 0;  } -void -OperatingSystemGo::ThreadWasSelected(Thread *thread) -{ -} +void OperatingSystemGo::ThreadWasSelected(Thread *thread) {}  RegisterContextSP -OperatingSystemGo::CreateRegisterContextForThread(Thread *thread, addr_t reg_data_addr) -{ -    RegisterContextSP reg_ctx_sp; -    if (!thread) -        return reg_ctx_sp; - -    if (!IsOperatingSystemPluginThread(thread->shared_from_this())) -        return reg_ctx_sp; +OperatingSystemGo::CreateRegisterContextForThread(Thread *thread, +                                                  addr_t reg_data_addr) { +  RegisterContextSP reg_ctx_sp; +  if (!thread) +    return reg_ctx_sp; -    reg_ctx_sp.reset(new RegisterContextGo(*thread, 0, *m_reginfo, reg_data_addr)); +  if (!IsOperatingSystemPluginThread(thread->shared_from_this()))      return reg_ctx_sp; + +  reg_ctx_sp.reset( +      new RegisterContextGo(*thread, 0, *m_reginfo, reg_data_addr)); +  return reg_ctx_sp;  }  StopInfoSP -OperatingSystemGo::CreateThreadStopReason(lldb_private::Thread *thread) -{ -    StopInfoSP stop_info_sp; -    return stop_info_sp; +OperatingSystemGo::CreateThreadStopReason(lldb_private::Thread *thread) { +  StopInfoSP stop_info_sp; +  return stop_info_sp;  } -lldb::ThreadSP -OperatingSystemGo::CreateThread(lldb::tid_t tid, addr_t context) -{ -    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); +lldb::ThreadSP OperatingSystemGo::CreateThread(lldb::tid_t tid, +                                               addr_t context) { +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); -    if (log) -        log->Printf("OperatingSystemGo::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") not implemented", -                    tid, context); +  if (log) +    log->Printf("OperatingSystemGo::CreateThread (tid = 0x%" PRIx64 +                ", context = 0x%" PRIx64 ") not implemented", +                tid, context); -    return ThreadSP(); +  return ThreadSP();  } -ValueObjectSP -OperatingSystemGo::FindGlobal(TargetSP target, const char *name) -{ -    VariableList variable_list; -    const bool append = true; - -    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - -    if (log) -    { -        log->Printf("exe: %s", target->GetExecutableModule()->GetSpecificationDescription().c_str()); -        log->Printf("modules: %zu", target->GetImages().GetSize()); -    } - -    uint32_t match_count = target->GetImages().FindGlobalVariables(ConstString(name), append, 1, variable_list); -    if (match_count > 0) -    { -        ExecutionContextScope *exe_scope = target->GetProcessSP().get(); -        if (exe_scope == NULL) -            exe_scope = target.get(); -        return ValueObjectVariable::Create(exe_scope, variable_list.GetVariableAtIndex(0)); -    } -    return ValueObjectSP(); +ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) { +  VariableList variable_list; +  const bool append = true; + +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); + +  if (log) { +    log->Printf( +        "exe: %s", +        target->GetExecutableModule()->GetSpecificationDescription().c_str()); +    log->Printf("modules: %zu", target->GetImages().GetSize()); +  } + +  uint32_t match_count = target->GetImages().FindGlobalVariables( +      ConstString(name), append, 1, variable_list); +  if (match_count > 0) { +    ExecutionContextScope *exe_scope = target->GetProcessSP().get(); +    if (exe_scope == NULL) +      exe_scope = target.get(); +    return ValueObjectVariable::Create(exe_scope, +                                       variable_list.GetVariableAtIndex(0)); +  } +  return ValueObjectSP();  } -TypeSP -OperatingSystemGo::FindType(TargetSP target_sp, const char *name) -{ -    ConstString const_typename(name); -    SymbolContext sc; -    const bool exact_match = false; - -    const ModuleList &module_list = target_sp->GetImages(); -    size_t count = module_list.GetSize(); -    for (size_t idx = 0; idx < count; idx++) -    { -        ModuleSP module_sp(module_list.GetModuleAtIndex(idx)); -        if (module_sp) -        { -            TypeSP type_sp(module_sp->FindFirstType(sc, const_typename, exact_match)); -            if (type_sp) -                return type_sp; -        } +TypeSP OperatingSystemGo::FindType(TargetSP target_sp, const char *name) { +  ConstString const_typename(name); +  SymbolContext sc; +  const bool exact_match = false; + +  const ModuleList &module_list = target_sp->GetImages(); +  size_t count = module_list.GetSize(); +  for (size_t idx = 0; idx < count; idx++) { +    ModuleSP module_sp(module_list.GetModuleAtIndex(idx)); +    if (module_sp) { +      TypeSP type_sp(module_sp->FindFirstType(sc, const_typename, exact_match)); +      if (type_sp) +        return type_sp;      } -    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); +  } +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); -    if (log) -        log->Printf("OperatingSystemGo::FindType(%s): not found", name); -    return TypeSP(); +  if (log) +    log->Printf("OperatingSystemGo::FindType(%s): not found", name); +  return TypeSP();  }  OperatingSystemGo::Goroutine -OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err) -{ -    err.Clear(); -    Goroutine result = {}; -    ValueObjectSP g = m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err); -    if (err.Fail()) -    { -        return result; -    } - -    ConstString name("goid"); -    ValueObjectSP val = g->GetChildMemberWithName(name, true); -    bool success = false; -    result.m_goid = val->GetValueAsUnsigned(0, &success); -    if (!success) -    { -        err.SetErrorToGenericError(); -        err.SetErrorString("unable to read goid"); -        return result; -    } -    name.SetCString("atomicstatus"); -    val = g->GetChildMemberWithName(name, true); -    result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success); -    if (!success) -    { -        err.SetErrorToGenericError(); -        err.SetErrorString("unable to read atomicstatus"); -        return result; -    } -    name.SetCString("sched"); -    val = g->GetChildMemberWithName(name, true); -    result.m_gobuf = val->GetAddressOf(false); -    name.SetCString("stack"); -    val = g->GetChildMemberWithName(name, true); -    name.SetCString("lo"); -    ValueObjectSP child = val->GetChildMemberWithName(name, true); -    result.m_lostack = child->GetValueAsUnsigned(0, &success); -    if (!success) -    { -        err.SetErrorToGenericError(); -        err.SetErrorString("unable to read stack.lo"); -        return result; -    } -    name.SetCString("hi"); -    child = val->GetChildMemberWithName(name, true); -    result.m_histack = child->GetValueAsUnsigned(0, &success); -    if (!success) -    { -        err.SetErrorToGenericError(); -        err.SetErrorString("unable to read stack.hi"); -        return result; -    } +OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err) { +  err.Clear(); +  Goroutine result = {}; +  ValueObjectSP g = +      m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err); +  if (err.Fail()) { +    return result; +  } + +  ConstString name("goid"); +  ValueObjectSP val = g->GetChildMemberWithName(name, true); +  bool success = false; +  result.m_goid = val->GetValueAsUnsigned(0, &success); +  if (!success) { +    err.SetErrorToGenericError(); +    err.SetErrorString("unable to read goid"); +    return result; +  } +  name.SetCString("atomicstatus"); +  val = g->GetChildMemberWithName(name, true); +  result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success); +  if (!success) { +    err.SetErrorToGenericError(); +    err.SetErrorString("unable to read atomicstatus"); +    return result; +  } +  name.SetCString("sched"); +  val = g->GetChildMemberWithName(name, true); +  result.m_gobuf = val->GetAddressOf(false); +  name.SetCString("stack"); +  val = g->GetChildMemberWithName(name, true); +  name.SetCString("lo"); +  ValueObjectSP child = val->GetChildMemberWithName(name, true); +  result.m_lostack = child->GetValueAsUnsigned(0, &success); +  if (!success) { +    err.SetErrorToGenericError(); +    err.SetErrorString("unable to read stack.lo"); +    return result; +  } +  name.SetCString("hi"); +  child = val->GetChildMemberWithName(name, true); +  result.m_histack = child->GetValueAsUnsigned(0, &success); +  if (!success) { +    err.SetErrorToGenericError(); +    err.SetErrorString("unable to read stack.hi");      return result; +  } +  return result;  } diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h index d3391d907dfe..d289985c72ad 100644 --- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h +++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h @@ -20,68 +20,71 @@  class DynamicRegisterInfo; -class OperatingSystemGo : public lldb_private::OperatingSystem -{ +class OperatingSystemGo : public lldb_private::OperatingSystem {  public: -    OperatingSystemGo(lldb_private::Process *process); +  OperatingSystemGo(lldb_private::Process *process); -    ~OperatingSystemGo() override; +  ~OperatingSystemGo() override; -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static lldb_private::OperatingSystem *CreateInstance(lldb_private::Process *process, bool force); +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static lldb_private::OperatingSystem * +  CreateInstance(lldb_private::Process *process, bool force); -    static void Initialize(); +  static void Initialize(); -    static void DebuggerInitialize(lldb_private::Debugger &debugger); +  static void DebuggerInitialize(lldb_private::Debugger &debugger); -    static void Terminate(); +  static void Terminate(); -    static lldb_private::ConstString GetPluginNameStatic(); +  static lldb_private::ConstString GetPluginNameStatic(); -    static const char *GetPluginDescriptionStatic(); +  static const char *GetPluginDescriptionStatic(); -    //------------------------------------------------------------------ -    // lldb_private::PluginInterface Methods -    //------------------------------------------------------------------ -    lldb_private::ConstString GetPluginName() override; +  //------------------------------------------------------------------ +  // lldb_private::PluginInterface Methods +  //------------------------------------------------------------------ +  lldb_private::ConstString GetPluginName() override; -    uint32_t GetPluginVersion() 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; +  //------------------------------------------------------------------ +  // 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; +  void ThreadWasSelected(lldb_private::Thread *thread) override; -    lldb::RegisterContextSP CreateRegisterContextForThread(lldb_private::Thread *thread, -                                                           lldb::addr_t reg_data_addr) override; +  lldb::RegisterContextSP +  CreateRegisterContextForThread(lldb_private::Thread *thread, +                                 lldb::addr_t reg_data_addr) override; -    lldb::StopInfoSP CreateThreadStopReason(lldb_private::Thread *thread) 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; +  //------------------------------------------------------------------ +  // Method for lazy creation of threads on demand +  //------------------------------------------------------------------ +  lldb::ThreadSP CreateThread(lldb::tid_t tid, lldb::addr_t context) override;  private: -    struct Goroutine; +  struct Goroutine; -    static lldb::ValueObjectSP FindGlobal(lldb::TargetSP target, const char *name); +  static lldb::ValueObjectSP FindGlobal(lldb::TargetSP target, +                                        const char *name); -    static lldb::TypeSP FindType(lldb::TargetSP target_sp, const char *name); +  static lldb::TypeSP FindType(lldb::TargetSP target_sp, const char *name); -    bool Init(lldb_private::ThreadList &threads); +  bool Init(lldb_private::ThreadList &threads); -    Goroutine CreateGoroutineAtIndex(uint64_t idx, lldb_private::Error &err); +  Goroutine CreateGoroutineAtIndex(uint64_t idx, lldb_private::Error &err); -    std::unique_ptr<DynamicRegisterInfo> m_reginfo; -    lldb::ValueObjectSP m_allg_sp; -    lldb::ValueObjectSP m_allglen_sp; +  std::unique_ptr<DynamicRegisterInfo> m_reginfo; +  lldb::ValueObjectSP m_allg_sp; +  lldb::ValueObjectSP m_allglen_sp;  };  #endif // liblldb_OperatingSystemGo_h_ | 
