diff options
Diffstat (limited to 'source/Target/Thread.cpp')
| -rw-r--r-- | source/Target/Thread.cpp | 118 | 
1 files changed, 112 insertions, 6 deletions
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp index b65434bf9482..98c26019b4a1 100644 --- a/source/Target/Thread.cpp +++ b/source/Target/Thread.cpp @@ -282,12 +282,18 @@ Thread::~Thread()  void   Thread::DestroyThread ()  { -    // Tell any plans on the plan stack that the thread is being destroyed since -    // any active plans that have a thread go away in the middle of might need -    // to do cleanup. +    // Tell any plans on the plan stacks that the thread is being destroyed since +    // any plans that have a thread go away in the middle of might need +    // to do cleanup, or in some cases NOT do cleanup...      for (auto plan : m_plan_stack)          plan->ThreadDestroyed(); +    for (auto plan : m_discarded_plan_stack) +        plan->ThreadDestroyed(); + +    for (auto plan : m_completed_plan_stack) +        plan->ThreadDestroyed(); +      m_destroy_called = true;      m_plan_stack.clear();      m_discarded_plan_stack.clear(); @@ -1745,6 +1751,79 @@ Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return      return return_error;  } +static void DumpAddressList (Stream &s, const std::vector<Address> &list, ExecutionContextScope *exe_scope) +{ +    for (size_t n=0;n<list.size();n++) +    { +        s << "\t"; +        list[n].Dump (&s, exe_scope, Address::DumpStyleResolvedDescription, Address::DumpStyleSectionNameOffset); +        s << "\n"; +    } +} + +Error +Thread::JumpToLine (const FileSpec &file, uint32_t line, bool can_leave_function, std::string *warnings) +{ +    ExecutionContext exe_ctx (GetStackFrameAtIndex(0)); +    Target *target = exe_ctx.GetTargetPtr(); +    TargetSP target_sp = exe_ctx.GetTargetSP(); +    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); +    StackFrame *frame = exe_ctx.GetFramePtr(); +    const SymbolContext &sc = frame->GetSymbolContext(eSymbolContextFunction); + +    // Find candidate locations. +    std::vector<Address> candidates, within_function, outside_function; +    target->GetImages().FindAddressesForLine (target_sp, file, line, sc.function, within_function, outside_function); + +    // If possible, we try and stay within the current function. +    // Within a function, we accept multiple locations (optimized code may do this, +    // there's no solution here so we do the best we can). +    // However if we're trying to leave the function, we don't know how to pick the +    // right location, so if there's more than one then we bail. +    if (!within_function.empty()) +        candidates = within_function; +    else if (outside_function.size() == 1 && can_leave_function) +        candidates = outside_function; + +    // Check if we got anything. +    if (candidates.empty()) +    { +        if (outside_function.empty()) +        { +            return Error("Cannot locate an address for %s:%i.", +                         file.GetFilename().AsCString(), line); +        } +        else if (outside_function.size() == 1) +        { +            return Error("%s:%i is outside the current function.", +                         file.GetFilename().AsCString(), line); +        } +        else +        { +            StreamString sstr; +            DumpAddressList(sstr, outside_function, target); +            return Error("%s:%i has multiple candidate locations:\n%s", +                         file.GetFilename().AsCString(), line, sstr.GetString().c_str()); +        } +    } + +    // Accept the first location, warn about any others. +    Address dest = candidates[0]; +    if (warnings && candidates.size() > 1) +    { +        StreamString sstr; +        sstr.Printf("%s:%i appears multiple times in this function, selecting the first location:\n", +                     file.GetFilename().AsCString(), line); +        DumpAddressList(sstr, candidates, target); +        *warnings = sstr.GetString(); +    } + +    if (!reg_ctx->SetPC (dest)) +        return Error("Cannot change PC to target address."); + +    return Error(); +} +  void  Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)  { @@ -1784,6 +1863,24 @@ Thread::SettingsTerminate ()  {  } +lldb::addr_t +Thread::GetThreadPointer () +{ +    return LLDB_INVALID_ADDRESS; +} + +addr_t +Thread::GetThreadLocalData (const ModuleSP module) +{ +    // The default implementation is to ask the dynamic loader for it. +    // This can be overridden for specific platforms. +    DynamicLoader *loader = GetProcess()->GetDynamicLoader(); +    if (loader) +        return loader->GetThreadLocalData (module, shared_from_this()); +    else +        return LLDB_INVALID_ADDRESS; +} +  lldb::StackFrameSP  Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)  { @@ -1863,13 +1960,21 @@ Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint          strm.IndentMore();          const bool show_frame_info = true; -        strm.IndentMore (); +         +        const char *selected_frame_marker = NULL; +        if (num_frames == 1 || (GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID())) +            strm.IndentMore (); +        else +            selected_frame_marker = "* "; +          num_frames_shown = GetStackFrameList ()->GetStatus (strm,                                                              start_frame,                                                               num_frames,                                                               show_frame_info,  -                                                            num_frames_with_source); -        strm.IndentLess(); +                                                            num_frames_with_source, +                                                            selected_frame_marker); +        if (num_frames == 1) +            strm.IndentLess();          strm.IndentLess();      }      return num_frames_shown; @@ -1944,6 +2049,7 @@ Thread::GetUnwinder ()              case llvm::Triple::x86:              case llvm::Triple::arm:              case llvm::Triple::thumb: +            case llvm::Triple::mips64:                  m_unwinder_ap.reset (new UnwindLLDB (*this));                  break;  | 
