diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Target/Thread.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Target/Thread.cpp | 213 |
1 files changed, 122 insertions, 91 deletions
diff --git a/contrib/llvm/tools/lldb/source/Target/Thread.cpp b/contrib/llvm/tools/lldb/source/Target/Thread.cpp index 5ead590..505d140 100644 --- a/contrib/llvm/tools/lldb/source/Target/Thread.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Thread.cpp @@ -17,12 +17,8 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/State.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" @@ -51,6 +47,11 @@ #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -380,24 +381,32 @@ lldb::StopInfoSP Thread::GetStopInfo() { if (m_destroy_called) return m_stop_info_sp; - ThreadPlanSP plan_sp(GetCompletedPlan()); + ThreadPlanSP completed_plan_sp(GetCompletedPlan()); ProcessSP process_sp(GetProcess()); const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX; - if (plan_sp && plan_sp->PlanSucceeded()) { - return StopInfo::CreateStopReasonWithPlan(plan_sp, GetReturnValueObject(), - GetExpressionVariable()); + + // Here we select the stop info according to priorirty: + // - m_stop_info_sp (if not trace) - preset value + // - completed plan stop info - new value with plan from completed plan stack + // - m_stop_info_sp (trace stop reason is OK now) + // - ask GetPrivateStopInfo to set stop info + + bool have_valid_stop_info = m_stop_info_sp && + m_stop_info_sp ->IsValid() && + m_stop_info_stop_id == stop_id; + bool have_valid_completed_plan = completed_plan_sp && completed_plan_sp->PlanSucceeded(); + bool plan_overrides_trace = + have_valid_stop_info && have_valid_completed_plan + && (m_stop_info_sp->GetStopReason() == eStopReasonTrace); + + if (have_valid_stop_info && !plan_overrides_trace) { + return m_stop_info_sp; + } else if (have_valid_completed_plan) { + return StopInfo::CreateStopReasonWithPlan( + completed_plan_sp, GetReturnValueObject(), GetExpressionVariable()); } else { - if ((m_stop_info_stop_id == stop_id) || // Stop info is valid, just return - // what we have (even if empty) - (m_stop_info_sp && - m_stop_info_sp - ->IsValid())) // Stop info is valid, just return what we have - { - return m_stop_info_sp; - } else { - GetPrivateStopInfo(); - return m_stop_info_sp; - } + GetPrivateStopInfo(); + return m_stop_info_sp; } } @@ -459,6 +468,12 @@ bool Thread::StopInfoIsUpToDate() const { // date... } +void Thread::ResetStopInfo() { + if (m_stop_info_sp) { + m_stop_info_sp.reset(); + } +} + void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) { m_stop_info_sp = stop_info_sp; if (m_stop_info_sp) { @@ -526,6 +541,7 @@ bool Thread::CheckpointThreadState(ThreadStateCheckpoint &saved_state) { if (process_sp) saved_state.orig_stop_id = process_sp->GetStopID(); saved_state.current_inlined_depth = GetCurrentInlinedDepth(); + saved_state.m_completed_plan_stack = m_completed_plan_stack; return true; } @@ -559,6 +575,7 @@ bool Thread::RestoreThreadStateFromCheckpoint( SetStopInfo(saved_state.stop_info_sp); GetStackFrameList()->SetCurrentInlinedDepth( saved_state.current_inlined_depth); + m_completed_plan_stack = saved_state.m_completed_plan_stack; return true; } @@ -895,6 +912,9 @@ bool Thread::ShouldStop(Event *event_ptr) { if (should_stop) { ThreadPlan *plan_ptr = GetCurrentPlan(); + + // Discard the stale plans and all plans below them in the stack, + // plus move the completed plans to the completed plan stack while (!PlanIsBasePlan(plan_ptr)) { bool stale = plan_ptr->IsPlanStale(); ThreadPlan *examined_plan = plan_ptr; @@ -905,7 +925,15 @@ bool Thread::ShouldStop(Event *event_ptr) { log->Printf( "Plan %s being discarded in cleanup, it says it is already done.", examined_plan->GetName()); - DiscardThreadPlansUpToPlan(examined_plan); + while (GetCurrentPlan() != examined_plan) { + DiscardPlan(); + } + if (examined_plan->IsPlanComplete()) { + // plan is complete but does not explain the stop (example: step to a line + // with breakpoint), let us move the plan to completed_plan_stack anyway + PopPlan(); + } else + DiscardPlan(); } } } @@ -1133,6 +1161,10 @@ bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) { return false; } +bool Thread::CompletedPlanOverridesBreakpoint() { + return (!m_completed_plan_stack.empty()) ; +} + ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) { if (current_plan == nullptr) return nullptr; @@ -1304,8 +1336,8 @@ bool Thread::PlanIsBasePlan(ThreadPlan *plan_ptr) { return m_plan_stack[0].get() == plan_ptr; } -Error Thread::UnwindInnermostExpression() { - Error error; +Status Thread::UnwindInnermostExpression() { + Status error; int stack_size = m_plan_stack.size(); // If the input plan is nullptr, discard all plans. Otherwise make sure this @@ -1604,11 +1636,11 @@ lldb::StackFrameSP Thread::GetFrameWithConcreteFrameIndex(uint32_t unwind_idx) { return GetStackFrameList()->GetFrameWithConcreteFrameIndex(unwind_idx); } -Error Thread::ReturnFromFrameWithIndex(uint32_t frame_idx, - lldb::ValueObjectSP return_value_sp, - bool broadcast) { +Status Thread::ReturnFromFrameWithIndex(uint32_t frame_idx, + lldb::ValueObjectSP return_value_sp, + bool broadcast) { StackFrameSP frame_sp = GetStackFrameAtIndex(frame_idx); - Error return_error; + Status return_error; if (!frame_sp) { return_error.SetErrorStringWithFormat( @@ -1619,10 +1651,10 @@ Error Thread::ReturnFromFrameWithIndex(uint32_t frame_idx, return ReturnFromFrame(frame_sp, return_value_sp, broadcast); } -Error Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp, - lldb::ValueObjectSP return_value_sp, - bool broadcast) { - Error return_error; +Status Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp, + lldb::ValueObjectSP return_value_sp, + bool broadcast) { + Status return_error; if (!frame_sp) { return_error.SetErrorString("Can't return to a null frame."); @@ -1709,8 +1741,8 @@ static void DumpAddressList(Stream &s, const std::vector<Address> &list, } } -Error Thread::JumpToLine(const FileSpec &file, uint32_t line, - bool can_leave_function, std::string *warnings) { +Status 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(); @@ -1738,16 +1770,16 @@ Error Thread::JumpToLine(const FileSpec &file, uint32_t line, // 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); + return Status("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); + return Status("%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.GetData()); + return Status("%s:%i has multiple candidate locations:\n%s", + file.GetFilename().AsCString(), line, sstr.GetData()); } } @@ -1763,9 +1795,9 @@ Error Thread::JumpToLine(const FileSpec &file, uint32_t line, } if (!reg_ctx->SetPC(dest)) - return Error("Cannot change PC to target address."); + return Status("Cannot change PC to target address."); - return Error(); + return Status(); } void Thread::DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx, @@ -1881,39 +1913,42 @@ const char *Thread::RunModeAsCString(lldb::RunMode mode) { size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source, - bool stop_format) { - ExecutionContext exe_ctx(shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - Process *process = exe_ctx.GetProcessPtr(); - size_t num_frames_shown = 0; - strm.Indent(); - bool is_selected = false; - if (process) { - if (process->GetThreadList().GetSelectedThread().get() == this) - is_selected = true; - } - strm.Printf("%c ", is_selected ? '*' : ' '); - if (target && target->GetDebugger().GetUseExternalEditor()) { - StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); - if (frame_sp) { - SymbolContext frame_sc( - frame_sp->GetSymbolContext(eSymbolContextLineEntry)); - if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { - Host::OpenFileInExternalEditor(frame_sc.line_entry.file, - frame_sc.line_entry.line); + bool stop_format, bool only_stacks) { + + if (!only_stacks) { + ExecutionContext exe_ctx(shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + strm.Indent(); + bool is_selected = false; + if (process) { + if (process->GetThreadList().GetSelectedThread().get() == this) + is_selected = true; + } + strm.Printf("%c ", is_selected ? '*' : ' '); + if (target && target->GetDebugger().GetUseExternalEditor()) { + StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); + if (frame_sp) { + SymbolContext frame_sc( + frame_sp->GetSymbolContext(eSymbolContextLineEntry)); + if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { + Host::OpenFileInExternalEditor(frame_sc.line_entry.file, + frame_sc.line_entry.line); + } } } - } - DumpUsingSettingsFormat(strm, start_frame, stop_format); + DumpUsingSettingsFormat(strm, start_frame, stop_format); + } + size_t num_frames_shown = 0; if (num_frames > 0) { strm.IndentMore(); const bool show_frame_info = true; - + const bool show_frame_unique = only_stacks; const char *selected_frame_marker = nullptr; - if (num_frames == 1 || + if (num_frames == 1 || only_stacks || (GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID())) strm.IndentMore(); else @@ -1921,7 +1956,7 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, num_frames_shown = GetStackFrameList()->GetStatus( strm, start_frame, num_frames, show_frame_info, num_frames_with_source, - selected_frame_marker); + show_frame_unique, selected_frame_marker); if (num_frames == 1) strm.IndentLess(); strm.IndentLess(); @@ -1963,22 +1998,20 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, thread_info->GetObjectForDotSeparatedPath("trace_messages"); bool printed_activity = false; - if (activity && - activity->GetType() == StructuredData::Type::eTypeDictionary) { + if (activity && activity->GetType() == eStructuredDataTypeDictionary) { StructuredData::Dictionary *activity_dict = activity->GetAsDictionary(); StructuredData::ObjectSP id = activity_dict->GetValueForKey("id"); StructuredData::ObjectSP name = activity_dict->GetValueForKey("name"); - if (name && name->GetType() == StructuredData::Type::eTypeString && id && - id->GetType() == StructuredData::Type::eTypeInteger) { - strm.Printf(" Activity '%s', 0x%" PRIx64 "\n", - name->GetAsString()->GetValue().c_str(), + if (name && name->GetType() == eStructuredDataTypeString && id && + id->GetType() == eStructuredDataTypeInteger) { + strm.Format(" Activity '{0}', {1:x}\n", + name->GetAsString()->GetValue(), id->GetAsInteger()->GetValue()); } printed_activity = true; } bool printed_breadcrumb = false; - if (breadcrumb && - breadcrumb->GetType() == StructuredData::Type::eTypeDictionary) { + if (breadcrumb && breadcrumb->GetType() == eStructuredDataTypeDictionary) { if (printed_activity) strm.Printf("\n"); StructuredData::Dictionary *breadcrumb_dict = @@ -1986,13 +2019,13 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, StructuredData::ObjectSP breadcrumb_text = breadcrumb_dict->GetValueForKey("name"); if (breadcrumb_text && - breadcrumb_text->GetType() == StructuredData::Type::eTypeString) { - strm.Printf(" Current Breadcrumb: %s\n", - breadcrumb_text->GetAsString()->GetValue().c_str()); + breadcrumb_text->GetType() == eStructuredDataTypeString) { + strm.Format(" Current Breadcrumb: {0}\n", + breadcrumb_text->GetAsString()->GetValue()); } printed_breadcrumb = true; } - if (messages && messages->GetType() == StructuredData::Type::eTypeArray) { + if (messages && messages->GetType() == eStructuredDataTypeArray) { if (printed_breadcrumb) strm.Printf("\n"); StructuredData::Array *messages_array = messages->GetAsArray(); @@ -2001,16 +2034,14 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, strm.Printf(" %zu trace messages:\n", msg_count); for (size_t i = 0; i < msg_count; i++) { StructuredData::ObjectSP message = messages_array->GetItemAtIndex(i); - if (message && - message->GetType() == StructuredData::Type::eTypeDictionary) { + if (message && message->GetType() == eStructuredDataTypeDictionary) { StructuredData::Dictionary *message_dict = message->GetAsDictionary(); StructuredData::ObjectSP message_text = message_dict->GetValueForKey("message"); if (message_text && - message_text->GetType() == StructuredData::Type::eTypeString) { - strm.Printf(" %s\n", - message_text->GetAsString()->GetValue().c_str()); + message_text->GetType() == eStructuredDataTypeString) { + strm.Format(" {0}\n", message_text->GetAsString()->GetValue()); } } } @@ -2086,12 +2117,12 @@ bool Thread::IsStillAtLastBreakpointHit() { return false; } -Error Thread::StepIn(bool source_step, - LazyBool step_in_avoids_code_without_debug_info, - LazyBool step_out_avoids_code_without_debug_info) +Status Thread::StepIn(bool source_step, + LazyBool step_in_avoids_code_without_debug_info, + LazyBool step_out_avoids_code_without_debug_info) { - Error error; + Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { StackFrameSP frame_sp = GetStackFrameAtIndex(0); @@ -2122,9 +2153,9 @@ Error Thread::StepIn(bool source_step, return error; } -Error Thread::StepOver(bool source_step, - LazyBool step_out_avoids_code_without_debug_info) { - Error error; +Status Thread::StepOver(bool source_step, + LazyBool step_out_avoids_code_without_debug_info) { + Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { StackFrameSP frame_sp = GetStackFrameAtIndex(0); @@ -2155,8 +2186,8 @@ Error Thread::StepOver(bool source_step, return error; } -Error Thread::StepOut() { - Error error; +Status Thread::StepOut() { + Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { const bool first_instruction = false; |