jingham created this revision. jingham added reviewers: friss, clayborg. Herald added subscribers: lldb-commits, danielkiss, kristof.beyls. Herald added a project: LLDB.
This is the first part of a multi-part commit. This change makes the ThreadPlans use the process & TID to specify which thread they belong to, rather than holding onto the Thread * directly. It doesn't change any behavior, it just means ThreadPlans have to get their thread from the ThreadPlan::GetThread() API, and OTOH can access their process and TID directly. This point of this multi-part commit will be to make it possible to preserve the stepping intentions for a thread in the target, even if the target doesn't report all threads on every stop. This is particularly a problem for targets that provide their threads using an OSPlugin thread provider. The Darwin kernel uses this extensively, and they found that if they reported all the current threads on every stop, it made stepping unusably slow. So they only report the "on core" threads when they stop. That made stepping perform acceptably, but caused stepping to behave badly. For instance, suppose you were next-ing Thread A, and the code had stepped into a function and so needed to step out. So lldb would set a breakpoint at the return address of the function, then continue. If you are unlucky, Thread B might hit a breakpoint before thread A completed its step out, and furthermore when Thread B stopped, Thread A didn't happen to be on another core. Then lldb would think Thread A has exited, and would remove the step out breakpoint. That meant when you continued again, your step-over would have turned into a continue. To fix this problem, I am going to move the ThreadPlan stacks into a separate class, and then have the Process hold onto the map of TID -> ThreadPlanStacks. Then if a thread goes away, we can leave its entry in the map, and if the thread comes back to life, we will know what we were doing with it. Couple of other random observations: - I tried preserving the whole Thread object for a while, but the logic for merging the old & new thread lists is pretty tricky and intervening at that point made this tricky code even harder to understand. Plus this was preserving a lot of unneeded information. Just keeping the ThreadPlanStack off to one side was much cleaner. - Leaving actually obsolete thread plan stacks around does have a cost. For instance, if the thread in the example above had really gone away, then we would leave a step-out breakpoint stranded. It wouldn't do any harm, since it is thread specific for a non-existent thread. But it would slow down execution. In the patches in this sequence, I will only preserve vanished thread's ThreadPlanStacks if there is an OperatingSystem plugin. So it won't affect the current ProcessGDBRemote clients, since ProcessGDBRemote always gets all "real" threads on every stop at present. In the future, we could change ProcessGDBRemote to NOT gather all threads on stop, but just read the threads that stopped "for a reason". We would have to encode that in the stop packet somehow. That could make stepping more efficient. If lldb was going to continue immediately (it was in the middle of stepping or whatever) it would be great to only have to reconstruct one or two threads. In the case of ProcessGDBRemote, we could even refine this by asking about the existence of all the threads that had non-trivial thread plans in flight, along with the stopped-for-a-reason threads. That would allow us to reap any of the ThreadPlanStacks that had any effect on the process (setting breakpoints, etc...) without having to enumerate all threads. Future: The sequence of patches should be: 1. This patch deals with how ThreadPlans know what thread they belong to. 2. Do the same change to ThreadPlanTracers 3. Introduce the ThreadPlanStacks, and move the plans there, but keep them in the Thread 4. Move the ThreadPlanStacks into the Process, and manage detaching & reattaching them from Threads as they come and go. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D75711 Files: lldb/include/lldb/Target/ThreadPlan.h lldb/include/lldb/Target/ThreadPlanPython.h lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp lldb/source/Target/ThreadPlan.cpp lldb/source/Target/ThreadPlanBase.cpp lldb/source/Target/ThreadPlanCallFunction.cpp lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp lldb/source/Target/ThreadPlanCallUserExpression.cpp lldb/source/Target/ThreadPlanPython.cpp lldb/source/Target/ThreadPlanRunToAddress.cpp lldb/source/Target/ThreadPlanStepInRange.cpp lldb/source/Target/ThreadPlanStepInstruction.cpp lldb/source/Target/ThreadPlanStepOut.cpp lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp lldb/source/Target/ThreadPlanStepOverRange.cpp lldb/source/Target/ThreadPlanStepRange.cpp lldb/source/Target/ThreadPlanStepThrough.cpp lldb/source/Target/ThreadPlanStepUntil.cpp
Index: lldb/source/Target/ThreadPlanStepUntil.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepUntil.cpp +++ lldb/source/Target/ThreadPlanStepUntil.cpp @@ -34,17 +34,16 @@ m_should_stop(false), m_ran_analyze(false), m_explains_stop(false), m_until_points(), m_stop_others(stop_others) { // Stash away our "until" addresses: - TargetSP target_sp(m_thread.CalculateTarget()); + TargetSP target_sp(thread.CalculateTarget()); - StackFrameSP frame_sp(m_thread.GetStackFrameAtIndex(frame_idx)); + StackFrameSP frame_sp(thread.GetStackFrameAtIndex(frame_idx)); if (frame_sp) { m_step_from_insn = frame_sp->GetStackID().GetPC(); - lldb::user_id_t thread_id = m_thread.GetID(); // Find the return address and set a breakpoint there: // FIXME - can we do this more securely if we know first_insn? - StackFrameSP return_frame_sp(m_thread.GetStackFrameAtIndex(frame_idx + 1)); + StackFrameSP return_frame_sp(thread.GetStackFrameAtIndex(frame_idx + 1)); if (return_frame_sp) { // TODO: add inline functionality m_return_addr = return_frame_sp->GetStackID().GetPC(); @@ -54,7 +53,7 @@ if (return_bp != nullptr) { if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) m_could_not_resolve_hw_bp = true; - return_bp->SetThreadID(thread_id); + return_bp->SetThreadID(m_tid); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("until-return-backstop"); } @@ -67,7 +66,7 @@ Breakpoint *until_bp = target_sp->CreateBreakpoint(address_list[i], true, false).get(); if (until_bp != nullptr) { - until_bp->SetThreadID(thread_id); + until_bp->SetThreadID(m_tid); m_until_points[address_list[i]] = until_bp->GetID(); until_bp->SetBreakpointKind("until-target"); } else { @@ -80,17 +79,15 @@ ThreadPlanStepUntil::~ThreadPlanStepUntil() { Clear(); } void ThreadPlanStepUntil::Clear() { - TargetSP target_sp(m_thread.CalculateTarget()); - if (target_sp) { - if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { - target_sp->RemoveBreakpointByID(m_return_bp_id); - m_return_bp_id = LLDB_INVALID_BREAK_ID; - } + Target &target = GetTarget(); + if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { + target.RemoveBreakpointByID(m_return_bp_id); + m_return_bp_id = LLDB_INVALID_BREAK_ID; + } - until_collection::iterator pos, end = m_until_points.end(); - for (pos = m_until_points.begin(); pos != end; pos++) { - target_sp->RemoveBreakpointByID((*pos).second); - } + until_collection::iterator pos, end = m_until_points.end(); + for (pos = m_until_points.begin(); pos != end; pos++) { + target.RemoveBreakpointByID((*pos).second); } m_until_points.clear(); m_could_not_resolve_hw_bp = false; @@ -158,7 +155,7 @@ // If this is OUR breakpoint, we're fine, otherwise we don't know why // this happened... BreakpointSiteSP this_site = - m_thread.GetProcess()->GetBreakpointSiteList().FindByID( + m_process.GetBreakpointSiteList().FindByID( stop_info_sp->GetValue()); if (!this_site) { m_explains_stop = false; @@ -196,17 +193,17 @@ for (pos = m_until_points.begin(); pos != end; pos++) { if (this_site->IsBreakpointAtThisSite((*pos).second)) { // If we're at the right stack depth, then we're done. - + Thread &thread = GetThread(); bool done; StackID frame_zero_id = - m_thread.GetStackFrameAtIndex(0)->GetStackID(); + thread.GetStackFrameAtIndex(0)->GetStackID(); if (frame_zero_id == m_stack_id) done = true; else if (frame_zero_id < m_stack_id) done = false; else { - StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1); + StackFrameSP older_frame_sp = thread.GetStackFrameAtIndex(1); // But if we can't even unwind one frame we should just get out // of here & stop... @@ -280,20 +277,18 @@ bool ThreadPlanStepUntil::DoWillResume(StateType resume_state, bool current_plan) { if (current_plan) { - TargetSP target_sp(m_thread.CalculateTarget()); - if (target_sp) { - Breakpoint *return_bp = - target_sp->GetBreakpointByID(m_return_bp_id).get(); - if (return_bp != nullptr) - return_bp->SetEnabled(true); + Target &target = GetTarget(); + Breakpoint *return_bp = + target.GetBreakpointByID(m_return_bp_id).get(); + if (return_bp != nullptr) + return_bp->SetEnabled(true); - until_collection::iterator pos, end = m_until_points.end(); - for (pos = m_until_points.begin(); pos != end; pos++) { - Breakpoint *until_bp = - target_sp->GetBreakpointByID((*pos).second).get(); - if (until_bp != nullptr) - until_bp->SetEnabled(true); - } + until_collection::iterator pos, end = m_until_points.end(); + for (pos = m_until_points.begin(); pos != end; pos++) { + Breakpoint *until_bp = + target.GetBreakpointByID((*pos).second).get(); + if (until_bp != nullptr) + until_bp->SetEnabled(true); } } @@ -304,18 +299,16 @@ } bool ThreadPlanStepUntil::WillStop() { - TargetSP target_sp(m_thread.CalculateTarget()); - if (target_sp) { - Breakpoint *return_bp = target_sp->GetBreakpointByID(m_return_bp_id).get(); - if (return_bp != nullptr) - return_bp->SetEnabled(false); - - until_collection::iterator pos, end = m_until_points.end(); - for (pos = m_until_points.begin(); pos != end; pos++) { - Breakpoint *until_bp = target_sp->GetBreakpointByID((*pos).second).get(); - if (until_bp != nullptr) - until_bp->SetEnabled(false); - } + Target &target = GetTarget(); + Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get(); + if (return_bp != nullptr) + return_bp->SetEnabled(false); + + until_collection::iterator pos, end = m_until_points.end(); + for (pos = m_until_points.begin(); pos != end; pos++) { + Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get(); + if (until_bp != nullptr) + until_bp->SetEnabled(false); } return true; } Index: lldb/source/Target/ThreadPlanStepThrough.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepThrough.cpp +++ lldb/source/Target/ThreadPlanStepThrough.cpp @@ -44,21 +44,21 @@ // some inlined code that we're in the middle of by doing this, but it's // easier than trying to figure out where the inlined code might return to. - StackFrameSP return_frame_sp = m_thread.GetFrameWithStackID(m_stack_id); + StackFrameSP return_frame_sp = thread.GetFrameWithStackID(m_stack_id); if (return_frame_sp) { m_backstop_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress( - m_thread.CalculateTarget().get()); + thread.CalculateTarget().get()); Breakpoint *return_bp = - m_thread.GetProcess() - ->GetTarget() + m_process + .GetTarget() .CreateBreakpoint(m_backstop_addr, true, false) .get(); if (return_bp != nullptr) { if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) m_could_not_resolve_hw_bp = true; - return_bp->SetThreadID(m_thread.GetID()); + return_bp->SetThreadID(m_tid); m_backstop_bkpt_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-through-backstop"); } @@ -79,18 +79,19 @@ } void ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC() { - DynamicLoader *loader = m_thread.GetProcess()->GetDynamicLoader(); + Thread &thread = GetThread(); + DynamicLoader *loader = thread.GetProcess()->GetDynamicLoader(); if (loader) m_sub_plan_sp = - loader->GetStepThroughTrampolinePlan(m_thread, m_stop_others); + loader->GetStepThroughTrampolinePlan(thread, m_stop_others); // If the DynamicLoader was unable to provide us with a ThreadPlan, then we // try the LanguageRuntimes. if (!m_sub_plan_sp) { for (LanguageRuntime *runtime : - m_thread.GetProcess()->GetLanguageRuntimes()) { + m_process.GetLanguageRuntimes()) { m_sub_plan_sp = - runtime->GetStepThroughTrampolinePlan(m_thread, m_stop_others); + runtime->GetStepThroughTrampolinePlan(thread, m_stop_others); if (m_sub_plan_sp) break; @@ -223,7 +224,7 @@ void ThreadPlanStepThrough::ClearBackstopBreakpoint() { if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) { - m_thread.GetProcess()->GetTarget().RemoveBreakpointByID(m_backstop_bkpt_id); + m_process.GetTarget().RemoveBreakpointByID(m_backstop_bkpt_id); m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID; m_could_not_resolve_hw_bp = false; } @@ -244,15 +245,16 @@ } bool ThreadPlanStepThrough::HitOurBackstopBreakpoint() { - StopInfoSP stop_info_sp(m_thread.GetStopInfo()); + Thread &thread = GetThread(); + StopInfoSP stop_info_sp(thread.GetStopInfo()); if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint) { break_id_t stop_value = (break_id_t)stop_info_sp->GetValue(); BreakpointSiteSP cur_site_sp = - m_thread.GetProcess()->GetBreakpointSiteList().FindByID(stop_value); + m_process.GetBreakpointSiteList().FindByID(stop_value); if (cur_site_sp && cur_site_sp->IsBreakpointAtThisSite(m_backstop_bkpt_id)) { StackID cur_frame_zero_id = - m_thread.GetStackFrameAtIndex(0)->GetStackID(); + thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_zero_id == m_return_stack_id) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); Index: lldb/source/Target/ThreadPlanStepRange.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepRange.cpp +++ lldb/source/Target/ThreadPlanStepRange.cpp @@ -41,8 +41,8 @@ m_given_ranges_only(given_ranges_only) { m_use_fast_step = GetTarget().GetUseFastStepping(); AddRange(range); - m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); - StackFrameSP parent_stack = m_thread.GetStackFrameAtIndex(1); + m_stack_id = thread.GetStackFrameAtIndex(0)->GetStackID(); + StackFrameSP parent_stack = thread.GetStackFrameAtIndex(1); if (parent_stack) m_parent_stack_id = parent_stack->GetStackID(); } @@ -86,14 +86,15 @@ } void ThreadPlanStepRange::DumpRanges(Stream *s) { + Thread &thread = GetThread(); size_t num_ranges = m_address_ranges.size(); if (num_ranges == 1) { - m_address_ranges[0].Dump(s, m_thread.CalculateTarget().get(), + m_address_ranges[0].Dump(s, &GetTarget(), Address::DumpStyleLoadAddress); } else { for (size_t i = 0; i < num_ranges; i++) { s->Printf(" %" PRIu64 ": ", uint64_t(i)); - m_address_ranges[i].Dump(s, m_thread.CalculateTarget().get(), + m_address_ranges[i].Dump(s, &GetTarget(), Address::DumpStyleLoadAddress); } } @@ -102,20 +103,20 @@ bool ThreadPlanStepRange::InRange() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); bool ret_value = false; - - lldb::addr_t pc_load_addr = m_thread.GetRegisterContext()->GetPC(); + Thread &thread = GetThread(); + lldb::addr_t pc_load_addr = thread.GetRegisterContext()->GetPC(); size_t num_ranges = m_address_ranges.size(); for (size_t i = 0; i < num_ranges; i++) { ret_value = m_address_ranges[i].ContainsLoadAddress( - pc_load_addr, m_thread.CalculateTarget().get()); + pc_load_addr, &GetTarget()); if (ret_value) break; } if (!ret_value && !m_given_ranges_only) { // See if we've just stepped to another part of the same line number... - StackFrame *frame = m_thread.GetStackFrameAtIndex(0).get(); + StackFrame *frame = thread.GetStackFrameAtIndex(0).get(); SymbolContext new_context( frame->GetSymbolContext(eSymbolContextEverything)); @@ -132,7 +133,7 @@ ret_value = true; if (log) { StreamString s; - m_addr_context.line_entry.Dump(&s, m_thread.CalculateTarget().get(), + m_addr_context.line_entry.Dump(&s, &GetTarget(), true, Address::DumpStyleLoadAddress, Address::DumpStyleLoadAddress, true); @@ -151,7 +152,7 @@ ret_value = true; if (log) { StreamString s; - m_addr_context.line_entry.Dump(&s, m_thread.CalculateTarget().get(), + m_addr_context.line_entry.Dump(&s, &GetTarget(), true, Address::DumpStyleLoadAddress, Address::DumpStyleLoadAddress, true); @@ -161,7 +162,7 @@ s.GetData()); } } else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress( - m_thread.CalculateTarget().get()) != pc_load_addr) { + &GetTarget()) != pc_load_addr) { // Another thing that sometimes happens here is that we step out of // one line into the MIDDLE of another line. So far I mostly see // this due to bugs in the debug information. But we probably don't @@ -174,7 +175,7 @@ ret_value = true; if (log) { StreamString s; - m_addr_context.line_entry.Dump(&s, m_thread.CalculateTarget().get(), + m_addr_context.line_entry.Dump(&s, &GetTarget(), true, Address::DumpStyleLoadAddress, Address::DumpStyleLoadAddress, true); @@ -195,14 +196,14 @@ } bool ThreadPlanStepRange::InSymbol() { - lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t cur_pc = GetThread().GetRegisterContext()->GetPC(); if (m_addr_context.function != nullptr) { return m_addr_context.function->GetAddressRange().ContainsLoadAddress( - cur_pc, m_thread.CalculateTarget().get()); + cur_pc, &GetTarget()); } else if (m_addr_context.symbol && m_addr_context.symbol->ValueIsAddress()) { AddressRange range(m_addr_context.symbol->GetAddressRef(), m_addr_context.symbol->GetByteSize()); - return range.ContainsLoadAddress(cur_pc, m_thread.CalculateTarget().get()); + return range.ContainsLoadAddress(cur_pc, &GetTarget()); } return false; } @@ -216,15 +217,15 @@ lldb::FrameComparison ThreadPlanStepRange::CompareCurrentFrameToStartFrame() { FrameComparison frame_order; - - StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + Thread &thread = GetThread(); + StackID cur_frame_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_id == m_stack_id) { frame_order = eFrameCompareEqual; } else if (cur_frame_id < m_stack_id) { frame_order = eFrameCompareYounger; } else { - StackFrameSP cur_parent_frame = m_thread.GetStackFrameAtIndex(1); + StackFrameSP cur_parent_frame = thread.GetStackFrameAtIndex(1); StackID cur_parent_id; if (cur_parent_frame) cur_parent_id = cur_parent_frame->GetStackID(); @@ -378,10 +379,10 @@ "breakpoint %d (site %d) to run to address 0x%" PRIx64, m_next_branch_bp_sp->GetID(), bp_site_id, run_to_address.GetLoadAddress( - &m_thread.GetProcess()->GetTarget())); + &m_process.GetTarget())); } - m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); + m_next_branch_bp_sp->SetThreadID(m_tid); m_next_branch_bp_sp->SetBreakpointKind("next-branch-location"); return true; @@ -400,7 +401,7 @@ break_id_t bp_site_id = stop_info_sp->GetValue(); BreakpointSiteSP bp_site_sp = - m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id); + m_process.GetBreakpointSiteList().FindByID(bp_site_id); if (!bp_site_sp) return false; else if (!bp_site_sp->IsBreakpointAtThisSite(m_next_branch_bp_sp->GetID())) @@ -487,11 +488,11 @@ // check that we are in the same symbol. if (!InRange()) { // Set plan Complete when we reach next instruction just after the range - lldb::addr_t addr = m_thread.GetRegisterContext()->GetPC() - 1; + lldb::addr_t addr = GetThread().GetRegisterContext()->GetPC() - 1; size_t num_ranges = m_address_ranges.size(); for (size_t i = 0; i < num_ranges; i++) { bool in_range = m_address_ranges[i].ContainsLoadAddress( - addr, m_thread.CalculateTarget().get()); + addr, &GetTarget()); if (in_range) { SetPlanComplete(); } Index: lldb/source/Target/ThreadPlanStepOverRange.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepOverRange.cpp +++ lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -85,7 +85,7 @@ avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug(); + avoid_nodebug = GetThread().GetStepOutAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -125,12 +125,13 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Thread &thread = GetThread(); if (log) { StreamString s; DumpAddress( - s.AsRawOstream(), m_thread.GetRegisterContext()->GetPC(), - m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); + s.AsRawOstream(), thread.GetRegisterContext()->GetPC(), + GetTarget().GetArchitecture().GetAddressByteSize()); LLDB_LOGF(log, "ThreadPlanStepOverRange reached %s.", s.GetData()); } @@ -151,8 +152,8 @@ // because the trampoline confused the backtracer. As below, we step // through first, and then try to figure out how to get back out again. - new_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, - stop_others, m_status); + new_plan_sp = thread.QueueThreadPlanForStepThrough(m_stack_id, false, + stop_others, m_status); if (new_plan_sp && log) LLDB_LOGF(log, @@ -161,7 +162,7 @@ // Make sure we really are in a new frame. Do that by unwinding and seeing // if the start function really is our start function... for (uint32_t i = 1;; ++i) { - StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(i); + StackFrameSP older_frame_sp = thread.GetStackFrameAtIndex(i); if (!older_frame_sp) { // We can't unwind the next frame we should just get out of here & // stop... @@ -171,12 +172,12 @@ const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything); if (IsEquivalentContext(older_context)) { - new_plan_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop( + new_plan_sp = thread.QueueThreadPlanForStepOutNoShouldStop( false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0, m_status, true); break; } else { - new_plan_sp = m_thread.QueueThreadPlanForStepThrough( + new_plan_sp = thread.QueueThreadPlanForStepThrough( m_stack_id, false, stop_others, m_status); // If we found a way through, then we should stop recursing. if (new_plan_sp) @@ -196,7 +197,7 @@ // we are in a stub then it's likely going to be hard to get out from // here. It is probably easiest to step into the stub, and then it will // be straight-forward to step out. - new_plan_sp = m_thread.QueueThreadPlanForStepThrough( + new_plan_sp = thread.QueueThreadPlanForStepThrough( m_stack_id, false, stop_others, m_status); } else { // The current clang (at least through 424) doesn't always get the @@ -212,7 +213,7 @@ if (m_addr_context.line_entry.IsValid()) { SymbolContext sc; - StackFrameSP frame_sp = m_thread.GetStackFrameAtIndex(0); + StackFrameSP frame_sp = thread.GetStackFrameAtIndex(0); sc = frame_sp->GetSymbolContext(eSymbolContextEverything); if (sc.line_entry.IsValid()) { if (sc.line_entry.original_file != @@ -278,7 +279,7 @@ m_addr_context.line_entry.original_file) { const bool abort_other_plans = false; const RunMode stop_other_threads = RunMode::eAllThreads; - lldb::addr_t cur_pc = m_thread.GetStackFrameAtIndex(0) + lldb::addr_t cur_pc = thread.GetStackFrameAtIndex(0) ->GetRegisterContext() ->GetPC(); AddressRange step_range( @@ -286,7 +287,7 @@ next_line_address.GetLoadAddress(&GetTarget()) - cur_pc); - new_plan_sp = m_thread.QueueThreadPlanForStepOverRange( + new_plan_sp = thread.QueueThreadPlanForStepOverRange( abort_other_plans, step_range, sc, stop_other_threads, m_status); break; @@ -365,23 +366,24 @@ if (resume_state != eStateSuspended && m_first_resume) { m_first_resume = false; if (resume_state == eStateStepping && current_plan) { + Thread &thread = GetThread(); // See if we are about to step over an inlined call in the middle of the // inlined stack, if so figure out its extents and reset our range to // step over that. - bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth(); + bool in_inlined_stack = thread.DecrementCurrentInlinedDepth(); if (in_inlined_stack) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); LLDB_LOGF(log, "ThreadPlanStepInRange::DoWillResume: adjusting range to " "the frame at inlined depth %d.", - m_thread.GetCurrentInlinedDepth()); - StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0); + thread.GetCurrentInlinedDepth()); + StackFrameSP stack_sp = thread.GetStackFrameAtIndex(0); if (stack_sp) { Block *frame_block = stack_sp->GetFrameBlock(); - lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); AddressRange my_range; if (frame_block->GetRangeContainingLoadAddress( - curr_pc, m_thread.GetProcess()->GetTarget(), my_range)) { + curr_pc, m_process.GetTarget(), my_range)) { m_address_ranges.clear(); m_address_ranges.push_back(my_range); if (log) { Index: lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -30,9 +30,9 @@ m_auto_continue(false), m_reenabled_breakpoint_site(false) { - m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC(); + m_breakpoint_addr = thread.GetRegisterContext()->GetPC(); m_breakpoint_site_id = - m_thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress( + thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress( m_breakpoint_addr); } @@ -86,7 +86,7 @@ // Be careful, however, as we may have "seen a breakpoint under the PC // because we stopped without changing the PC, in which case we do want // to re-claim this stop so we'll try again. - lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC(); if (pc_addr == m_breakpoint_addr) { LLDB_LOGF(log, @@ -120,10 +120,10 @@ bool current_plan) { if (current_plan) { BreakpointSiteSP bp_site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress( + m_process.GetBreakpointSiteList().FindByAddress( m_breakpoint_addr)); if (bp_site_sp && bp_site_sp->IsEnabled()) { - m_thread.GetProcess()->DisableBreakpointSite(bp_site_sp.get()); + m_process.DisableBreakpointSite(bp_site_sp.get()); m_reenabled_breakpoint_site = false; } } @@ -140,7 +140,7 @@ } bool ThreadPlanStepOverBreakpoint::MischiefManaged() { - lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC(); if (pc_addr == m_breakpoint_addr) { // If we are still at the PC of our breakpoint, then for some reason we @@ -161,10 +161,10 @@ if (!m_reenabled_breakpoint_site) { m_reenabled_breakpoint_site = true; BreakpointSiteSP bp_site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress( + m_process.GetBreakpointSiteList().FindByAddress( m_breakpoint_addr)); if (bp_site_sp) { - m_thread.GetProcess()->EnableBreakpointSite(bp_site_sp.get()); + m_process.EnableBreakpointSite(bp_site_sp.get()); } } } @@ -181,5 +181,5 @@ } bool ThreadPlanStepOverBreakpoint::IsPlanStale() { - return m_thread.GetRegisterContext()->GetPC() != m_breakpoint_addr; + return GetThread().GetRegisterContext()->GetPC() != m_breakpoint_addr; } Index: lldb/source/Target/ThreadPlanStepOut.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepOut.cpp +++ lldb/source/Target/ThreadPlanStepOut.cpp @@ -47,13 +47,13 @@ SetFlagsToDefault(); SetupAvoidNoDebug(step_out_avoids_code_without_debug_info); - m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0); + m_step_from_insn = thread.GetRegisterContext()->GetPC(0); uint32_t return_frame_index = frame_idx + 1; StackFrameSP return_frame_sp( - m_thread.GetStackFrameAtIndex(return_frame_index)); + thread.GetStackFrameAtIndex(return_frame_index)); StackFrameSP immediate_return_from_sp( - m_thread.GetStackFrameAtIndex(frame_idx)); + thread.GetStackFrameAtIndex(frame_idx)); if (!return_frame_sp || !immediate_return_from_sp) return; // we can't do anything here. ValidatePlan() will return false. @@ -63,7 +63,7 @@ m_stepped_past_frames.push_back(return_frame_sp); ++return_frame_index; - return_frame_sp = m_thread.GetStackFrameAtIndex(return_frame_index); + return_frame_sp = thread.GetStackFrameAtIndex(return_frame_index); // We never expect to see an artificial frame without a regular ancestor. // If this happens, log the issue and defensively refuse to step out. @@ -85,7 +85,7 @@ // First queue a plan that gets us to this inlined frame, and when we get // there we'll queue a second plan that walks us out of this frame. m_step_out_to_inline_plan_sp = std::make_shared<ThreadPlanStepOut>( - m_thread, nullptr, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, + thread, nullptr, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx - 1, eLazyBoolNo, continue_to_next_branch); static_cast<ThreadPlanStepOut *>(m_step_out_to_inline_plan_sp.get()) ->SetShouldStopHereCallbacks(nullptr, nullptr); @@ -115,21 +115,21 @@ include_inlined_functions); if (range.GetByteSize() > 0) { return_address = - m_thread.GetProcess()->AdvanceAddressToNextBranchInstruction( + m_process.AdvanceAddressToNextBranchInstruction( return_address, range); } } } m_return_addr = - return_address.GetLoadAddress(&m_thread.GetProcess()->GetTarget()); + return_address.GetLoadAddress(&m_process.GetTarget()); if (m_return_addr == LLDB_INVALID_ADDRESS) return; // Perform some additional validation on the return address. uint32_t permissions = 0; - if (!m_thread.GetProcess()->GetLoadAddressPermissions(m_return_addr, - permissions)) { + if (!m_process.GetLoadAddressPermissions(m_return_addr, + permissions)) { LLDB_LOGF(log, "ThreadPlanStepOut(%p): Return address (0x%" PRIx64 ") permissions not found.", static_cast<void *>(this), m_return_addr); @@ -142,14 +142,13 @@ return; } - Breakpoint *return_bp = m_thread.CalculateTarget() - ->CreateBreakpoint(m_return_addr, true, false) - .get(); + Breakpoint *return_bp = GetTarget().CreateBreakpoint(m_return_addr, + true, false).get(); if (return_bp != nullptr) { if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) m_could_not_resolve_hw_bp = true; - return_bp->SetThreadID(m_thread.GetID()); + return_bp->SetThreadID(m_tid); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-out"); } @@ -175,7 +174,7 @@ avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug(); + avoid_nodebug = GetThread().GetStepOutAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -185,15 +184,16 @@ } void ThreadPlanStepOut::DidPush() { + Thread &thread = GetThread(); if (m_step_out_to_inline_plan_sp) - m_thread.QueueThreadPlan(m_step_out_to_inline_plan_sp, false); + thread.QueueThreadPlan(m_step_out_to_inline_plan_sp, false); else if (m_step_through_inline_plan_sp) - m_thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); + thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); } ThreadPlanStepOut::~ThreadPlanStepOut() { if (m_return_bp_id != LLDB_INVALID_BREAK_ID) - m_thread.CalculateTarget()->RemoveBreakpointByID(m_return_bp_id); + GetThread().CalculateTarget()->RemoveBreakpointByID(m_return_bp_id); } void ThreadPlanStepOut::GetDescription(Stream *s, @@ -293,12 +293,13 @@ // If this is OUR breakpoint, we're fine, otherwise we don't know why // this happened... BreakpointSiteSP site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByID( + m_process.GetBreakpointSiteList().FindByID( stop_info_sp->GetValue())); if (site_sp && site_sp->IsBreakpointAtThisSite(m_return_bp_id)) { bool done; - StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID frame_zero_id + = GetThread().GetStackFrameAtIndex(0)->GetStackID(); if (m_step_out_to_id == frame_zero_id) done = true; @@ -365,7 +366,7 @@ } if (!done) { - StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID frame_zero_id = GetThread().GetStackFrameAtIndex(0)->GetStackID(); done = !(frame_zero_id < m_step_out_to_id); } @@ -399,8 +400,7 @@ return false; if (current_plan) { - Breakpoint *return_bp = - m_thread.CalculateTarget()->GetBreakpointByID(m_return_bp_id).get(); + Breakpoint *return_bp = GetTarget().GetBreakpointByID(m_return_bp_id).get(); if (return_bp != nullptr) return_bp->SetEnabled(true); } @@ -409,8 +409,7 @@ bool ThreadPlanStepOut::WillStop() { if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { - Breakpoint *return_bp = - m_thread.CalculateTarget()->GetBreakpointByID(m_return_bp_id).get(); + Breakpoint *return_bp = GetTarget().GetBreakpointByID(m_return_bp_id).get(); if (return_bp != nullptr) return_bp->SetEnabled(false); } @@ -431,7 +430,7 @@ if (log) LLDB_LOGF(log, "Completed step out plan."); if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { - m_thread.CalculateTarget()->RemoveBreakpointByID(m_return_bp_id); + GetTarget().RemoveBreakpointByID(m_return_bp_id); m_return_bp_id = LLDB_INVALID_BREAK_ID; } @@ -446,7 +445,8 @@ // Now figure out the range of this inlined block, and set up a "step through // range" plan for that. If we've been provided with a context, then use the // block in that context. - StackFrameSP immediate_return_from_sp(m_thread.GetStackFrameAtIndex(0)); + Thread &thread = GetThread(); + StackFrameSP immediate_return_from_sp(thread.GetStackFrameAtIndex(0)); if (!immediate_return_from_sp) return false; @@ -473,7 +473,7 @@ m_step_through_inline_plan_sp = std::make_shared<ThreadPlanStepOverRange>( - m_thread, inline_range, inlined_sc, run_mode, avoid_no_debug); + thread, inline_range, inlined_sc, run_mode, avoid_no_debug); ThreadPlanStepOverRange *step_through_inline_plan_ptr = static_cast<ThreadPlanStepOverRange *>( m_step_through_inline_plan_sp.get()); @@ -493,7 +493,7 @@ } if (queue_now) - m_thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); + thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); return true; } } @@ -514,10 +514,10 @@ m_immediate_step_from_function->GetCompilerType() .GetFunctionReturnType(); if (return_compiler_type) { - lldb::ABISP abi_sp = m_thread.GetProcess()->GetABI(); + lldb::ABISP abi_sp = m_process.GetABI(); if (abi_sp) m_return_valobj_sp = - abi_sp->GetReturnValueObject(m_thread, return_compiler_type); + abi_sp->GetReturnValueObject(GetThread(), return_compiler_type); } } } @@ -526,6 +526,6 @@ // If we are still lower on the stack than the frame we are returning to, // then there's something for us to do. Otherwise, we're stale. - StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID frame_zero_id = GetThread().GetStackFrameAtIndex(0)->GetStackID(); return !(frame_zero_id < m_step_out_to_id); } Index: lldb/source/Target/ThreadPlanStepInstruction.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepInstruction.cpp +++ lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -36,14 +36,15 @@ ThreadPlanStepInstruction::~ThreadPlanStepInstruction() = default; void ThreadPlanStepInstruction::SetUpState() { - m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); - StackFrameSP start_frame_sp(m_thread.GetStackFrameAtIndex(0)); + Thread &thread = GetThread(); + m_instruction_addr = thread.GetRegisterContext()->GetPC(0); + StackFrameSP start_frame_sp(thread.GetStackFrameAtIndex(0)); m_stack_id = start_frame_sp->GetStackID(); m_start_has_symbol = start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != nullptr; - StackFrameSP parent_frame_sp = m_thread.GetStackFrameAtIndex(1); + StackFrameSP parent_frame_sp = thread.GetStackFrameAtIndex(1); if (parent_frame_sp) m_parent_frame_id = parent_frame_sp->GetStackID(); } @@ -95,18 +96,19 @@ bool ThreadPlanStepInstruction::IsPlanStale() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + Thread &thread = GetThread(); + StackID cur_frame_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_id == m_stack_id) { // Set plan Complete when we reach next instruction - uint64_t pc = m_thread.GetRegisterContext()->GetPC(0); - uint32_t max_opcode_size = m_thread.CalculateTarget() - ->GetArchitecture().GetMaximumOpcodeByteSize(); + uint64_t pc = thread.GetRegisterContext()->GetPC(0); + uint32_t max_opcode_size + = GetTarget().GetArchitecture().GetMaximumOpcodeByteSize(); bool next_instruction_reached = (pc > m_instruction_addr) && (pc <= m_instruction_addr + max_opcode_size); if (next_instruction_reached) { SetPlanComplete(); } - return (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr); + return (thread.GetRegisterContext()->GetPC(0) != m_instruction_addr); } else if (cur_frame_id < m_stack_id) { // If the current frame is younger than the start frame and we are stepping // over, then we need to continue, but if we are doing just one step, we're @@ -123,10 +125,10 @@ } bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { + Thread &thread = GetThread(); if (m_step_over) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - - StackFrameSP cur_frame_sp = m_thread.GetStackFrameAtIndex(0); + StackFrameSP cur_frame_sp = thread.GetStackFrameAtIndex(0); if (!cur_frame_sp) { LLDB_LOGF( log, @@ -138,7 +140,7 @@ StackID cur_frame_zero_id = cur_frame_sp->GetStackID(); if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id) { - if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) { + if (thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) { if (--m_iteration_count <= 0) { SetPlanComplete(); return true; @@ -152,7 +154,7 @@ return false; } else { // We've stepped in, step back out again: - StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); + StackFrame *return_frame = thread.GetStackFrameAtIndex(1).get(); if (return_frame) { if (return_frame->GetStackID() != m_parent_frame_id || m_start_has_symbol) { @@ -162,7 +164,7 @@ if (cur_frame_sp->IsInlined()) { StackFrameSP parent_frame_sp = - m_thread.GetFrameWithStackID(m_stack_id); + thread.GetFrameWithStackID(m_stack_id); if (parent_frame_sp && parent_frame_sp->GetConcreteFrameIndex() == @@ -181,24 +183,20 @@ StreamString s; s.PutCString("Stepped in to: "); addr_t stop_addr = - m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); + thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); DumpAddress(s.AsRawOstream(), stop_addr, - m_thread.CalculateTarget() - ->GetArchitecture() - .GetAddressByteSize()); + GetTarget().GetArchitecture().GetAddressByteSize()); s.PutCString(" stepping out to: "); addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); DumpAddress(s.AsRawOstream(), return_addr, - m_thread.CalculateTarget() - ->GetArchitecture() - .GetAddressByteSize()); + GetTarget().GetArchitecture().GetAddressByteSize()); LLDB_LOGF(log, "%s.", s.GetData()); } // StepInstruction should probably have the tri-state RunMode, but // for now it is safer to run others. const bool stop_others = false; - m_thread.QueueThreadPlanForStepOutNoShouldStop( + thread.QueueThreadPlanForStepOutNoShouldStop( false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0, m_status); return false; @@ -219,7 +217,7 @@ } } } else { - lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(0); + lldb::addr_t pc_addr = thread.GetRegisterContext()->GetPC(0); if (pc_addr != m_instruction_addr) { if (--m_iteration_count <= 0) { SetPlanComplete(); Index: lldb/source/Target/ThreadPlanStepInRange.cpp =================================================================== --- lldb/source/Target/ThreadPlanStepInRange.cpp +++ lldb/source/Target/ThreadPlanStepInRange.cpp @@ -69,7 +69,7 @@ LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info) { bool avoid_nodebug = true; - + Thread &thread = GetThread(); switch (step_in_avoids_code_without_debug_info) { case eLazyBoolYes: avoid_nodebug = true; @@ -78,7 +78,7 @@ avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepInAvoidsNoDebug(); + avoid_nodebug = thread.GetStepInAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -94,7 +94,7 @@ avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug(); + avoid_nodebug = thread.GetStepOutAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -145,9 +145,8 @@ if (log) { StreamString s; - DumpAddress( - s.AsRawOstream(), m_thread.GetRegisterContext()->GetPC(), - m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); + DumpAddress(s.AsRawOstream(), GetThread().GetRegisterContext()->GetPC(), + GetTarget().GetArchitecture().GetAddressByteSize()); LLDB_LOGF(log, "ThreadPlanStepInRange reached %s.", s.GetData()); } @@ -180,6 +179,7 @@ FrameComparison frame_order = CompareCurrentFrameToStartFrame(); + Thread &thread = GetThread(); if (frame_order == eFrameCompareOlder || frame_order == eFrameCompareSameParent) { // If we're in an older frame then we should stop. @@ -189,7 +189,7 @@ // I'm going to make the assumption that you wouldn't RETURN to a // trampoline. So if we are in a trampoline we think the frame is older // because the trampoline confused the backtracer. - m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough( + m_sub_plan_sp = thread.QueueThreadPlanForStepThrough( m_stack_id, false, stop_others, m_status); if (!m_sub_plan_sp) { // Otherwise check the ShouldStopHere for step out: @@ -233,7 +233,7 @@ // We may have set the plan up above in the FrameIsOlder section: if (!m_sub_plan_sp) - m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough( + m_sub_plan_sp = thread.QueueThreadPlanForStepThrough( m_stack_id, false, stop_others, m_status); if (log) { @@ -254,10 +254,10 @@ if (!m_sub_plan_sp && frame_order == eFrameCompareYounger && m_step_past_prologue) { - lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0); + lldb::StackFrameSP curr_frame = thread.GetStackFrameAtIndex(0); if (curr_frame) { size_t bytes_to_skip = 0; - lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t curr_addr = thread.GetRegisterContext()->GetPC(); Address func_start_address; SymbolContext sc = curr_frame->GetSymbolContext(eSymbolContextFunction | @@ -266,24 +266,21 @@ if (sc.function) { func_start_address = sc.function->GetAddressRange().GetBaseAddress(); if (curr_addr == - func_start_address.GetLoadAddress( - m_thread.CalculateTarget().get())) + func_start_address.GetLoadAddress(&GetTarget())) bytes_to_skip = sc.function->GetPrologueByteSize(); } else if (sc.symbol) { func_start_address = sc.symbol->GetAddress(); if (curr_addr == - func_start_address.GetLoadAddress( - m_thread.CalculateTarget().get())) + func_start_address.GetLoadAddress(&GetTarget())) bytes_to_skip = sc.symbol->GetPrologueByteSize(); } if (bytes_to_skip == 0 && sc.symbol) { - TargetSP target = m_thread.CalculateTarget(); - const Architecture *arch = target->GetArchitecturePlugin(); + const Architecture *arch = GetTarget().GetArchitecturePlugin(); if (arch) { Address curr_sec_addr; - target->GetSectionLoadList().ResolveLoadAddress(curr_addr, - curr_sec_addr); + GetTarget().GetSectionLoadList().ResolveLoadAddress(curr_addr, + curr_sec_addr); bytes_to_skip = arch->GetBytesToSkip(*sc.symbol, curr_sec_addr); } } @@ -293,7 +290,7 @@ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP); LLDB_LOGF(log, "Pushing past prologue "); - m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress( + m_sub_plan_sp = thread.QueueThreadPlanForRunToAddress( false, func_start_address, true, m_status); } } @@ -486,15 +483,16 @@ bool current_plan) { m_virtual_step = false; if (resume_state == eStateStepping && current_plan) { + Thread &thread = GetThread(); // See if we are about to step over a virtual inlined call. - bool step_without_resume = m_thread.DecrementCurrentInlinedDepth(); + bool step_without_resume = thread.DecrementCurrentInlinedDepth(); if (step_without_resume) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); LLDB_LOGF(log, "ThreadPlanStepInRange::DoWillResume: returning false, " "inline_depth: %d", - m_thread.GetCurrentInlinedDepth()); - SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread)); + thread.GetCurrentInlinedDepth()); + SetStopInfo(StopInfo::CreateStopReasonToTrace(thread)); // FIXME: Maybe it would be better to create a InlineStep stop reason, but // then Index: lldb/source/Target/ThreadPlanRunToAddress.cpp =================================================================== --- lldb/source/Target/ThreadPlanRunToAddress.cpp +++ lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -25,7 +25,7 @@ eVoteNoOpinion, eVoteNoOpinion), m_stop_others(stop_others), m_addresses(), m_break_ids() { m_addresses.push_back( - address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get())); + address.GetOpcodeLoadAddress(thread.CalculateTarget().get())); SetInitialBreakpoints(); } @@ -36,7 +36,7 @@ eVoteNoOpinion, eVoteNoOpinion), m_stop_others(stop_others), m_addresses(), m_break_ids() { m_addresses.push_back( - m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); + thread.CalculateTarget()->GetOpcodeLoadAddress(address)); SetInitialBreakpoints(); } @@ -62,14 +62,13 @@ for (size_t i = 0; i < num_addresses; i++) { Breakpoint *breakpoint; - breakpoint = m_thread.CalculateTarget() - ->CreateBreakpoint(m_addresses[i], true, false) - .get(); + breakpoint + = GetTarget().CreateBreakpoint(m_addresses[i], true, false).get(); if (breakpoint != nullptr) { if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations()) m_could_not_resolve_hw_bp = true; m_break_ids[i] = breakpoint->GetID(); - breakpoint->SetThreadID(m_thread.GetID()); + breakpoint->SetThreadID(m_tid); breakpoint->SetBreakpointKind("run-to-address"); } } @@ -78,7 +77,7 @@ ThreadPlanRunToAddress::~ThreadPlanRunToAddress() { size_t num_break_ids = m_break_ids.size(); for (size_t i = 0; i < num_break_ids; i++) { - m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); + GetTarget().RemoveBreakpointByID(m_break_ids[i]); } m_could_not_resolve_hw_bp = false; } @@ -119,7 +118,7 @@ DumpAddress(s->AsRawOstream(), m_addresses[i], sizeof(addr_t)); s->Printf(" using breakpoint: %d - ", m_break_ids[i]); Breakpoint *breakpoint = - m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get(); + GetTarget().GetBreakpointByID(m_break_ids[i]).get(); if (breakpoint) breakpoint->Dump(s); else @@ -178,7 +177,7 @@ for (size_t i = 0; i < num_break_ids; i++) { if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) { - m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); + GetTarget().RemoveBreakpointByID(m_break_ids[i]); m_break_ids[i] = LLDB_INVALID_BREAK_ID; } } @@ -190,7 +189,7 @@ } bool ThreadPlanRunToAddress::AtOurAddress() { - lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t current_address = GetThread().GetRegisterContext()->GetPC(); bool found_it = false; size_t num_addresses = m_addresses.size(); for (size_t i = 0; i < num_addresses; i++) { Index: lldb/source/Target/ThreadPlanPython.cpp =================================================================== --- lldb/source/Target/ThreadPlanPython.cpp +++ lldb/source/Target/ThreadPlanPython.cpp @@ -55,15 +55,16 @@ return true; } +ScriptInterpreter *ThreadPlanPython::GetScriptInterpreter() { + return m_process.GetTarget().GetDebugger().GetScriptInterpreter(); +} + void ThreadPlanPython::DidPush() { // We set up the script side in DidPush, so that it can push other plans in // the constructor, and doesn't have to care about the details of DidPush. m_did_push = true; if (!m_class_name.empty()) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { m_implementation_sp = script_interp->CreateScriptedThreadPlan( m_class_name.c_str(), m_args_data, m_error_str, @@ -79,10 +80,7 @@ bool should_stop = true; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; should_stop = script_interp->ScriptedThreadPlanShouldStop( @@ -101,10 +99,7 @@ bool is_stale = true; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp, @@ -123,10 +118,7 @@ bool explains_stop = true; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; explains_stop = script_interp->ScriptedThreadPlanExplainsStop( @@ -159,10 +151,7 @@ m_class_name.c_str()); lldb::StateType run_state = eStateRunning; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; run_state = script_interp->ScriptedThreadPlanGetRunState( Index: lldb/source/Target/ThreadPlanCallUserExpression.cpp =================================================================== --- lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -101,8 +101,7 @@ if (stop_info_sp) { lldb::addr_t addr = GetStopAddress(); - DynamicCheckerFunctions *checkers = - m_thread.GetProcess()->GetDynamicCheckers(); + DynamicCheckerFunctions *checkers = m_process.GetDynamicCheckers(); StreamString s; if (checkers && checkers->DoCheckersExplainStop(addr, s)) Index: lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp =================================================================== --- lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp +++ lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp @@ -49,20 +49,18 @@ if (level == eDescriptionLevelBrief) { s->Printf("Function call thread plan using ABI instead of JIT"); } else { - TargetSP target_sp(m_thread.CalculateTarget()); s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT", - m_function_addr.GetLoadAddress(target_sp.get())); + m_function_addr.GetLoadAddress(&GetTarget())); } } void ThreadPlanCallFunctionUsingABI::SetReturnValue() { - ProcessSP process_sp(m_thread.GetProcess()); - const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + const ABI *abi = m_process.GetABI().get(); // Ask the abi for the return value if (abi) { const bool persistent = false; m_return_valobj_sp = - abi->GetReturnValueObject(m_thread, m_return_type, persistent); + abi->GetReturnValueObject(GetThread(), m_return_type, persistent); } } Index: lldb/source/Target/ThreadPlanCallFunction.cpp =================================================================== --- lldb/source/Target/ThreadPlanCallFunction.cpp +++ lldb/source/Target/ThreadPlanCallFunction.cpp @@ -146,7 +146,7 @@ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log && log->GetVerbose()) { StreamString strm; - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); log->PutCString(message); @@ -178,19 +178,20 @@ } if (!m_takedown_done) { + Thread &thread = GetThread(); if (success) { SetReturnValue(); } LLDB_LOGF(log, "ThreadPlanCallFunction(%p): DoTakedown called for thread " "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", - static_cast<void *>(this), m_thread.GetID(), m_valid, + static_cast<void *>(this), m_tid, m_valid, IsPlanComplete()); m_takedown_done = true; m_stop_address = - m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); + thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); m_real_stop_info_sp = GetPrivateStopInfo(); - if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) { + if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) { LLDB_LOGF(log, "ThreadPlanCallFunction(%p): DoTakedown failed to restore " "register state", @@ -205,7 +206,7 @@ LLDB_LOGF(log, "ThreadPlanCallFunction(%p): DoTakedown called as no-op for " "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", - static_cast<void *>(this), m_thread.GetID(), m_valid, + static_cast<void *>(this), m_tid, m_valid, IsPlanComplete()); } } @@ -216,9 +217,8 @@ if (level == eDescriptionLevelBrief) { s->Printf("Function call thread plan"); } else { - TargetSP target_sp(m_thread.CalculateTarget()); s->Printf("Thread plan to call 0x%" PRIx64, - m_function_addr.GetLoadAddress(target_sp.get())); + m_function_addr.GetLoadAddress(&GetTarget())); } } @@ -283,11 +283,9 @@ // m_ignore_breakpoints. if (stop_reason == eStopReasonBreakpoint) { - ProcessSP process_sp(m_thread.CalculateProcess()); uint64_t break_site_id = m_real_stop_info_sp->GetValue(); BreakpointSiteSP bp_site_sp; - if (process_sp) - bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); + bp_site_sp = m_process.GetBreakpointSiteList().FindByID(break_site_id); if (bp_site_sp) { uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); bool is_internal = true; @@ -374,10 +372,11 @@ GetThread().SetStopInfoToNothing(); #ifndef SINGLE_STEP_EXPRESSIONS + Thread &thread = GetThread(); m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>( - m_thread, m_start_addr, m_stop_other_threads); + thread, m_start_addr, m_stop_other_threads); - m_thread.QueueThreadPlan(m_subplan_sp, false); + thread.QueueThreadPlan(m_subplan_sp, false); m_subplan_sp->SetPrivate(true); #endif } @@ -399,11 +398,10 @@ } void ThreadPlanCallFunction::SetBreakpoints() { - ProcessSP process_sp(m_thread.CalculateProcess()); - if (m_trap_exceptions && process_sp) { + if (m_trap_exceptions) { m_cxx_language_runtime = - process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); - m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); + m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus); + m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC); if (m_cxx_language_runtime) { m_should_clear_cxx_exception_bp = @@ -463,11 +461,10 @@ } void ThreadPlanCallFunction::SetReturnValue() { - ProcessSP process_sp(m_thread.GetProcess()); - const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + const ABI *abi = m_process.GetABI().get(); if (abi && m_return_type.IsValid()) { const bool persistent = false; m_return_valobj_sp = - abi->GetReturnValueObject(m_thread, m_return_type, persistent); + abi->GetReturnValueObject(GetThread(), m_return_type, persistent); } } Index: lldb/source/Target/ThreadPlanBase.cpp =================================================================== --- lldb/source/Target/ThreadPlanBase.cpp +++ lldb/source/Target/ThreadPlanBase.cpp @@ -34,11 +34,11 @@ #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1 #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER - ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread)); + ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(thread)); #else ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread)); #endif - new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState()); + new_tracer_sp->EnableTracing(thread.GetTraceEnabledState()); SetThreadPlanTracer(new_tracer_sp); SetIsMasterPlan(true); } @@ -58,7 +58,7 @@ } Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) { - StopInfoSP stop_info_sp = m_thread.GetStopInfo(); + StopInfoSP stop_info_sp = GetThread().GetStopInfo(); if (stop_info_sp) { bool should_notify = stop_info_sp->ShouldNotify(event_ptr); if (should_notify) @@ -96,8 +96,8 @@ log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (breakpoint hit.)", - m_thread.GetID()); - m_thread.DiscardThreadPlans(false); + m_tid); + GetThread().DiscardThreadPlans(false); return true; } // If we aren't going to stop at this breakpoint, and it is internal, @@ -125,9 +125,8 @@ LLDB_LOGF( log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 - " (exception: %s)", - m_thread.GetID(), stop_info_sp->GetDescription()); - m_thread.DiscardThreadPlans(false); + " (exception: %s)", m_tid, stop_info_sp->GetDescription()); + GetThread().DiscardThreadPlans(false); return true; case eStopReasonExec: @@ -138,8 +137,8 @@ log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exec.)", - m_thread.GetID()); - m_thread.DiscardThreadPlans(false); + m_tid); + GetThread().DiscardThreadPlans(false); return true; case eStopReasonThreadExiting: @@ -148,9 +147,8 @@ LLDB_LOGF( log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 - " (signal: %s)", - m_thread.GetID(), stop_info_sp->GetDescription()); - m_thread.DiscardThreadPlans(false); + " (signal: %s)", m_tid, stop_info_sp->GetDescription()); + GetThread().DiscardThreadPlans(false); return true; } else { // We're not going to stop, but while we are here, let's figure out Index: lldb/source/Target/ThreadPlan.cpp =================================================================== --- lldb/source/Target/ThreadPlan.cpp +++ lldb/source/Target/ThreadPlan.cpp @@ -21,9 +21,10 @@ // ThreadPlan constructor ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) - : m_thread(thread), m_stop_vote(stop_vote), m_run_vote(run_vote), + : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), + m_stop_vote(stop_vote), m_run_vote(run_vote), m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false), - m_kind(kind), m_name(name), m_plan_complete_mutex(), + m_kind(kind), m_thread(&thread), m_name(name), m_plan_complete_mutex(), m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false), m_plan_private(false), m_okay_to_discard(true), m_is_master_plan(false), m_plan_succeeded(true) { @@ -33,6 +34,15 @@ // Destructor ThreadPlan::~ThreadPlan() = default; +Thread &ThreadPlan::GetThread() { + if (m_thread) + return *m_thread; + + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid); + m_thread = thread_sp.get(); + return *m_thread; +} + bool ThreadPlan::PlanExplainsStop(Event *event_ptr) { if (m_cached_plan_explains_stop == eLazyBoolCalculate) { bool actual_value = DoPlanExplainsStop(event_ptr); @@ -103,7 +113,7 @@ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log) { - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); assert(reg_ctx); addr_t pc = reg_ctx->GetPC(); addr_t sp = reg_ctx->GetSP(); @@ -113,8 +123,9 @@ "%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", " "plan = '%s', state = %s, stop others = %d", - __FUNCTION__, m_thread.GetIndexID(), static_cast<void *>(&m_thread), - m_thread.GetID(), static_cast<uint64_t>(pc), + __FUNCTION__, GetThread().GetIndexID(), + static_cast<void *>(&GetThread()), + m_tid, static_cast<uint64_t>(pc), static_cast<uint64_t>(sp), static_cast<uint64_t>(fp), m_name.c_str(), StateAsCString(resume_state), StopOthers()); } @@ -174,14 +185,14 @@ fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, + GetThread().GetProtocolID()); #endif return true; } @@ -191,14 +202,14 @@ fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, + GetThread().GetProtocolID()); #endif return true; } @@ -208,14 +219,14 @@ fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, + GetThread().GetProtocolID()); #endif return true; } @@ -231,8 +242,8 @@ if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, + GetThread().GetProtocolID()); #endif return true; } @@ -244,14 +255,13 @@ fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return false; } @@ -262,14 +272,14 @@ fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, + GetThread().GetProtocolID()); #endif return eStateRunning; } Index: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -48,15 +48,14 @@ // Setting up the memory space for the called function text might require // allocations, i.e. a nested function call. This needs to be done as a // PreResumeAction. - m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller, - (void *)this); + m_process.AddPreResumeAction(PreResumeInitializeFunctionCaller,(void *)this); } bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() { if (!m_func_sp) { DiagnosticManager diagnostics; m_args_addr = - m_trampoline_handler.SetupDispatchFunction(m_thread, m_input_values); + m_trampoline_handler.SetupDispatchFunction(GetThread(), m_input_values); if (m_args_addr == LLDB_INVALID_ADDRESS) { return false; @@ -68,7 +67,7 @@ options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); options.SetStopOthers(m_stop_others); - m_thread.CalculateExecutionContext(exc_ctx); + GetThread().CalculateExecutionContext(exc_ctx); m_func_sp = m_impl_function->GetThreadPlanToCallFunction( exc_ctx, m_args_addr, options, diagnostics); m_func_sp->SetOkayToDiscard(true); @@ -132,7 +131,7 @@ if (!m_run_to_sp) { Value target_addr_value; ExecutionContext exc_ctx; - m_thread.CalculateExecutionContext(exc_ctx); + GetThread().CalculateExecutionContext(exc_ctx); m_impl_function->FetchFunctionResults(exc_ctx, m_args_addr, target_addr_value); m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr); @@ -151,13 +150,13 @@ ", stopping.", target_addr); - SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext( + SymbolContext sc = GetThread().GetStackFrameAtIndex(0)->GetSymbolContext( eSymbolContextEverything); Status status; const bool abort_other_plans = false; const bool first_insn = true; const uint32_t frame_idx = 0; - m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop( + m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop( abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx, status); if (m_run_to_sp && status.Success()) @@ -180,10 +179,10 @@ // Extract the target address from the value: m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>( - m_thread, target_so_addr, m_stop_others); + GetThread(), target_so_addr, m_stop_others); PushPlan(m_run_to_sp); return false; - } else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) { + } else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) { // Third stage, work the run to target plan. SetPlanComplete(); return true; Index: lldb/include/lldb/Target/ThreadPlanPython.h =================================================================== --- lldb/include/lldb/Target/ThreadPlanPython.h +++ lldb/include/lldb/Target/ThreadPlanPython.h @@ -55,6 +55,8 @@ bool DoPlanExplainsStop(Event *event_ptr) override; lldb::StateType GetPlanRunState() override; + + ScriptInterpreter *GetScriptInterpreter(); private: std::string m_class_name; Index: lldb/include/lldb/Target/ThreadPlan.h =================================================================== --- lldb/include/lldb/Target/ThreadPlan.h +++ lldb/include/lldb/Target/ThreadPlan.h @@ -369,13 +369,11 @@ /// /// \return /// A pointer to the thread plan's owning thread. - Thread &GetThread() { return m_thread; } + Thread &GetThread(); - const Thread &GetThread() const { return m_thread; } + Target &GetTarget() { return m_process.GetTarget(); } - Target &GetTarget() { return m_thread.GetProcess()->GetTarget(); } - - const Target &GetTarget() const { return m_thread.GetProcess()->GetTarget(); } + const Target &GetTarget() const { return m_process.GetTarget(); } /// Print a description of this thread to the stream \a s. /// \a thread. @@ -464,7 +462,7 @@ // Also sets the plans to private and not master plans. A plan pushed by // another thread plan is never either of the above. void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { - m_thread.PushPlan(thread_plan_sp); + GetThread().PushPlan(thread_plan_sp); thread_plan_sp->SetPrivate(false); thread_plan_sp->SetIsMasterPlan(false); } @@ -497,7 +495,9 @@ // original stop reason so that stopping and calling a few functions won't // lose the history of the run. This call can be implemented to get you back // to the real stop info. - virtual lldb::StopInfoSP GetRealStopInfo() { return m_thread.GetStopInfo(); } + virtual lldb::StopInfoSP GetRealStopInfo() { + return GetThread().GetStopInfo(); + } // If the completion of the thread plan stepped out of a function, the return // value of the function might have been captured by the thread plan @@ -560,17 +560,17 @@ // This is mostly a formal requirement, it allows us to make the Thread's // GetPreviousPlan protected, but only friend ThreadPlan to thread. - ThreadPlan *GetPreviousPlan() { return m_thread.GetPreviousPlan(this); } + ThreadPlan *GetPreviousPlan() { return GetThread().GetPreviousPlan(this); } // This forwards the private Thread::GetPrivateStopInfo which is generally // what ThreadPlan's need to know. lldb::StopInfoSP GetPrivateStopInfo() { - return m_thread.GetPrivateStopInfo(); + return GetThread().GetPrivateStopInfo(); } void SetStopInfo(lldb::StopInfoSP stop_reason_sp) { - m_thread.SetStopInfo(stop_reason_sp); + GetThread().SetStopInfo(stop_reason_sp); } void CachePlanExplainsStop(bool does_explain) { @@ -586,7 +586,8 @@ bool IsUsuallyUnexplainedStopReason(lldb::StopReason); Status m_status; - Thread &m_thread; + Process &m_process; + lldb::tid_t m_tid; Vote m_stop_vote; Vote m_run_vote; bool m_takes_iteration_count; @@ -597,6 +598,7 @@ // For ThreadPlan only static lldb::user_id_t GetNextID(); + Thread *m_thread; ThreadPlanKind m_kind; std::string m_name; std::recursive_mutex m_plan_complete_mutex;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits