15ffd83dbSDimitry Andric //===-- Thread.cpp --------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
100b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointLocation.h"
110b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
120b57cec5SDimitry Andric #include "lldb/Core/FormatEntity.h"
130b57cec5SDimitry Andric #include "lldb/Core/Module.h"
149dba64beSDimitry Andric #include "lldb/Core/StructuredDataImpl.h"
150b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
161fd87a68SDimitry Andric #include "lldb/Core/ValueObjectConstResult.h"
170b57cec5SDimitry Andric #include "lldb/Host/Host.h"
180b57cec5SDimitry Andric #include "lldb/Interpreter/OptionValueFileSpecList.h"
190b57cec5SDimitry Andric #include "lldb/Interpreter/OptionValueProperties.h"
200b57cec5SDimitry Andric #include "lldb/Interpreter/Property.h"
210b57cec5SDimitry Andric #include "lldb/Symbol/Function.h"
220b57cec5SDimitry Andric #include "lldb/Target/ABI.h"
230b57cec5SDimitry Andric #include "lldb/Target/DynamicLoader.h"
240b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
250b57cec5SDimitry Andric #include "lldb/Target/LanguageRuntime.h"
260b57cec5SDimitry Andric #include "lldb/Target/Process.h"
270b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
280b57cec5SDimitry Andric #include "lldb/Target/StackFrameRecognizer.h"
290b57cec5SDimitry Andric #include "lldb/Target/StopInfo.h"
300b57cec5SDimitry Andric #include "lldb/Target/SystemRuntime.h"
310b57cec5SDimitry Andric #include "lldb/Target/Target.h"
320b57cec5SDimitry Andric #include "lldb/Target/ThreadPlan.h"
330b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanBase.h"
340b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanCallFunction.h"
350b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanPython.h"
360b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanRunToAddress.h"
375ffd83dbSDimitry Andric #include "lldb/Target/ThreadPlanStack.h"
380b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepInRange.h"
390b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepInstruction.h"
400b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepOut.h"
410b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
420b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepOverRange.h"
430b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepThrough.h"
440b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepUntil.h"
450b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h"
465ffd83dbSDimitry Andric #include "lldb/Target/UnwindLLDB.h"
4781ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
480b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
490b57cec5SDimitry Andric #include "lldb/Utility/RegularExpression.h"
500b57cec5SDimitry Andric #include "lldb/Utility/State.h"
510b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
520b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
530b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric #include <memory>
56bdd1243dSDimitry Andric #include <optional>
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric using namespace lldb;
590b57cec5SDimitry Andric using namespace lldb_private;
600b57cec5SDimitry Andric 
GetGlobalProperties()61349cc55cSDimitry Andric ThreadProperties &Thread::GetGlobalProperties() {
620b57cec5SDimitry Andric   // NOTE: intentional leak so we don't crash if global destructor chain gets
630b57cec5SDimitry Andric   // called as other threads still use the result of this function
64349cc55cSDimitry Andric   static ThreadProperties *g_settings_ptr = new ThreadProperties(true);
65349cc55cSDimitry Andric   return *g_settings_ptr;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
689dba64beSDimitry Andric #define LLDB_PROPERTIES_thread
699dba64beSDimitry Andric #include "TargetProperties.inc"
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric enum {
729dba64beSDimitry Andric #define LLDB_PROPERTIES_thread
739dba64beSDimitry Andric #include "TargetPropertiesEnum.inc"
740b57cec5SDimitry Andric };
750b57cec5SDimitry Andric 
76fe6060f1SDimitry Andric class ThreadOptionValueProperties
77fe6060f1SDimitry Andric     : public Cloneable<ThreadOptionValueProperties, OptionValueProperties> {
780b57cec5SDimitry Andric public:
ThreadOptionValueProperties(llvm::StringRef name)79c9157d92SDimitry Andric   ThreadOptionValueProperties(llvm::StringRef name) : Cloneable(name) {}
800b57cec5SDimitry Andric 
81fe013be4SDimitry Andric   const Property *
GetPropertyAtIndex(size_t idx,const ExecutionContext * exe_ctx) const82fe013be4SDimitry Andric   GetPropertyAtIndex(size_t idx,
83fe013be4SDimitry Andric                      const ExecutionContext *exe_ctx) const override {
840b57cec5SDimitry Andric     // When getting the value for a key from the thread options, we will always
850b57cec5SDimitry Andric     // try and grab the setting from the current thread if there is one. Else
860b57cec5SDimitry Andric     // we just use the one from this instance.
870b57cec5SDimitry Andric     if (exe_ctx) {
880b57cec5SDimitry Andric       Thread *thread = exe_ctx->GetThreadPtr();
890b57cec5SDimitry Andric       if (thread) {
900b57cec5SDimitry Andric         ThreadOptionValueProperties *instance_properties =
910b57cec5SDimitry Andric             static_cast<ThreadOptionValueProperties *>(
920b57cec5SDimitry Andric                 thread->GetValueProperties().get());
930b57cec5SDimitry Andric         if (this != instance_properties)
940b57cec5SDimitry Andric           return instance_properties->ProtectedGetPropertyAtIndex(idx);
950b57cec5SDimitry Andric       }
960b57cec5SDimitry Andric     }
970b57cec5SDimitry Andric     return ProtectedGetPropertyAtIndex(idx);
980b57cec5SDimitry Andric   }
990b57cec5SDimitry Andric };
1000b57cec5SDimitry Andric 
ThreadProperties(bool is_global)1010b57cec5SDimitry Andric ThreadProperties::ThreadProperties(bool is_global) : Properties() {
1020b57cec5SDimitry Andric   if (is_global) {
103c9157d92SDimitry Andric     m_collection_sp = std::make_shared<ThreadOptionValueProperties>("thread");
1049dba64beSDimitry Andric     m_collection_sp->Initialize(g_thread_properties);
1050b57cec5SDimitry Andric   } else
106fe6060f1SDimitry Andric     m_collection_sp =
107349cc55cSDimitry Andric         OptionValueProperties::CreateLocalCopy(Thread::GetGlobalProperties());
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric ThreadProperties::~ThreadProperties() = default;
1110b57cec5SDimitry Andric 
GetSymbolsToAvoidRegexp()1120b57cec5SDimitry Andric const RegularExpression *ThreadProperties::GetSymbolsToAvoidRegexp() {
1130b57cec5SDimitry Andric   const uint32_t idx = ePropertyStepAvoidRegex;
114fe013be4SDimitry Andric   return GetPropertyAtIndexAs<const RegularExpression *>(idx);
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
GetLibrariesToAvoid() const1170b57cec5SDimitry Andric FileSpecList ThreadProperties::GetLibrariesToAvoid() const {
1180b57cec5SDimitry Andric   const uint32_t idx = ePropertyStepAvoidLibraries;
119fe013be4SDimitry Andric   return GetPropertyAtIndexAs<FileSpecList>(idx, {});
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
GetTraceEnabledState() const1220b57cec5SDimitry Andric bool ThreadProperties::GetTraceEnabledState() const {
1230b57cec5SDimitry Andric   const uint32_t idx = ePropertyEnableThreadTrace;
124fe013be4SDimitry Andric   return GetPropertyAtIndexAs<bool>(
125fe013be4SDimitry Andric       idx, g_thread_properties[idx].default_uint_value != 0);
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
GetStepInAvoidsNoDebug() const1280b57cec5SDimitry Andric bool ThreadProperties::GetStepInAvoidsNoDebug() const {
1290b57cec5SDimitry Andric   const uint32_t idx = ePropertyStepInAvoidsNoDebug;
130fe013be4SDimitry Andric   return GetPropertyAtIndexAs<bool>(
131fe013be4SDimitry Andric       idx, g_thread_properties[idx].default_uint_value != 0);
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
GetStepOutAvoidsNoDebug() const1340b57cec5SDimitry Andric bool ThreadProperties::GetStepOutAvoidsNoDebug() const {
1350b57cec5SDimitry Andric   const uint32_t idx = ePropertyStepOutAvoidsNoDebug;
136fe013be4SDimitry Andric   return GetPropertyAtIndexAs<bool>(
137fe013be4SDimitry Andric       idx, g_thread_properties[idx].default_uint_value != 0);
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
GetMaxBacktraceDepth() const1400b57cec5SDimitry Andric uint64_t ThreadProperties::GetMaxBacktraceDepth() const {
1410b57cec5SDimitry Andric   const uint32_t idx = ePropertyMaxBacktraceDepth;
142fe013be4SDimitry Andric   return GetPropertyAtIndexAs<uint64_t>(
143fe013be4SDimitry Andric       idx, g_thread_properties[idx].default_uint_value);
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric // Thread Event Data
1470b57cec5SDimitry Andric 
GetFlavorString()148fe013be4SDimitry Andric llvm::StringRef Thread::ThreadEventData::GetFlavorString() {
149fe013be4SDimitry Andric   return "Thread::ThreadEventData";
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
ThreadEventData(const lldb::ThreadSP thread_sp)1520b57cec5SDimitry Andric Thread::ThreadEventData::ThreadEventData(const lldb::ThreadSP thread_sp)
1530b57cec5SDimitry Andric     : m_thread_sp(thread_sp), m_stack_id() {}
1540b57cec5SDimitry Andric 
ThreadEventData(const lldb::ThreadSP thread_sp,const StackID & stack_id)1550b57cec5SDimitry Andric Thread::ThreadEventData::ThreadEventData(const lldb::ThreadSP thread_sp,
1560b57cec5SDimitry Andric                                          const StackID &stack_id)
1570b57cec5SDimitry Andric     : m_thread_sp(thread_sp), m_stack_id(stack_id) {}
1580b57cec5SDimitry Andric 
ThreadEventData()1590b57cec5SDimitry Andric Thread::ThreadEventData::ThreadEventData() : m_thread_sp(), m_stack_id() {}
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric Thread::ThreadEventData::~ThreadEventData() = default;
1620b57cec5SDimitry Andric 
Dump(Stream * s) const1630b57cec5SDimitry Andric void Thread::ThreadEventData::Dump(Stream *s) const {}
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric const Thread::ThreadEventData *
GetEventDataFromEvent(const Event * event_ptr)1660b57cec5SDimitry Andric Thread::ThreadEventData::GetEventDataFromEvent(const Event *event_ptr) {
1670b57cec5SDimitry Andric   if (event_ptr) {
1680b57cec5SDimitry Andric     const EventData *event_data = event_ptr->GetData();
1690b57cec5SDimitry Andric     if (event_data &&
1700b57cec5SDimitry Andric         event_data->GetFlavor() == ThreadEventData::GetFlavorString())
1710b57cec5SDimitry Andric       return static_cast<const ThreadEventData *>(event_ptr->GetData());
1720b57cec5SDimitry Andric   }
1730b57cec5SDimitry Andric   return nullptr;
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric 
GetThreadFromEvent(const Event * event_ptr)1760b57cec5SDimitry Andric ThreadSP Thread::ThreadEventData::GetThreadFromEvent(const Event *event_ptr) {
1770b57cec5SDimitry Andric   ThreadSP thread_sp;
1780b57cec5SDimitry Andric   const ThreadEventData *event_data = GetEventDataFromEvent(event_ptr);
1790b57cec5SDimitry Andric   if (event_data)
1800b57cec5SDimitry Andric     thread_sp = event_data->GetThread();
1810b57cec5SDimitry Andric   return thread_sp;
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
GetStackIDFromEvent(const Event * event_ptr)1840b57cec5SDimitry Andric StackID Thread::ThreadEventData::GetStackIDFromEvent(const Event *event_ptr) {
1850b57cec5SDimitry Andric   StackID stack_id;
1860b57cec5SDimitry Andric   const ThreadEventData *event_data = GetEventDataFromEvent(event_ptr);
1870b57cec5SDimitry Andric   if (event_data)
1880b57cec5SDimitry Andric     stack_id = event_data->GetStackID();
1890b57cec5SDimitry Andric   return stack_id;
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric StackFrameSP
GetStackFrameFromEvent(const Event * event_ptr)1930b57cec5SDimitry Andric Thread::ThreadEventData::GetStackFrameFromEvent(const Event *event_ptr) {
1940b57cec5SDimitry Andric   const ThreadEventData *event_data = GetEventDataFromEvent(event_ptr);
1950b57cec5SDimitry Andric   StackFrameSP frame_sp;
1960b57cec5SDimitry Andric   if (event_data) {
1970b57cec5SDimitry Andric     ThreadSP thread_sp = event_data->GetThread();
1980b57cec5SDimitry Andric     if (thread_sp) {
1990b57cec5SDimitry Andric       frame_sp = thread_sp->GetStackFrameList()->GetFrameWithStackID(
2000b57cec5SDimitry Andric           event_data->GetStackID());
2010b57cec5SDimitry Andric     }
2020b57cec5SDimitry Andric   }
2030b57cec5SDimitry Andric   return frame_sp;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric // Thread class
2070b57cec5SDimitry Andric 
GetStaticBroadcasterClass()2080b57cec5SDimitry Andric ConstString &Thread::GetStaticBroadcasterClass() {
2090b57cec5SDimitry Andric   static ConstString class_name("lldb.thread");
2100b57cec5SDimitry Andric   return class_name;
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
Thread(Process & process,lldb::tid_t tid,bool use_invalid_index_id)2130b57cec5SDimitry Andric Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id)
2140b57cec5SDimitry Andric     : ThreadProperties(false), UserID(tid),
2150b57cec5SDimitry Andric       Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(),
2160b57cec5SDimitry Andric                   Thread::GetStaticBroadcasterClass().AsCString()),
2170b57cec5SDimitry Andric       m_process_wp(process.shared_from_this()), m_stop_info_sp(),
2180b57cec5SDimitry Andric       m_stop_info_stop_id(0), m_stop_info_override_stop_id(0),
219bdd1243dSDimitry Andric       m_should_run_before_public_stop(false),
2200b57cec5SDimitry Andric       m_index_id(use_invalid_index_id ? LLDB_INVALID_INDEX32
2210b57cec5SDimitry Andric                                       : process.GetNextThreadIndexID(tid)),
2220b57cec5SDimitry Andric       m_reg_context_sp(), m_state(eStateUnloaded), m_state_mutex(),
2235ffd83dbSDimitry Andric       m_frame_mutex(), m_curr_frames_sp(), m_prev_frames_sp(),
2240b57cec5SDimitry Andric       m_resume_signal(LLDB_INVALID_SIGNAL_NUMBER),
2250b57cec5SDimitry Andric       m_resume_state(eStateRunning), m_temporary_resume_state(eStateRunning),
2260b57cec5SDimitry Andric       m_unwinder_up(), m_destroy_called(false),
2270b57cec5SDimitry Andric       m_override_should_notify(eLazyBoolCalculate),
2280b57cec5SDimitry Andric       m_extended_info_fetched(false), m_extended_info() {
22981ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Object);
2309dba64beSDimitry Andric   LLDB_LOGF(log, "%p Thread::Thread(tid = 0x%4.4" PRIx64 ")",
2310b57cec5SDimitry Andric             static_cast<void *>(this), GetID());
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   CheckInWithManager();
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
~Thread()2360b57cec5SDimitry Andric Thread::~Thread() {
23781ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Object);
2389dba64beSDimitry Andric   LLDB_LOGF(log, "%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")",
2390b57cec5SDimitry Andric             static_cast<void *>(this), GetID());
2400b57cec5SDimitry Andric   /// If you hit this assert, it means your derived class forgot to call
2410b57cec5SDimitry Andric   /// DoDestroy in its destructor.
2420b57cec5SDimitry Andric   assert(m_destroy_called);
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric 
DestroyThread()2450b57cec5SDimitry Andric void Thread::DestroyThread() {
2460b57cec5SDimitry Andric   m_destroy_called = true;
2470b57cec5SDimitry Andric   m_stop_info_sp.reset();
2480b57cec5SDimitry Andric   m_reg_context_sp.reset();
2490b57cec5SDimitry Andric   m_unwinder_up.reset();
2500b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
2510b57cec5SDimitry Andric   m_curr_frames_sp.reset();
2520b57cec5SDimitry Andric   m_prev_frames_sp.reset();
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
BroadcastSelectedFrameChange(StackID & new_frame_id)2550b57cec5SDimitry Andric void Thread::BroadcastSelectedFrameChange(StackID &new_frame_id) {
256*a58f00eaSDimitry Andric   if (EventTypeHasListeners(eBroadcastBitSelectedFrameChanged)) {
257*a58f00eaSDimitry Andric     auto data_sp =
258*a58f00eaSDimitry Andric         std::make_shared<ThreadEventData>(shared_from_this(), new_frame_id);
259*a58f00eaSDimitry Andric     BroadcastEvent(eBroadcastBitSelectedFrameChanged, data_sp);
260*a58f00eaSDimitry Andric   }
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric 
263fe013be4SDimitry Andric lldb::StackFrameSP
GetSelectedFrame(SelectMostRelevant select_most_relevant)264fe013be4SDimitry Andric Thread::GetSelectedFrame(SelectMostRelevant select_most_relevant) {
2650b57cec5SDimitry Andric   StackFrameListSP stack_frame_list_sp(GetStackFrameList());
2660b57cec5SDimitry Andric   StackFrameSP frame_sp = stack_frame_list_sp->GetFrameAtIndex(
267fe013be4SDimitry Andric       stack_frame_list_sp->GetSelectedFrameIndex(select_most_relevant));
2685ffd83dbSDimitry Andric   FrameSelectedCallback(frame_sp.get());
2690b57cec5SDimitry Andric   return frame_sp;
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
SetSelectedFrame(lldb_private::StackFrame * frame,bool broadcast)2720b57cec5SDimitry Andric uint32_t Thread::SetSelectedFrame(lldb_private::StackFrame *frame,
2730b57cec5SDimitry Andric                                   bool broadcast) {
2740b57cec5SDimitry Andric   uint32_t ret_value = GetStackFrameList()->SetSelectedFrame(frame);
2750b57cec5SDimitry Andric   if (broadcast)
2760b57cec5SDimitry Andric     BroadcastSelectedFrameChange(frame->GetStackID());
2775ffd83dbSDimitry Andric   FrameSelectedCallback(frame);
2780b57cec5SDimitry Andric   return ret_value;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric 
SetSelectedFrameByIndex(uint32_t frame_idx,bool broadcast)2810b57cec5SDimitry Andric bool Thread::SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast) {
2820b57cec5SDimitry Andric   StackFrameSP frame_sp(GetStackFrameList()->GetFrameAtIndex(frame_idx));
2830b57cec5SDimitry Andric   if (frame_sp) {
2840b57cec5SDimitry Andric     GetStackFrameList()->SetSelectedFrame(frame_sp.get());
2850b57cec5SDimitry Andric     if (broadcast)
2860b57cec5SDimitry Andric       BroadcastSelectedFrameChange(frame_sp->GetStackID());
2875ffd83dbSDimitry Andric     FrameSelectedCallback(frame_sp.get());
2880b57cec5SDimitry Andric     return true;
2890b57cec5SDimitry Andric   } else
2900b57cec5SDimitry Andric     return false;
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
SetSelectedFrameByIndexNoisily(uint32_t frame_idx,Stream & output_stream)2930b57cec5SDimitry Andric bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx,
2940b57cec5SDimitry Andric                                             Stream &output_stream) {
2950b57cec5SDimitry Andric   const bool broadcast = true;
2960b57cec5SDimitry Andric   bool success = SetSelectedFrameByIndex(frame_idx, broadcast);
2970b57cec5SDimitry Andric   if (success) {
298fe013be4SDimitry Andric     StackFrameSP frame_sp = GetSelectedFrame(DoNoSelectMostRelevantFrame);
2990b57cec5SDimitry Andric     if (frame_sp) {
3000b57cec5SDimitry Andric       bool already_shown = false;
3010b57cec5SDimitry Andric       SymbolContext frame_sc(
3020b57cec5SDimitry Andric           frame_sp->GetSymbolContext(eSymbolContextLineEntry));
303fe013be4SDimitry Andric       const Debugger &debugger = GetProcess()->GetTarget().GetDebugger();
304fe013be4SDimitry Andric       if (debugger.GetUseExternalEditor() && frame_sc.line_entry.file &&
305fe013be4SDimitry Andric           frame_sc.line_entry.line != 0) {
306fe013be4SDimitry Andric         if (llvm::Error e = Host::OpenFileInExternalEditor(
307fe013be4SDimitry Andric                 debugger.GetExternalEditor(), frame_sc.line_entry.file,
308fe013be4SDimitry Andric                 frame_sc.line_entry.line)) {
309fe013be4SDimitry Andric           LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e),
310fe013be4SDimitry Andric                          "OpenFileInExternalEditor failed: {0}");
311fe013be4SDimitry Andric         } else {
312fe013be4SDimitry Andric           already_shown = true;
313fe013be4SDimitry Andric         }
3140b57cec5SDimitry Andric       }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric       bool show_frame_info = true;
3170b57cec5SDimitry Andric       bool show_source = !already_shown;
3185ffd83dbSDimitry Andric       FrameSelectedCallback(frame_sp.get());
3190b57cec5SDimitry Andric       return frame_sp->GetStatus(output_stream, show_frame_info, show_source);
3200b57cec5SDimitry Andric     }
3210b57cec5SDimitry Andric     return false;
3220b57cec5SDimitry Andric   } else
3230b57cec5SDimitry Andric     return false;
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
FrameSelectedCallback(StackFrame * frame)3265ffd83dbSDimitry Andric void Thread::FrameSelectedCallback(StackFrame *frame) {
3275ffd83dbSDimitry Andric   if (!frame)
3285ffd83dbSDimitry Andric     return;
3295ffd83dbSDimitry Andric 
3305ffd83dbSDimitry Andric   if (frame->HasDebugInformation() &&
3315ffd83dbSDimitry Andric       (GetProcess()->GetWarningsOptimization() ||
3325ffd83dbSDimitry Andric        GetProcess()->GetWarningsUnsupportedLanguage())) {
3330b57cec5SDimitry Andric     SymbolContext sc =
3340b57cec5SDimitry Andric         frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextModule);
3350b57cec5SDimitry Andric     GetProcess()->PrintWarningOptimization(sc);
3365ffd83dbSDimitry Andric     GetProcess()->PrintWarningUnsupportedLanguage(sc);
3370b57cec5SDimitry Andric   }
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
GetStopInfo()3400b57cec5SDimitry Andric lldb::StopInfoSP Thread::GetStopInfo() {
3410b57cec5SDimitry Andric   if (m_destroy_called)
3420b57cec5SDimitry Andric     return m_stop_info_sp;
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   ThreadPlanSP completed_plan_sp(GetCompletedPlan());
3450b57cec5SDimitry Andric   ProcessSP process_sp(GetProcess());
3460b57cec5SDimitry Andric   const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX;
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   // Here we select the stop info according to priorirty: - m_stop_info_sp (if
3490b57cec5SDimitry Andric   // not trace) - preset value - completed plan stop info - new value with plan
3500b57cec5SDimitry Andric   // from completed plan stack - m_stop_info_sp (trace stop reason is OK now) -
3510b57cec5SDimitry Andric   // ask GetPrivateStopInfo to set stop info
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   bool have_valid_stop_info = m_stop_info_sp &&
3540b57cec5SDimitry Andric       m_stop_info_sp ->IsValid() &&
3550b57cec5SDimitry Andric       m_stop_info_stop_id == stop_id;
3560b57cec5SDimitry Andric   bool have_valid_completed_plan = completed_plan_sp && completed_plan_sp->PlanSucceeded();
3570b57cec5SDimitry Andric   bool plan_failed = completed_plan_sp && !completed_plan_sp->PlanSucceeded();
3580b57cec5SDimitry Andric   bool plan_overrides_trace =
3590b57cec5SDimitry Andric     have_valid_stop_info && have_valid_completed_plan
3600b57cec5SDimitry Andric     && (m_stop_info_sp->GetStopReason() == eStopReasonTrace);
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   if (have_valid_stop_info && !plan_overrides_trace && !plan_failed) {
3630b57cec5SDimitry Andric     return m_stop_info_sp;
3640b57cec5SDimitry Andric   } else if (completed_plan_sp) {
3650b57cec5SDimitry Andric     return StopInfo::CreateStopReasonWithPlan(
3660b57cec5SDimitry Andric         completed_plan_sp, GetReturnValueObject(), GetExpressionVariable());
3670b57cec5SDimitry Andric   } else {
3680b57cec5SDimitry Andric     GetPrivateStopInfo();
3690b57cec5SDimitry Andric     return m_stop_info_sp;
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric 
CalculatePublicStopInfo()3739dba64beSDimitry Andric void Thread::CalculatePublicStopInfo() {
3749dba64beSDimitry Andric   ResetStopInfo();
3759dba64beSDimitry Andric   SetStopInfo(GetStopInfo());
3769dba64beSDimitry Andric }
3779dba64beSDimitry Andric 
GetPrivateStopInfo(bool calculate)378bdd1243dSDimitry Andric lldb::StopInfoSP Thread::GetPrivateStopInfo(bool calculate) {
379bdd1243dSDimitry Andric   if (!calculate)
380bdd1243dSDimitry Andric     return m_stop_info_sp;
381bdd1243dSDimitry Andric 
3820b57cec5SDimitry Andric   if (m_destroy_called)
3830b57cec5SDimitry Andric     return m_stop_info_sp;
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   ProcessSP process_sp(GetProcess());
3860b57cec5SDimitry Andric   if (process_sp) {
3870b57cec5SDimitry Andric     const uint32_t process_stop_id = process_sp->GetStopID();
3880b57cec5SDimitry Andric     if (m_stop_info_stop_id != process_stop_id) {
389bdd1243dSDimitry Andric       // We preserve the old stop info for a variety of reasons:
390bdd1243dSDimitry Andric       // 1) Someone has already updated it by the time we get here
391bdd1243dSDimitry Andric       // 2) We didn't get to execute the breakpoint instruction we stopped at
392bdd1243dSDimitry Andric       // 3) This is a virtual step so we didn't actually run
393bdd1243dSDimitry Andric       // 4) If this thread wasn't allowed to run the last time round.
3940b57cec5SDimitry Andric       if (m_stop_info_sp) {
3950b57cec5SDimitry Andric         if (m_stop_info_sp->IsValid() || IsStillAtLastBreakpointHit() ||
396bdd1243dSDimitry Andric             GetCurrentPlan()->IsVirtualStep()
397bdd1243dSDimitry Andric             || GetTemporaryResumeState() == eStateSuspended)
3980b57cec5SDimitry Andric           SetStopInfo(m_stop_info_sp);
3990b57cec5SDimitry Andric         else
4000b57cec5SDimitry Andric           m_stop_info_sp.reset();
4010b57cec5SDimitry Andric       }
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric       if (!m_stop_info_sp) {
4040b57cec5SDimitry Andric         if (!CalculateStopInfo())
4050b57cec5SDimitry Andric           SetStopInfo(StopInfoSP());
4060b57cec5SDimitry Andric       }
4070b57cec5SDimitry Andric     }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric     // The stop info can be manually set by calling Thread::SetStopInfo() prior
4100b57cec5SDimitry Andric     // to this function ever getting called, so we can't rely on
4110b57cec5SDimitry Andric     // "m_stop_info_stop_id != process_stop_id" as the condition for the if
4120b57cec5SDimitry Andric     // statement below, we must also check the stop info to see if we need to
4130b57cec5SDimitry Andric     // override it. See the header documentation in
4145ffd83dbSDimitry Andric     // Architecture::OverrideStopInfo() for more information on the stop
4150b57cec5SDimitry Andric     // info override callback.
4160b57cec5SDimitry Andric     if (m_stop_info_override_stop_id != process_stop_id) {
4170b57cec5SDimitry Andric       m_stop_info_override_stop_id = process_stop_id;
4180b57cec5SDimitry Andric       if (m_stop_info_sp) {
4190b57cec5SDimitry Andric         if (const Architecture *arch =
4200b57cec5SDimitry Andric                 process_sp->GetTarget().GetArchitecturePlugin())
4210b57cec5SDimitry Andric           arch->OverrideStopInfo(*this);
4220b57cec5SDimitry Andric       }
4230b57cec5SDimitry Andric     }
4240b57cec5SDimitry Andric   }
4250b57cec5SDimitry Andric   return m_stop_info_sp;
4260b57cec5SDimitry Andric }
4270b57cec5SDimitry Andric 
GetStopReason()4280b57cec5SDimitry Andric lldb::StopReason Thread::GetStopReason() {
4290b57cec5SDimitry Andric   lldb::StopInfoSP stop_info_sp(GetStopInfo());
4300b57cec5SDimitry Andric   if (stop_info_sp)
4310b57cec5SDimitry Andric     return stop_info_sp->GetStopReason();
4320b57cec5SDimitry Andric   return eStopReasonNone;
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric 
StopInfoIsUpToDate() const4350b57cec5SDimitry Andric bool Thread::StopInfoIsUpToDate() const {
4360b57cec5SDimitry Andric   ProcessSP process_sp(GetProcess());
4370b57cec5SDimitry Andric   if (process_sp)
4380b57cec5SDimitry Andric     return m_stop_info_stop_id == process_sp->GetStopID();
4390b57cec5SDimitry Andric   else
4400b57cec5SDimitry Andric     return true; // Process is no longer around so stop info is always up to
4410b57cec5SDimitry Andric                  // date...
4420b57cec5SDimitry Andric }
4430b57cec5SDimitry Andric 
ResetStopInfo()4440b57cec5SDimitry Andric void Thread::ResetStopInfo() {
4450b57cec5SDimitry Andric   if (m_stop_info_sp) {
4460b57cec5SDimitry Andric     m_stop_info_sp.reset();
4470b57cec5SDimitry Andric   }
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
SetStopInfo(const lldb::StopInfoSP & stop_info_sp)4500b57cec5SDimitry Andric void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) {
4510b57cec5SDimitry Andric   m_stop_info_sp = stop_info_sp;
4520b57cec5SDimitry Andric   if (m_stop_info_sp) {
4530b57cec5SDimitry Andric     m_stop_info_sp->MakeStopInfoValid();
4540b57cec5SDimitry Andric     // If we are overriding the ShouldReportStop, do that here:
4550b57cec5SDimitry Andric     if (m_override_should_notify != eLazyBoolCalculate)
4560b57cec5SDimitry Andric       m_stop_info_sp->OverrideShouldNotify(m_override_should_notify ==
4570b57cec5SDimitry Andric                                            eLazyBoolYes);
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   ProcessSP process_sp(GetProcess());
4610b57cec5SDimitry Andric   if (process_sp)
4620b57cec5SDimitry Andric     m_stop_info_stop_id = process_sp->GetStopID();
4630b57cec5SDimitry Andric   else
4640b57cec5SDimitry Andric     m_stop_info_stop_id = UINT32_MAX;
46581ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Thread);
4669dba64beSDimitry Andric   LLDB_LOGF(log, "%p: tid = 0x%" PRIx64 ": stop info = %s (stop_id = %u)",
4670b57cec5SDimitry Andric             static_cast<void *>(this), GetID(),
4680b57cec5SDimitry Andric             stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>",
4690b57cec5SDimitry Andric             m_stop_info_stop_id);
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric 
SetShouldReportStop(Vote vote)4720b57cec5SDimitry Andric void Thread::SetShouldReportStop(Vote vote) {
4730b57cec5SDimitry Andric   if (vote == eVoteNoOpinion)
4740b57cec5SDimitry Andric     return;
4750b57cec5SDimitry Andric   else {
4760b57cec5SDimitry Andric     m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo);
4770b57cec5SDimitry Andric     if (m_stop_info_sp)
4780b57cec5SDimitry Andric       m_stop_info_sp->OverrideShouldNotify(m_override_should_notify ==
4790b57cec5SDimitry Andric                                            eLazyBoolYes);
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric }
4820b57cec5SDimitry Andric 
SetStopInfoToNothing()4830b57cec5SDimitry Andric void Thread::SetStopInfoToNothing() {
4840b57cec5SDimitry Andric   // Note, we can't just NULL out the private reason, or the native thread
4850b57cec5SDimitry Andric   // implementation will try to go calculate it again.  For now, just set it to
4860b57cec5SDimitry Andric   // a Unix Signal with an invalid signal number.
4870b57cec5SDimitry Andric   SetStopInfo(
4880b57cec5SDimitry Andric       StopInfo::CreateStopReasonWithSignal(*this, LLDB_INVALID_SIGNAL_NUMBER));
4890b57cec5SDimitry Andric }
4900b57cec5SDimitry Andric 
ThreadStoppedForAReason()49104eeddc0SDimitry Andric bool Thread::ThreadStoppedForAReason() { return (bool)GetPrivateStopInfo(); }
4920b57cec5SDimitry Andric 
CheckpointThreadState(ThreadStateCheckpoint & saved_state)4930b57cec5SDimitry Andric bool Thread::CheckpointThreadState(ThreadStateCheckpoint &saved_state) {
4940b57cec5SDimitry Andric   saved_state.register_backup_sp.reset();
4950b57cec5SDimitry Andric   lldb::StackFrameSP frame_sp(GetStackFrameAtIndex(0));
4960b57cec5SDimitry Andric   if (frame_sp) {
4970b57cec5SDimitry Andric     lldb::RegisterCheckpointSP reg_checkpoint_sp(
4980b57cec5SDimitry Andric         new RegisterCheckpoint(RegisterCheckpoint::Reason::eExpression));
4990b57cec5SDimitry Andric     if (reg_checkpoint_sp) {
5000b57cec5SDimitry Andric       lldb::RegisterContextSP reg_ctx_sp(frame_sp->GetRegisterContext());
5010b57cec5SDimitry Andric       if (reg_ctx_sp && reg_ctx_sp->ReadAllRegisterValues(*reg_checkpoint_sp))
5020b57cec5SDimitry Andric         saved_state.register_backup_sp = reg_checkpoint_sp;
5030b57cec5SDimitry Andric     }
5040b57cec5SDimitry Andric   }
5050b57cec5SDimitry Andric   if (!saved_state.register_backup_sp)
5060b57cec5SDimitry Andric     return false;
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   saved_state.stop_info_sp = GetStopInfo();
5090b57cec5SDimitry Andric   ProcessSP process_sp(GetProcess());
5100b57cec5SDimitry Andric   if (process_sp)
5110b57cec5SDimitry Andric     saved_state.orig_stop_id = process_sp->GetStopID();
5120b57cec5SDimitry Andric   saved_state.current_inlined_depth = GetCurrentInlinedDepth();
5135ffd83dbSDimitry Andric   saved_state.m_completed_plan_checkpoint =
5145ffd83dbSDimitry Andric       GetPlans().CheckpointCompletedPlans();
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   return true;
5170b57cec5SDimitry Andric }
5180b57cec5SDimitry Andric 
RestoreRegisterStateFromCheckpoint(ThreadStateCheckpoint & saved_state)5190b57cec5SDimitry Andric bool Thread::RestoreRegisterStateFromCheckpoint(
5200b57cec5SDimitry Andric     ThreadStateCheckpoint &saved_state) {
5210b57cec5SDimitry Andric   if (saved_state.register_backup_sp) {
5220b57cec5SDimitry Andric     lldb::StackFrameSP frame_sp(GetStackFrameAtIndex(0));
5230b57cec5SDimitry Andric     if (frame_sp) {
5240b57cec5SDimitry Andric       lldb::RegisterContextSP reg_ctx_sp(frame_sp->GetRegisterContext());
5250b57cec5SDimitry Andric       if (reg_ctx_sp) {
5260b57cec5SDimitry Andric         bool ret =
5270b57cec5SDimitry Andric             reg_ctx_sp->WriteAllRegisterValues(*saved_state.register_backup_sp);
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric         // Clear out all stack frames as our world just changed.
5300b57cec5SDimitry Andric         ClearStackFrames();
5310b57cec5SDimitry Andric         reg_ctx_sp->InvalidateIfNeeded(true);
5320b57cec5SDimitry Andric         if (m_unwinder_up)
5330b57cec5SDimitry Andric           m_unwinder_up->Clear();
5340b57cec5SDimitry Andric         return ret;
5350b57cec5SDimitry Andric       }
5360b57cec5SDimitry Andric     }
5370b57cec5SDimitry Andric   }
5380b57cec5SDimitry Andric   return false;
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint & saved_state)541fe6060f1SDimitry Andric void Thread::RestoreThreadStateFromCheckpoint(
5420b57cec5SDimitry Andric     ThreadStateCheckpoint &saved_state) {
5430b57cec5SDimitry Andric   if (saved_state.stop_info_sp)
5440b57cec5SDimitry Andric     saved_state.stop_info_sp->MakeStopInfoValid();
5450b57cec5SDimitry Andric   SetStopInfo(saved_state.stop_info_sp);
5460b57cec5SDimitry Andric   GetStackFrameList()->SetCurrentInlinedDepth(
5470b57cec5SDimitry Andric       saved_state.current_inlined_depth);
5485ffd83dbSDimitry Andric   GetPlans().RestoreCompletedPlanCheckpoint(
5495ffd83dbSDimitry Andric       saved_state.m_completed_plan_checkpoint);
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric 
GetState() const5520b57cec5SDimitry Andric StateType Thread::GetState() const {
5530b57cec5SDimitry Andric   // If any other threads access this we will need a mutex for it
5540b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
5550b57cec5SDimitry Andric   return m_state;
5560b57cec5SDimitry Andric }
5570b57cec5SDimitry Andric 
SetState(StateType state)5580b57cec5SDimitry Andric void Thread::SetState(StateType state) {
5590b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
5600b57cec5SDimitry Andric   m_state = state;
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric 
GetStopDescription()5635ffd83dbSDimitry Andric std::string Thread::GetStopDescription() {
5645ffd83dbSDimitry Andric   StackFrameSP frame_sp = GetStackFrameAtIndex(0);
5655ffd83dbSDimitry Andric 
5665ffd83dbSDimitry Andric   if (!frame_sp)
5675ffd83dbSDimitry Andric     return GetStopDescriptionRaw();
5685ffd83dbSDimitry Andric 
5695ffd83dbSDimitry Andric   auto recognized_frame_sp = frame_sp->GetRecognizedFrame();
5705ffd83dbSDimitry Andric 
5715ffd83dbSDimitry Andric   if (!recognized_frame_sp)
5725ffd83dbSDimitry Andric     return GetStopDescriptionRaw();
5735ffd83dbSDimitry Andric 
5745ffd83dbSDimitry Andric   std::string recognized_stop_description =
5755ffd83dbSDimitry Andric       recognized_frame_sp->GetStopDescription();
5765ffd83dbSDimitry Andric 
5775ffd83dbSDimitry Andric   if (!recognized_stop_description.empty())
5785ffd83dbSDimitry Andric     return recognized_stop_description;
5795ffd83dbSDimitry Andric 
5805ffd83dbSDimitry Andric   return GetStopDescriptionRaw();
5815ffd83dbSDimitry Andric }
5825ffd83dbSDimitry Andric 
GetStopDescriptionRaw()5835ffd83dbSDimitry Andric std::string Thread::GetStopDescriptionRaw() {
5845ffd83dbSDimitry Andric   StopInfoSP stop_info_sp = GetStopInfo();
5855ffd83dbSDimitry Andric   std::string raw_stop_description;
5865ffd83dbSDimitry Andric   if (stop_info_sp && stop_info_sp->IsValid()) {
5875ffd83dbSDimitry Andric     raw_stop_description = stop_info_sp->GetDescription();
5885ffd83dbSDimitry Andric     assert((!raw_stop_description.empty() ||
5895ffd83dbSDimitry Andric             stop_info_sp->GetStopReason() == eStopReasonNone) &&
5905ffd83dbSDimitry Andric            "StopInfo returned an empty description.");
5915ffd83dbSDimitry Andric   }
5925ffd83dbSDimitry Andric   return raw_stop_description;
5935ffd83dbSDimitry Andric }
5945ffd83dbSDimitry Andric 
WillStop()5950b57cec5SDimitry Andric void Thread::WillStop() {
5960b57cec5SDimitry Andric   ThreadPlan *current_plan = GetCurrentPlan();
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   // FIXME: I may decide to disallow threads with no plans.  In which
5990b57cec5SDimitry Andric   // case this should go to an assert.
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   if (!current_plan)
6020b57cec5SDimitry Andric     return;
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   current_plan->WillStop();
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric 
SetupForResume()6070b57cec5SDimitry Andric void Thread::SetupForResume() {
6080b57cec5SDimitry Andric   if (GetResumeState() != eStateSuspended) {
6090b57cec5SDimitry Andric     // If we're at a breakpoint push the step-over breakpoint plan.  Do this
6100b57cec5SDimitry Andric     // before telling the current plan it will resume, since we might change
6110b57cec5SDimitry Andric     // what the current plan is.
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric     lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
6140b57cec5SDimitry Andric     if (reg_ctx_sp) {
6150b57cec5SDimitry Andric       const addr_t thread_pc = reg_ctx_sp->GetPC();
6160b57cec5SDimitry Andric       BreakpointSiteSP bp_site_sp =
6170b57cec5SDimitry Andric           GetProcess()->GetBreakpointSiteList().FindByAddress(thread_pc);
6180b57cec5SDimitry Andric       if (bp_site_sp) {
6190b57cec5SDimitry Andric         // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the
6200b57cec5SDimitry Andric         // target may not require anything special to step over a breakpoint.
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric         ThreadPlan *cur_plan = GetCurrentPlan();
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric         bool push_step_over_bp_plan = false;
6250b57cec5SDimitry Andric         if (cur_plan->GetKind() == ThreadPlan::eKindStepOverBreakpoint) {
6260b57cec5SDimitry Andric           ThreadPlanStepOverBreakpoint *bp_plan =
6270b57cec5SDimitry Andric               (ThreadPlanStepOverBreakpoint *)cur_plan;
6280b57cec5SDimitry Andric           if (bp_plan->GetBreakpointLoadAddress() != thread_pc)
6290b57cec5SDimitry Andric             push_step_over_bp_plan = true;
6300b57cec5SDimitry Andric         } else
6310b57cec5SDimitry Andric           push_step_over_bp_plan = true;
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric         if (push_step_over_bp_plan) {
6340b57cec5SDimitry Andric           ThreadPlanSP step_bp_plan_sp(new ThreadPlanStepOverBreakpoint(*this));
6350b57cec5SDimitry Andric           if (step_bp_plan_sp) {
6360b57cec5SDimitry Andric             step_bp_plan_sp->SetPrivate(true);
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric             if (GetCurrentPlan()->RunState() != eStateStepping) {
6390b57cec5SDimitry Andric               ThreadPlanStepOverBreakpoint *step_bp_plan =
6400b57cec5SDimitry Andric                   static_cast<ThreadPlanStepOverBreakpoint *>(
6410b57cec5SDimitry Andric                       step_bp_plan_sp.get());
6420b57cec5SDimitry Andric               step_bp_plan->SetAutoContinue(true);
6430b57cec5SDimitry Andric             }
6440b57cec5SDimitry Andric             QueueThreadPlan(step_bp_plan_sp, false);
6450b57cec5SDimitry Andric           }
6460b57cec5SDimitry Andric         }
6470b57cec5SDimitry Andric       }
6480b57cec5SDimitry Andric     }
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric }
6510b57cec5SDimitry Andric 
ShouldResume(StateType resume_state)6520b57cec5SDimitry Andric bool Thread::ShouldResume(StateType resume_state) {
6530b57cec5SDimitry Andric   // At this point clear the completed plan stack.
6545ffd83dbSDimitry Andric   GetPlans().WillResume();
6550b57cec5SDimitry Andric   m_override_should_notify = eLazyBoolCalculate;
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   StateType prev_resume_state = GetTemporaryResumeState();
6580b57cec5SDimitry Andric 
6590b57cec5SDimitry Andric   SetTemporaryResumeState(resume_state);
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   lldb::ThreadSP backing_thread_sp(GetBackingThread());
6620b57cec5SDimitry Andric   if (backing_thread_sp)
6630b57cec5SDimitry Andric     backing_thread_sp->SetTemporaryResumeState(resume_state);
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   // Make sure m_stop_info_sp is valid.  Don't do this for threads we suspended
6660b57cec5SDimitry Andric   // in the previous run.
6670b57cec5SDimitry Andric   if (prev_resume_state != eStateSuspended)
6680b57cec5SDimitry Andric     GetPrivateStopInfo();
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric   // This is a little dubious, but we are trying to limit how often we actually
6710b57cec5SDimitry Andric   // fetch stop info from the target, 'cause that slows down single stepping.
6720b57cec5SDimitry Andric   // So assume that if we got to the point where we're about to resume, and we
6730b57cec5SDimitry Andric   // haven't yet had to fetch the stop reason, then it doesn't need to know
6740b57cec5SDimitry Andric   // about the fact that we are resuming...
6750b57cec5SDimitry Andric   const uint32_t process_stop_id = GetProcess()->GetStopID();
6760b57cec5SDimitry Andric   if (m_stop_info_stop_id == process_stop_id &&
6770b57cec5SDimitry Andric       (m_stop_info_sp && m_stop_info_sp->IsValid())) {
6780b57cec5SDimitry Andric     StopInfo *stop_info = GetPrivateStopInfo().get();
6790b57cec5SDimitry Andric     if (stop_info)
6800b57cec5SDimitry Andric       stop_info->WillResume(resume_state);
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   // Tell all the plans that we are about to resume in case they need to clear
6840b57cec5SDimitry Andric   // any state. We distinguish between the plan on the top of the stack and the
6850b57cec5SDimitry Andric   // lower plans in case a plan needs to do any special business before it
6860b57cec5SDimitry Andric   // runs.
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   bool need_to_resume = false;
6890b57cec5SDimitry Andric   ThreadPlan *plan_ptr = GetCurrentPlan();
6900b57cec5SDimitry Andric   if (plan_ptr) {
6910b57cec5SDimitry Andric     need_to_resume = plan_ptr->WillResume(resume_state, true);
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric     while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) {
6940b57cec5SDimitry Andric       plan_ptr->WillResume(resume_state, false);
6950b57cec5SDimitry Andric     }
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric     // If the WillResume for the plan says we are faking a resume, then it will
6980b57cec5SDimitry Andric     // have set an appropriate stop info. In that case, don't reset it here.
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric     if (need_to_resume && resume_state != eStateSuspended) {
7010b57cec5SDimitry Andric       m_stop_info_sp.reset();
7020b57cec5SDimitry Andric     }
7030b57cec5SDimitry Andric   }
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric   if (need_to_resume) {
7060b57cec5SDimitry Andric     ClearStackFrames();
7070b57cec5SDimitry Andric     // Let Thread subclasses do any special work they need to prior to resuming
7080b57cec5SDimitry Andric     WillResume(resume_state);
7090b57cec5SDimitry Andric   }
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric   return need_to_resume;
7120b57cec5SDimitry Andric }
7130b57cec5SDimitry Andric 
DidResume()714bdd1243dSDimitry Andric void Thread::DidResume() {
715bdd1243dSDimitry Andric   SetResumeSignal(LLDB_INVALID_SIGNAL_NUMBER);
716bdd1243dSDimitry Andric   // This will get recomputed each time when we stop.
717bdd1243dSDimitry Andric   SetShouldRunBeforePublicStop(false);
718bdd1243dSDimitry Andric }
7190b57cec5SDimitry Andric 
DidStop()7200b57cec5SDimitry Andric void Thread::DidStop() { SetState(eStateStopped); }
7210b57cec5SDimitry Andric 
ShouldStop(Event * event_ptr)7220b57cec5SDimitry Andric bool Thread::ShouldStop(Event *event_ptr) {
7230b57cec5SDimitry Andric   ThreadPlan *current_plan = GetCurrentPlan();
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   bool should_stop = true;
7260b57cec5SDimitry Andric 
72781ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric   if (GetResumeState() == eStateSuspended) {
7309dba64beSDimitry Andric     LLDB_LOGF(log,
7319dba64beSDimitry Andric               "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
7320b57cec5SDimitry Andric               ", should_stop = 0 (ignore since thread was suspended)",
7330b57cec5SDimitry Andric               __FUNCTION__, GetID(), GetProtocolID());
7340b57cec5SDimitry Andric     return false;
7350b57cec5SDimitry Andric   }
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   if (GetTemporaryResumeState() == eStateSuspended) {
7389dba64beSDimitry Andric     LLDB_LOGF(log,
7399dba64beSDimitry Andric               "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
7400b57cec5SDimitry Andric               ", should_stop = 0 (ignore since thread was suspended)",
7410b57cec5SDimitry Andric               __FUNCTION__, GetID(), GetProtocolID());
7420b57cec5SDimitry Andric     return false;
7430b57cec5SDimitry Andric   }
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric   // Based on the current thread plan and process stop info, check if this
7460b57cec5SDimitry Andric   // thread caused the process to stop. NOTE: this must take place before the
7470b57cec5SDimitry Andric   // plan is moved from the current plan stack to the completed plan stack.
7480b57cec5SDimitry Andric   if (!ThreadStoppedForAReason()) {
7499dba64beSDimitry Andric     LLDB_LOGF(log,
7509dba64beSDimitry Andric               "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
7510b57cec5SDimitry Andric               ", pc = 0x%16.16" PRIx64
7520b57cec5SDimitry Andric               ", should_stop = 0 (ignore since no stop reason)",
7530b57cec5SDimitry Andric               __FUNCTION__, GetID(), GetProtocolID(),
7540b57cec5SDimitry Andric               GetRegisterContext() ? GetRegisterContext()->GetPC()
7550b57cec5SDimitry Andric                                    : LLDB_INVALID_ADDRESS);
7560b57cec5SDimitry Andric     return false;
7570b57cec5SDimitry Andric   }
7580b57cec5SDimitry Andric 
759bdd1243dSDimitry Andric   // Clear the "must run me before stop" if it was set:
760bdd1243dSDimitry Andric   SetShouldRunBeforePublicStop(false);
761bdd1243dSDimitry Andric 
7620b57cec5SDimitry Andric   if (log) {
7639dba64beSDimitry Andric     LLDB_LOGF(log,
7649dba64beSDimitry Andric               "Thread::%s(%p) for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
7650b57cec5SDimitry Andric               ", pc = 0x%16.16" PRIx64,
7669dba64beSDimitry Andric               __FUNCTION__, static_cast<void *>(this), GetID(), GetProtocolID(),
7670b57cec5SDimitry Andric               GetRegisterContext() ? GetRegisterContext()->GetPC()
7680b57cec5SDimitry Andric                                    : LLDB_INVALID_ADDRESS);
7699dba64beSDimitry Andric     LLDB_LOGF(log, "^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
7700b57cec5SDimitry Andric     StreamString s;
7710b57cec5SDimitry Andric     s.IndentMore();
7725ffd83dbSDimitry Andric     GetProcess()->DumpThreadPlansForTID(
7735ffd83dbSDimitry Andric         s, GetID(), eDescriptionLevelVerbose, true /* internal */,
7745ffd83dbSDimitry Andric         false /* condense_trivial */, true /* skip_unreported */);
7759dba64beSDimitry Andric     LLDB_LOGF(log, "Plan stack initial state:\n%s", s.GetData());
7760b57cec5SDimitry Andric   }
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric   // The top most plan always gets to do the trace log...
7790b57cec5SDimitry Andric   current_plan->DoTraceLog();
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric   // First query the stop info's ShouldStopSynchronous.  This handles
7820b57cec5SDimitry Andric   // "synchronous" stop reasons, for example the breakpoint command on internal
7830b57cec5SDimitry Andric   // breakpoints.  If a synchronous stop reason says we should not stop, then
7840b57cec5SDimitry Andric   // we don't have to do any more work on this stop.
7850b57cec5SDimitry Andric   StopInfoSP private_stop_info(GetPrivateStopInfo());
7860b57cec5SDimitry Andric   if (private_stop_info &&
7870b57cec5SDimitry Andric       !private_stop_info->ShouldStopSynchronous(event_ptr)) {
7889dba64beSDimitry Andric     LLDB_LOGF(log, "StopInfo::ShouldStop async callback says we should not "
7890b57cec5SDimitry Andric                    "stop, returning ShouldStop of false.");
7900b57cec5SDimitry Andric     return false;
7910b57cec5SDimitry Andric   }
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric   // If we've already been restarted, don't query the plans since the state
7940b57cec5SDimitry Andric   // they would examine is not current.
7950b57cec5SDimitry Andric   if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr))
7960b57cec5SDimitry Andric     return false;
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric   // Before the plans see the state of the world, calculate the current inlined
7990b57cec5SDimitry Andric   // depth.
8000b57cec5SDimitry Andric   GetStackFrameList()->CalculateCurrentInlinedDepth();
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric   // If the base plan doesn't understand why we stopped, then we have to find a
8030b57cec5SDimitry Andric   // plan that does. If that plan is still working, then we don't need to do
8040b57cec5SDimitry Andric   // any more work.  If the plan that explains the stop is done, then we should
8050b57cec5SDimitry Andric   // pop all the plans below it, and pop it, and then let the plans above it
8060b57cec5SDimitry Andric   // decide whether they still need to do more work.
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   bool done_processing_current_plan = false;
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric   if (!current_plan->PlanExplainsStop(event_ptr)) {
8110b57cec5SDimitry Andric     if (current_plan->TracerExplainsStop()) {
8120b57cec5SDimitry Andric       done_processing_current_plan = true;
8130b57cec5SDimitry Andric       should_stop = false;
8140b57cec5SDimitry Andric     } else {
8150b57cec5SDimitry Andric       // If the current plan doesn't explain the stop, then find one that does
8160b57cec5SDimitry Andric       // and let it handle the situation.
8170b57cec5SDimitry Andric       ThreadPlan *plan_ptr = current_plan;
8180b57cec5SDimitry Andric       while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) {
8190b57cec5SDimitry Andric         if (plan_ptr->PlanExplainsStop(event_ptr)) {
820fe6060f1SDimitry Andric           LLDB_LOGF(log, "Plan %s explains stop.", plan_ptr->GetName());
821fe6060f1SDimitry Andric 
8220b57cec5SDimitry Andric           should_stop = plan_ptr->ShouldStop(event_ptr);
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric           // plan_ptr explains the stop, next check whether plan_ptr is done,
8250b57cec5SDimitry Andric           // if so, then we should take it and all the plans below it off the
8260b57cec5SDimitry Andric           // stack.
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric           if (plan_ptr->MischiefManaged()) {
8290b57cec5SDimitry Andric             // We're going to pop the plans up to and including the plan that
8300b57cec5SDimitry Andric             // explains the stop.
8310b57cec5SDimitry Andric             ThreadPlan *prev_plan_ptr = GetPreviousPlan(plan_ptr);
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric             do {
8340b57cec5SDimitry Andric               if (should_stop)
8350b57cec5SDimitry Andric                 current_plan->WillStop();
8360b57cec5SDimitry Andric               PopPlan();
8370b57cec5SDimitry Andric             } while ((current_plan = GetCurrentPlan()) != prev_plan_ptr);
8380b57cec5SDimitry Andric             // Now, if the responsible plan was not "Okay to discard" then
8390b57cec5SDimitry Andric             // we're done, otherwise we forward this to the next plan in the
8400b57cec5SDimitry Andric             // stack below.
8410b57cec5SDimitry Andric             done_processing_current_plan =
842349cc55cSDimitry Andric                 (plan_ptr->IsControllingPlan() && !plan_ptr->OkayToDiscard());
843bdd1243dSDimitry Andric           } else {
844bdd1243dSDimitry Andric             bool should_force_run = plan_ptr->ShouldRunBeforePublicStop();
845bdd1243dSDimitry Andric             if (should_force_run) {
846bdd1243dSDimitry Andric               SetShouldRunBeforePublicStop(true);
847bdd1243dSDimitry Andric               should_stop = false;
848bdd1243dSDimitry Andric             }
8490b57cec5SDimitry Andric             done_processing_current_plan = true;
850bdd1243dSDimitry Andric           }
8510b57cec5SDimitry Andric           break;
8520b57cec5SDimitry Andric         }
8530b57cec5SDimitry Andric       }
8540b57cec5SDimitry Andric     }
8550b57cec5SDimitry Andric   }
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric   if (!done_processing_current_plan) {
858fe6060f1SDimitry Andric     bool override_stop = false;
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric     // We're starting from the base plan, so just let it decide;
8615ffd83dbSDimitry Andric     if (current_plan->IsBasePlan()) {
8620b57cec5SDimitry Andric       should_stop = current_plan->ShouldStop(event_ptr);
8639dba64beSDimitry Andric       LLDB_LOGF(log, "Base plan says should stop: %i.", should_stop);
8640b57cec5SDimitry Andric     } else {
8650b57cec5SDimitry Andric       // Otherwise, don't let the base plan override what the other plans say
8660b57cec5SDimitry Andric       // to do, since presumably if there were other plans they would know what
8670b57cec5SDimitry Andric       // to do...
8680b57cec5SDimitry Andric       while (true) {
8695ffd83dbSDimitry Andric         if (current_plan->IsBasePlan())
8700b57cec5SDimitry Andric           break;
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric         should_stop = current_plan->ShouldStop(event_ptr);
8739dba64beSDimitry Andric         LLDB_LOGF(log, "Plan %s should stop: %d.", current_plan->GetName(),
8740b57cec5SDimitry Andric                   should_stop);
8750b57cec5SDimitry Andric         if (current_plan->MischiefManaged()) {
8760b57cec5SDimitry Andric           if (should_stop)
8770b57cec5SDimitry Andric             current_plan->WillStop();
8780b57cec5SDimitry Andric 
879fe6060f1SDimitry Andric           if (current_plan->ShouldAutoContinue(event_ptr)) {
880fe6060f1SDimitry Andric             override_stop = true;
881fe6060f1SDimitry Andric             LLDB_LOGF(log, "Plan %s auto-continue: true.",
882fe6060f1SDimitry Andric                       current_plan->GetName());
883fe6060f1SDimitry Andric           }
8840b57cec5SDimitry Andric 
885349cc55cSDimitry Andric           // If a Controlling Plan wants to stop, we let it. Otherwise, see if
886349cc55cSDimitry Andric           // the plan's parent wants to stop.
887fe6060f1SDimitry Andric 
888fe6060f1SDimitry Andric           PopPlan();
889349cc55cSDimitry Andric           if (should_stop && current_plan->IsControllingPlan() &&
8900b57cec5SDimitry Andric               !current_plan->OkayToDiscard()) {
8910b57cec5SDimitry Andric             break;
892fe6060f1SDimitry Andric           }
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric           current_plan = GetCurrentPlan();
8950b57cec5SDimitry Andric           if (current_plan == nullptr) {
8960b57cec5SDimitry Andric             break;
8970b57cec5SDimitry Andric           }
8980b57cec5SDimitry Andric         } else {
8990b57cec5SDimitry Andric           break;
9000b57cec5SDimitry Andric         }
9010b57cec5SDimitry Andric       }
9020b57cec5SDimitry Andric     }
9030b57cec5SDimitry Andric 
904fe6060f1SDimitry Andric     if (override_stop)
9050b57cec5SDimitry Andric       should_stop = false;
9060b57cec5SDimitry Andric   }
9070b57cec5SDimitry Andric 
908349cc55cSDimitry Andric   // One other potential problem is that we set up a controlling plan, then stop
909349cc55cSDimitry Andric   // in before it is complete - for instance by hitting a breakpoint during a
9100b57cec5SDimitry Andric   // step-over - then do some step/finish/etc operations that wind up past the
9110b57cec5SDimitry Andric   // end point condition of the initial plan.  We don't want to strand the
9120b57cec5SDimitry Andric   // original plan on the stack, This code clears stale plans off the stack.
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric   if (should_stop) {
9150b57cec5SDimitry Andric     ThreadPlan *plan_ptr = GetCurrentPlan();
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric     // Discard the stale plans and all plans below them in the stack, plus move
9180b57cec5SDimitry Andric     // the completed plans to the completed plan stack
9195ffd83dbSDimitry Andric     while (!plan_ptr->IsBasePlan()) {
9200b57cec5SDimitry Andric       bool stale = plan_ptr->IsPlanStale();
9210b57cec5SDimitry Andric       ThreadPlan *examined_plan = plan_ptr;
9220b57cec5SDimitry Andric       plan_ptr = GetPreviousPlan(examined_plan);
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric       if (stale) {
9259dba64beSDimitry Andric         LLDB_LOGF(
9269dba64beSDimitry Andric             log,
9270b57cec5SDimitry Andric             "Plan %s being discarded in cleanup, it says it is already done.",
9280b57cec5SDimitry Andric             examined_plan->GetName());
9290b57cec5SDimitry Andric         while (GetCurrentPlan() != examined_plan) {
9300b57cec5SDimitry Andric           DiscardPlan();
9310b57cec5SDimitry Andric         }
9320b57cec5SDimitry Andric         if (examined_plan->IsPlanComplete()) {
9330b57cec5SDimitry Andric           // plan is complete but does not explain the stop (example: step to a
9340b57cec5SDimitry Andric           // line with breakpoint), let us move the plan to
9350b57cec5SDimitry Andric           // completed_plan_stack anyway
9360b57cec5SDimitry Andric           PopPlan();
9370b57cec5SDimitry Andric         } else
9380b57cec5SDimitry Andric           DiscardPlan();
9390b57cec5SDimitry Andric       }
9400b57cec5SDimitry Andric     }
9410b57cec5SDimitry Andric   }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   if (log) {
9440b57cec5SDimitry Andric     StreamString s;
9450b57cec5SDimitry Andric     s.IndentMore();
9465ffd83dbSDimitry Andric     GetProcess()->DumpThreadPlansForTID(
9475ffd83dbSDimitry Andric         s, GetID(), eDescriptionLevelVerbose, true /* internal */,
9485ffd83dbSDimitry Andric         false /* condense_trivial */, true /* skip_unreported */);
9499dba64beSDimitry Andric     LLDB_LOGF(log, "Plan stack final state:\n%s", s.GetData());
9509dba64beSDimitry Andric     LLDB_LOGF(log, "vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv",
9510b57cec5SDimitry Andric               should_stop);
9520b57cec5SDimitry Andric   }
9530b57cec5SDimitry Andric   return should_stop;
9540b57cec5SDimitry Andric }
9550b57cec5SDimitry Andric 
ShouldReportStop(Event * event_ptr)9560b57cec5SDimitry Andric Vote Thread::ShouldReportStop(Event *event_ptr) {
9570b57cec5SDimitry Andric   StateType thread_state = GetResumeState();
9580b57cec5SDimitry Andric   StateType temp_thread_state = GetTemporaryResumeState();
9590b57cec5SDimitry Andric 
96081ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   if (thread_state == eStateSuspended || thread_state == eStateInvalid) {
9639dba64beSDimitry Andric     LLDB_LOGF(log,
9649dba64beSDimitry Andric               "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
9650b57cec5SDimitry Andric               ": returning vote %i (state was suspended or invalid)",
9660b57cec5SDimitry Andric               GetID(), eVoteNoOpinion);
9670b57cec5SDimitry Andric     return eVoteNoOpinion;
9680b57cec5SDimitry Andric   }
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric   if (temp_thread_state == eStateSuspended ||
9710b57cec5SDimitry Andric       temp_thread_state == eStateInvalid) {
9729dba64beSDimitry Andric     LLDB_LOGF(log,
9730b57cec5SDimitry Andric               "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
9740b57cec5SDimitry Andric               ": returning vote %i (temporary state was suspended or invalid)",
9750b57cec5SDimitry Andric               GetID(), eVoteNoOpinion);
9760b57cec5SDimitry Andric     return eVoteNoOpinion;
9770b57cec5SDimitry Andric   }
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   if (!ThreadStoppedForAReason()) {
9809dba64beSDimitry Andric     LLDB_LOGF(log,
9819dba64beSDimitry Andric               "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
9820b57cec5SDimitry Andric               ": returning vote %i (thread didn't stop for a reason.)",
9830b57cec5SDimitry Andric               GetID(), eVoteNoOpinion);
9840b57cec5SDimitry Andric     return eVoteNoOpinion;
9850b57cec5SDimitry Andric   }
9860b57cec5SDimitry Andric 
9875ffd83dbSDimitry Andric   if (GetPlans().AnyCompletedPlans()) {
9885ffd83dbSDimitry Andric     // Pass skip_private = false to GetCompletedPlan, since we want to ask
9895ffd83dbSDimitry Andric     // the last plan, regardless of whether it is private or not.
9909dba64beSDimitry Andric     LLDB_LOGF(log,
9919dba64beSDimitry Andric               "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
9920b57cec5SDimitry Andric               ": returning vote for complete stack's back plan",
9930b57cec5SDimitry Andric               GetID());
9945ffd83dbSDimitry Andric     return GetPlans().GetCompletedPlan(false)->ShouldReportStop(event_ptr);
9950b57cec5SDimitry Andric   } else {
9960b57cec5SDimitry Andric     Vote thread_vote = eVoteNoOpinion;
9970b57cec5SDimitry Andric     ThreadPlan *plan_ptr = GetCurrentPlan();
9980b57cec5SDimitry Andric     while (true) {
9990b57cec5SDimitry Andric       if (plan_ptr->PlanExplainsStop(event_ptr)) {
10000b57cec5SDimitry Andric         thread_vote = plan_ptr->ShouldReportStop(event_ptr);
10010b57cec5SDimitry Andric         break;
10020b57cec5SDimitry Andric       }
10035ffd83dbSDimitry Andric       if (plan_ptr->IsBasePlan())
10040b57cec5SDimitry Andric         break;
10050b57cec5SDimitry Andric       else
10060b57cec5SDimitry Andric         plan_ptr = GetPreviousPlan(plan_ptr);
10070b57cec5SDimitry Andric     }
10089dba64beSDimitry Andric     LLDB_LOGF(log,
10099dba64beSDimitry Andric               "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
10100b57cec5SDimitry Andric               ": returning vote %i for current plan",
10110b57cec5SDimitry Andric               GetID(), thread_vote);
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric     return thread_vote;
10140b57cec5SDimitry Andric   }
10150b57cec5SDimitry Andric }
10160b57cec5SDimitry Andric 
ShouldReportRun(Event * event_ptr)10170b57cec5SDimitry Andric Vote Thread::ShouldReportRun(Event *event_ptr) {
10180b57cec5SDimitry Andric   StateType thread_state = GetResumeState();
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric   if (thread_state == eStateSuspended || thread_state == eStateInvalid) {
10210b57cec5SDimitry Andric     return eVoteNoOpinion;
10220b57cec5SDimitry Andric   }
10230b57cec5SDimitry Andric 
102481ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
10255ffd83dbSDimitry Andric   if (GetPlans().AnyCompletedPlans()) {
10265ffd83dbSDimitry Andric     // Pass skip_private = false to GetCompletedPlan, since we want to ask
10275ffd83dbSDimitry Andric     // the last plan, regardless of whether it is private or not.
10289dba64beSDimitry Andric     LLDB_LOGF(log,
10299dba64beSDimitry Andric               "Current Plan for thread %d(%p) (0x%4.4" PRIx64
10300b57cec5SDimitry Andric               ", %s): %s being asked whether we should report run.",
10310b57cec5SDimitry Andric               GetIndexID(), static_cast<void *>(this), GetID(),
10320b57cec5SDimitry Andric               StateAsCString(GetTemporaryResumeState()),
10335ffd83dbSDimitry Andric               GetCompletedPlan()->GetName());
10340b57cec5SDimitry Andric 
10355ffd83dbSDimitry Andric     return GetPlans().GetCompletedPlan(false)->ShouldReportRun(event_ptr);
10360b57cec5SDimitry Andric   } else {
10379dba64beSDimitry Andric     LLDB_LOGF(log,
10389dba64beSDimitry Andric               "Current Plan for thread %d(%p) (0x%4.4" PRIx64
10390b57cec5SDimitry Andric               ", %s): %s being asked whether we should report run.",
10400b57cec5SDimitry Andric               GetIndexID(), static_cast<void *>(this), GetID(),
10410b57cec5SDimitry Andric               StateAsCString(GetTemporaryResumeState()),
10420b57cec5SDimitry Andric               GetCurrentPlan()->GetName());
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric     return GetCurrentPlan()->ShouldReportRun(event_ptr);
10450b57cec5SDimitry Andric   }
10460b57cec5SDimitry Andric }
10470b57cec5SDimitry Andric 
MatchesSpec(const ThreadSpec * spec)10480b57cec5SDimitry Andric bool Thread::MatchesSpec(const ThreadSpec *spec) {
10490b57cec5SDimitry Andric   return (spec == nullptr) ? true : spec->ThreadPassesBasicTests(*this);
10500b57cec5SDimitry Andric }
10510b57cec5SDimitry Andric 
GetPlans() const10525ffd83dbSDimitry Andric ThreadPlanStack &Thread::GetPlans() const {
10535ffd83dbSDimitry Andric   ThreadPlanStack *plans = GetProcess()->FindThreadPlans(GetID());
10545ffd83dbSDimitry Andric   if (plans)
10555ffd83dbSDimitry Andric     return *plans;
10560b57cec5SDimitry Andric 
10575ffd83dbSDimitry Andric   // History threads don't have a thread plan, but they do ask get asked to
10585ffd83dbSDimitry Andric   // describe themselves, which usually involves pulling out the stop reason.
10595ffd83dbSDimitry Andric   // That in turn will check for a completed plan on the ThreadPlanStack.
10605ffd83dbSDimitry Andric   // Instead of special-casing at that point, we return a Stack with a
10615ffd83dbSDimitry Andric   // ThreadPlanNull as its base plan.  That will give the right answers to the
10625ffd83dbSDimitry Andric   // queries GetDescription makes, and only assert if you try to run the thread.
10635ffd83dbSDimitry Andric   if (!m_null_plan_stack_up)
10645ffd83dbSDimitry Andric     m_null_plan_stack_up = std::make_unique<ThreadPlanStack>(*this, true);
1065bdd1243dSDimitry Andric   return *m_null_plan_stack_up;
10665ffd83dbSDimitry Andric }
10675ffd83dbSDimitry Andric 
PushPlan(ThreadPlanSP thread_plan_sp)10685ffd83dbSDimitry Andric void Thread::PushPlan(ThreadPlanSP thread_plan_sp) {
10695ffd83dbSDimitry Andric   assert(thread_plan_sp && "Don't push an empty thread plan.");
10700b57cec5SDimitry Andric 
107181ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
10720b57cec5SDimitry Andric   if (log) {
10730b57cec5SDimitry Andric     StreamString s;
10740b57cec5SDimitry Andric     thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
10759dba64beSDimitry Andric     LLDB_LOGF(log, "Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64 ".",
10760b57cec5SDimitry Andric               static_cast<void *>(this), s.GetData(),
10770b57cec5SDimitry Andric               thread_plan_sp->GetThread().GetID());
10780b57cec5SDimitry Andric   }
10795ffd83dbSDimitry Andric 
10805ffd83dbSDimitry Andric   GetPlans().PushPlan(std::move(thread_plan_sp));
10810b57cec5SDimitry Andric }
10820b57cec5SDimitry Andric 
PopPlan()10830b57cec5SDimitry Andric void Thread::PopPlan() {
108481ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
10855ffd83dbSDimitry Andric   ThreadPlanSP popped_plan_sp = GetPlans().PopPlan();
10860b57cec5SDimitry Andric   if (log) {
10879dba64beSDimitry Andric     LLDB_LOGF(log, "Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
10885ffd83dbSDimitry Andric               popped_plan_sp->GetName(), popped_plan_sp->GetThread().GetID());
10890b57cec5SDimitry Andric   }
10900b57cec5SDimitry Andric }
10910b57cec5SDimitry Andric 
DiscardPlan()10920b57cec5SDimitry Andric void Thread::DiscardPlan() {
109381ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
109481ad6265SDimitry Andric   ThreadPlanSP discarded_plan_sp = GetPlans().DiscardPlan();
10955ffd83dbSDimitry Andric 
10969dba64beSDimitry Andric   LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
10975ffd83dbSDimitry Andric             discarded_plan_sp->GetName(),
10985ffd83dbSDimitry Andric             discarded_plan_sp->GetThread().GetID());
10990b57cec5SDimitry Andric }
11000b57cec5SDimitry Andric 
AutoCompleteThreadPlans(CompletionRequest & request) const1101e8d8bef9SDimitry Andric void Thread::AutoCompleteThreadPlans(CompletionRequest &request) const {
1102e8d8bef9SDimitry Andric   const ThreadPlanStack &plans = GetPlans();
1103e8d8bef9SDimitry Andric   if (!plans.AnyPlans())
1104e8d8bef9SDimitry Andric     return;
1105e8d8bef9SDimitry Andric 
1106e8d8bef9SDimitry Andric   // Iterate from the second plan (index: 1) to skip the base plan.
1107e8d8bef9SDimitry Andric   ThreadPlanSP p;
1108e8d8bef9SDimitry Andric   uint32_t i = 1;
1109e8d8bef9SDimitry Andric   while ((p = plans.GetPlanByIndex(i, false))) {
1110e8d8bef9SDimitry Andric     StreamString strm;
1111e8d8bef9SDimitry Andric     p->GetDescription(&strm, eDescriptionLevelInitial);
1112e8d8bef9SDimitry Andric     request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1113e8d8bef9SDimitry Andric     i++;
1114e8d8bef9SDimitry Andric   }
1115e8d8bef9SDimitry Andric }
1116e8d8bef9SDimitry Andric 
GetCurrentPlan() const11175ffd83dbSDimitry Andric ThreadPlan *Thread::GetCurrentPlan() const {
11185ffd83dbSDimitry Andric   return GetPlans().GetCurrentPlan().get();
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric 
GetCompletedPlan() const11215ffd83dbSDimitry Andric ThreadPlanSP Thread::GetCompletedPlan() const {
11225ffd83dbSDimitry Andric   return GetPlans().GetCompletedPlan();
11230b57cec5SDimitry Andric }
11240b57cec5SDimitry Andric 
GetReturnValueObject() const11255ffd83dbSDimitry Andric ValueObjectSP Thread::GetReturnValueObject() const {
11265ffd83dbSDimitry Andric   return GetPlans().GetReturnValueObject();
11270b57cec5SDimitry Andric }
11280b57cec5SDimitry Andric 
GetExpressionVariable() const11295ffd83dbSDimitry Andric ExpressionVariableSP Thread::GetExpressionVariable() const {
11305ffd83dbSDimitry Andric   return GetPlans().GetExpressionVariable();
11310b57cec5SDimitry Andric }
11320b57cec5SDimitry Andric 
IsThreadPlanDone(ThreadPlan * plan) const11335ffd83dbSDimitry Andric bool Thread::IsThreadPlanDone(ThreadPlan *plan) const {
11345ffd83dbSDimitry Andric   return GetPlans().IsPlanDone(plan);
11350b57cec5SDimitry Andric }
11360b57cec5SDimitry Andric 
WasThreadPlanDiscarded(ThreadPlan * plan) const11375ffd83dbSDimitry Andric bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) const {
11385ffd83dbSDimitry Andric   return GetPlans().WasPlanDiscarded(plan);
11390b57cec5SDimitry Andric }
11400b57cec5SDimitry Andric 
CompletedPlanOverridesBreakpoint() const11415ffd83dbSDimitry Andric bool Thread::CompletedPlanOverridesBreakpoint() const {
11425ffd83dbSDimitry Andric   return GetPlans().AnyCompletedPlans();
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
GetPreviousPlan(ThreadPlan * current_plan) const11455ffd83dbSDimitry Andric ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) const{
11465ffd83dbSDimitry Andric   return GetPlans().GetPreviousPlan(current_plan);
11470b57cec5SDimitry Andric }
11480b57cec5SDimitry Andric 
QueueThreadPlan(ThreadPlanSP & thread_plan_sp,bool abort_other_plans)11490b57cec5SDimitry Andric Status Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp,
11500b57cec5SDimitry Andric                                bool abort_other_plans) {
11510b57cec5SDimitry Andric   Status status;
11520b57cec5SDimitry Andric   StreamString s;
11530b57cec5SDimitry Andric   if (!thread_plan_sp->ValidatePlan(&s)) {
11540b57cec5SDimitry Andric     DiscardThreadPlansUpToPlan(thread_plan_sp);
11550b57cec5SDimitry Andric     thread_plan_sp.reset();
11560b57cec5SDimitry Andric     status.SetErrorString(s.GetString());
11570b57cec5SDimitry Andric     return status;
11580b57cec5SDimitry Andric   }
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric   if (abort_other_plans)
11610b57cec5SDimitry Andric     DiscardThreadPlans(true);
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric   PushPlan(thread_plan_sp);
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   // This seems a little funny, but I don't want to have to split up the
11660b57cec5SDimitry Andric   // constructor and the DidPush in the scripted plan, that seems annoying.
11670b57cec5SDimitry Andric   // That means the constructor has to be in DidPush. So I have to validate the
11680b57cec5SDimitry Andric   // plan AFTER pushing it, and then take it off again...
11690b57cec5SDimitry Andric   if (!thread_plan_sp->ValidatePlan(&s)) {
11700b57cec5SDimitry Andric     DiscardThreadPlansUpToPlan(thread_plan_sp);
11710b57cec5SDimitry Andric     thread_plan_sp.reset();
11720b57cec5SDimitry Andric     status.SetErrorString(s.GetString());
11730b57cec5SDimitry Andric     return status;
11740b57cec5SDimitry Andric   }
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric   return status;
11770b57cec5SDimitry Andric }
11780b57cec5SDimitry Andric 
DiscardUserThreadPlansUpToIndex(uint32_t plan_index)11795ffd83dbSDimitry Andric bool Thread::DiscardUserThreadPlansUpToIndex(uint32_t plan_index) {
11800b57cec5SDimitry Andric   // Count the user thread plans from the back end to get the number of the one
11810b57cec5SDimitry Andric   // we want to discard:
11820b57cec5SDimitry Andric 
11835ffd83dbSDimitry Andric   ThreadPlan *up_to_plan_ptr = GetPlans().GetPlanByIndex(plan_index).get();
11840b57cec5SDimitry Andric   if (up_to_plan_ptr == nullptr)
11850b57cec5SDimitry Andric     return false;
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric   DiscardThreadPlansUpToPlan(up_to_plan_ptr);
11880b57cec5SDimitry Andric   return true;
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric 
DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP & up_to_plan_sp)11910b57cec5SDimitry Andric void Thread::DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP &up_to_plan_sp) {
11920b57cec5SDimitry Andric   DiscardThreadPlansUpToPlan(up_to_plan_sp.get());
11930b57cec5SDimitry Andric }
11940b57cec5SDimitry Andric 
DiscardThreadPlansUpToPlan(ThreadPlan * up_to_plan_ptr)11950b57cec5SDimitry Andric void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) {
119681ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
11979dba64beSDimitry Andric   LLDB_LOGF(log,
11989dba64beSDimitry Andric             "Discarding thread plans for thread tid = 0x%4.4" PRIx64
11990b57cec5SDimitry Andric             ", up to %p",
12000b57cec5SDimitry Andric             GetID(), static_cast<void *>(up_to_plan_ptr));
12015ffd83dbSDimitry Andric   GetPlans().DiscardPlansUpToPlan(up_to_plan_ptr);
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
DiscardThreadPlans(bool force)12040b57cec5SDimitry Andric void Thread::DiscardThreadPlans(bool force) {
120581ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
12060b57cec5SDimitry Andric   if (log) {
12079dba64beSDimitry Andric     LLDB_LOGF(log,
12089dba64beSDimitry Andric               "Discarding thread plans for thread (tid = 0x%4.4" PRIx64
12090b57cec5SDimitry Andric               ", force %d)",
12100b57cec5SDimitry Andric               GetID(), force);
12110b57cec5SDimitry Andric   }
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric   if (force) {
12145ffd83dbSDimitry Andric     GetPlans().DiscardAllPlans();
12150b57cec5SDimitry Andric     return;
12160b57cec5SDimitry Andric   }
1217349cc55cSDimitry Andric   GetPlans().DiscardConsultingControllingPlans();
12180b57cec5SDimitry Andric }
12190b57cec5SDimitry Andric 
UnwindInnermostExpression()12200b57cec5SDimitry Andric Status Thread::UnwindInnermostExpression() {
12210b57cec5SDimitry Andric   Status error;
12225ffd83dbSDimitry Andric   ThreadPlan *innermost_expr_plan = GetPlans().GetInnermostExpression();
12235ffd83dbSDimitry Andric   if (!innermost_expr_plan) {
12245ffd83dbSDimitry Andric     error.SetErrorString("No expressions currently active on this thread");
12250b57cec5SDimitry Andric     return error;
12260b57cec5SDimitry Andric   }
12275ffd83dbSDimitry Andric   DiscardThreadPlansUpToPlan(innermost_expr_plan);
12280b57cec5SDimitry Andric   return error;
12290b57cec5SDimitry Andric }
12300b57cec5SDimitry Andric 
QueueBasePlan(bool abort_other_plans)1231fe6060f1SDimitry Andric ThreadPlanSP Thread::QueueBasePlan(bool abort_other_plans) {
12320b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanBase(*this));
12330b57cec5SDimitry Andric   QueueThreadPlan(thread_plan_sp, abort_other_plans);
12340b57cec5SDimitry Andric   return thread_plan_sp;
12350b57cec5SDimitry Andric }
12360b57cec5SDimitry Andric 
QueueThreadPlanForStepSingleInstruction(bool step_over,bool abort_other_plans,bool stop_other_threads,Status & status)12370b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepSingleInstruction(
12380b57cec5SDimitry Andric     bool step_over, bool abort_other_plans, bool stop_other_threads,
12390b57cec5SDimitry Andric     Status &status) {
12400b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanStepInstruction(
12410b57cec5SDimitry Andric       *this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
12420b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
12430b57cec5SDimitry Andric   return thread_plan_sp;
12440b57cec5SDimitry Andric }
12450b57cec5SDimitry Andric 
QueueThreadPlanForStepOverRange(bool abort_other_plans,const AddressRange & range,const SymbolContext & addr_context,lldb::RunMode stop_other_threads,Status & status,LazyBool step_out_avoids_code_withoug_debug_info)12460b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
12470b57cec5SDimitry Andric     bool abort_other_plans, const AddressRange &range,
12480b57cec5SDimitry Andric     const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
12490b57cec5SDimitry Andric     Status &status, LazyBool step_out_avoids_code_withoug_debug_info) {
12500b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp;
12510b57cec5SDimitry Andric   thread_plan_sp = std::make_shared<ThreadPlanStepOverRange>(
12520b57cec5SDimitry Andric       *this, range, addr_context, stop_other_threads,
12530b57cec5SDimitry Andric       step_out_avoids_code_withoug_debug_info);
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
12560b57cec5SDimitry Andric   return thread_plan_sp;
12570b57cec5SDimitry Andric }
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric // Call the QueueThreadPlanForStepOverRange method which takes an address
12600b57cec5SDimitry Andric // range.
QueueThreadPlanForStepOverRange(bool abort_other_plans,const LineEntry & line_entry,const SymbolContext & addr_context,lldb::RunMode stop_other_threads,Status & status,LazyBool step_out_avoids_code_withoug_debug_info)12610b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
12620b57cec5SDimitry Andric     bool abort_other_plans, const LineEntry &line_entry,
12630b57cec5SDimitry Andric     const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
12640b57cec5SDimitry Andric     Status &status, LazyBool step_out_avoids_code_withoug_debug_info) {
12650b57cec5SDimitry Andric   const bool include_inlined_functions = true;
12660b57cec5SDimitry Andric   auto address_range =
12670b57cec5SDimitry Andric       line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
12680b57cec5SDimitry Andric   return QueueThreadPlanForStepOverRange(
12690b57cec5SDimitry Andric       abort_other_plans, address_range, addr_context, stop_other_threads,
12700b57cec5SDimitry Andric       status, step_out_avoids_code_withoug_debug_info);
12710b57cec5SDimitry Andric }
12720b57cec5SDimitry Andric 
QueueThreadPlanForStepInRange(bool abort_other_plans,const AddressRange & range,const SymbolContext & addr_context,const char * step_in_target,lldb::RunMode stop_other_threads,Status & status,LazyBool step_in_avoids_code_without_debug_info,LazyBool step_out_avoids_code_without_debug_info)12730b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
12740b57cec5SDimitry Andric     bool abort_other_plans, const AddressRange &range,
12750b57cec5SDimitry Andric     const SymbolContext &addr_context, const char *step_in_target,
12760b57cec5SDimitry Andric     lldb::RunMode stop_other_threads, Status &status,
12770b57cec5SDimitry Andric     LazyBool step_in_avoids_code_without_debug_info,
12780b57cec5SDimitry Andric     LazyBool step_out_avoids_code_without_debug_info) {
1279fe6060f1SDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanStepInRange(
1280fe6060f1SDimitry Andric       *this, range, addr_context, step_in_target, stop_other_threads,
12810b57cec5SDimitry Andric       step_in_avoids_code_without_debug_info,
12820b57cec5SDimitry Andric       step_out_avoids_code_without_debug_info));
12830b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
12840b57cec5SDimitry Andric   return thread_plan_sp;
12850b57cec5SDimitry Andric }
12860b57cec5SDimitry Andric 
12870b57cec5SDimitry Andric // Call the QueueThreadPlanForStepInRange method which takes an address range.
QueueThreadPlanForStepInRange(bool abort_other_plans,const LineEntry & line_entry,const SymbolContext & addr_context,const char * step_in_target,lldb::RunMode stop_other_threads,Status & status,LazyBool step_in_avoids_code_without_debug_info,LazyBool step_out_avoids_code_without_debug_info)12880b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
12890b57cec5SDimitry Andric     bool abort_other_plans, const LineEntry &line_entry,
12900b57cec5SDimitry Andric     const SymbolContext &addr_context, const char *step_in_target,
12910b57cec5SDimitry Andric     lldb::RunMode stop_other_threads, Status &status,
12920b57cec5SDimitry Andric     LazyBool step_in_avoids_code_without_debug_info,
12930b57cec5SDimitry Andric     LazyBool step_out_avoids_code_without_debug_info) {
12940b57cec5SDimitry Andric   const bool include_inlined_functions = false;
12950b57cec5SDimitry Andric   return QueueThreadPlanForStepInRange(
12960b57cec5SDimitry Andric       abort_other_plans,
12970b57cec5SDimitry Andric       line_entry.GetSameLineContiguousAddressRange(include_inlined_functions),
12980b57cec5SDimitry Andric       addr_context, step_in_target, stop_other_threads, status,
12990b57cec5SDimitry Andric       step_in_avoids_code_without_debug_info,
13000b57cec5SDimitry Andric       step_out_avoids_code_without_debug_info);
13010b57cec5SDimitry Andric }
13020b57cec5SDimitry Andric 
QueueThreadPlanForStepOut(bool abort_other_plans,SymbolContext * addr_context,bool first_insn,bool stop_other_threads,Vote report_stop_vote,Vote report_run_vote,uint32_t frame_idx,Status & status,LazyBool step_out_avoids_code_without_debug_info)13030b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepOut(
13040b57cec5SDimitry Andric     bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
1305fe6060f1SDimitry Andric     bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote,
1306fe6060f1SDimitry Andric     uint32_t frame_idx, Status &status,
1307fe6060f1SDimitry Andric     LazyBool step_out_avoids_code_without_debug_info) {
13080b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut(
1309fe6060f1SDimitry Andric       *this, addr_context, first_insn, stop_other_threads, report_stop_vote,
1310fe6060f1SDimitry Andric       report_run_vote, frame_idx, step_out_avoids_code_without_debug_info));
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
13130b57cec5SDimitry Andric   return thread_plan_sp;
13140b57cec5SDimitry Andric }
13150b57cec5SDimitry Andric 
QueueThreadPlanForStepOutNoShouldStop(bool abort_other_plans,SymbolContext * addr_context,bool first_insn,bool stop_other_threads,Vote report_stop_vote,Vote report_run_vote,uint32_t frame_idx,Status & status,bool continue_to_next_branch)13160b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepOutNoShouldStop(
13170b57cec5SDimitry Andric     bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
1318fe6060f1SDimitry Andric     bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote,
1319fe6060f1SDimitry Andric     uint32_t frame_idx, Status &status, bool continue_to_next_branch) {
13200b57cec5SDimitry Andric   const bool calculate_return_value =
13210b57cec5SDimitry Andric       false; // No need to calculate the return value here.
13220b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut(
1323fe6060f1SDimitry Andric       *this, addr_context, first_insn, stop_other_threads, report_stop_vote,
1324fe6060f1SDimitry Andric       report_run_vote, frame_idx, eLazyBoolNo, continue_to_next_branch,
1325fe6060f1SDimitry Andric       calculate_return_value));
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric   ThreadPlanStepOut *new_plan =
13280b57cec5SDimitry Andric       static_cast<ThreadPlanStepOut *>(thread_plan_sp.get());
13290b57cec5SDimitry Andric   new_plan->ClearShouldStopHereCallbacks();
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
13320b57cec5SDimitry Andric   return thread_plan_sp;
13330b57cec5SDimitry Andric }
13340b57cec5SDimitry Andric 
QueueThreadPlanForStepThrough(StackID & return_stack_id,bool abort_other_plans,bool stop_other_threads,Status & status)13350b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepThrough(StackID &return_stack_id,
13360b57cec5SDimitry Andric                                                    bool abort_other_plans,
13370b57cec5SDimitry Andric                                                    bool stop_other_threads,
13380b57cec5SDimitry Andric                                                    Status &status) {
13390b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(
13400b57cec5SDimitry Andric       new ThreadPlanStepThrough(*this, return_stack_id, stop_other_threads));
13410b57cec5SDimitry Andric   if (!thread_plan_sp || !thread_plan_sp->ValidatePlan(nullptr))
13420b57cec5SDimitry Andric     return ThreadPlanSP();
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
13450b57cec5SDimitry Andric   return thread_plan_sp;
13460b57cec5SDimitry Andric }
13470b57cec5SDimitry Andric 
QueueThreadPlanForRunToAddress(bool abort_other_plans,Address & target_addr,bool stop_other_threads,Status & status)13480b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForRunToAddress(bool abort_other_plans,
13490b57cec5SDimitry Andric                                                     Address &target_addr,
13500b57cec5SDimitry Andric                                                     bool stop_other_threads,
13510b57cec5SDimitry Andric                                                     Status &status) {
13520b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(
13530b57cec5SDimitry Andric       new ThreadPlanRunToAddress(*this, target_addr, stop_other_threads));
13540b57cec5SDimitry Andric 
13550b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
13560b57cec5SDimitry Andric   return thread_plan_sp;
13570b57cec5SDimitry Andric }
13580b57cec5SDimitry Andric 
QueueThreadPlanForStepUntil(bool abort_other_plans,lldb::addr_t * address_list,size_t num_addresses,bool stop_other_threads,uint32_t frame_idx,Status & status)13590b57cec5SDimitry Andric ThreadPlanSP Thread::QueueThreadPlanForStepUntil(
13600b57cec5SDimitry Andric     bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses,
13610b57cec5SDimitry Andric     bool stop_other_threads, uint32_t frame_idx, Status &status) {
13620b57cec5SDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanStepUntil(
13630b57cec5SDimitry Andric       *this, address_list, num_addresses, stop_other_threads, frame_idx));
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
13660b57cec5SDimitry Andric   return thread_plan_sp;
13670b57cec5SDimitry Andric }
13680b57cec5SDimitry Andric 
QueueThreadPlanForStepScripted(bool abort_other_plans,const char * class_name,StructuredData::ObjectSP extra_args_sp,bool stop_other_threads,Status & status)13690b57cec5SDimitry Andric lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
13709dba64beSDimitry Andric     bool abort_other_plans, const char *class_name,
13719dba64beSDimitry Andric     StructuredData::ObjectSP extra_args_sp, bool stop_other_threads,
13720b57cec5SDimitry Andric     Status &status) {
13739dba64beSDimitry Andric 
13740eae32dcSDimitry Andric   ThreadPlanSP thread_plan_sp(new ThreadPlanPython(
13750eae32dcSDimitry Andric       *this, class_name, StructuredDataImpl(extra_args_sp)));
1376e8d8bef9SDimitry Andric   thread_plan_sp->SetStopOthers(stop_other_threads);
13770b57cec5SDimitry Andric   status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
13780b57cec5SDimitry Andric   return thread_plan_sp;
13790b57cec5SDimitry Andric }
13800b57cec5SDimitry Andric 
GetIndexID() const13810b57cec5SDimitry Andric uint32_t Thread::GetIndexID() const { return m_index_id; }
13820b57cec5SDimitry Andric 
CalculateTarget()13830b57cec5SDimitry Andric TargetSP Thread::CalculateTarget() {
13840b57cec5SDimitry Andric   TargetSP target_sp;
13850b57cec5SDimitry Andric   ProcessSP process_sp(GetProcess());
13860b57cec5SDimitry Andric   if (process_sp)
13870b57cec5SDimitry Andric     target_sp = process_sp->CalculateTarget();
13880b57cec5SDimitry Andric   return target_sp;
13890b57cec5SDimitry Andric }
13900b57cec5SDimitry Andric 
CalculateProcess()13910b57cec5SDimitry Andric ProcessSP Thread::CalculateProcess() { return GetProcess(); }
13920b57cec5SDimitry Andric 
CalculateThread()13930b57cec5SDimitry Andric ThreadSP Thread::CalculateThread() { return shared_from_this(); }
13940b57cec5SDimitry Andric 
CalculateStackFrame()13950b57cec5SDimitry Andric StackFrameSP Thread::CalculateStackFrame() { return StackFrameSP(); }
13960b57cec5SDimitry Andric 
CalculateExecutionContext(ExecutionContext & exe_ctx)13970b57cec5SDimitry Andric void Thread::CalculateExecutionContext(ExecutionContext &exe_ctx) {
13980b57cec5SDimitry Andric   exe_ctx.SetContext(shared_from_this());
13990b57cec5SDimitry Andric }
14000b57cec5SDimitry Andric 
GetStackFrameList()14010b57cec5SDimitry Andric StackFrameListSP Thread::GetStackFrameList() {
14020b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric   if (!m_curr_frames_sp)
14050b57cec5SDimitry Andric     m_curr_frames_sp =
14060b57cec5SDimitry Andric         std::make_shared<StackFrameList>(*this, m_prev_frames_sp, true);
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric   return m_curr_frames_sp;
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric 
ClearStackFrames()14110b57cec5SDimitry Andric void Thread::ClearStackFrames() {
14120b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
14130b57cec5SDimitry Andric 
14145ffd83dbSDimitry Andric   GetUnwinder().Clear();
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric   // Only store away the old "reference" StackFrameList if we got all its
14170b57cec5SDimitry Andric   // frames:
14180b57cec5SDimitry Andric   // FIXME: At some point we can try to splice in the frames we have fetched
14190b57cec5SDimitry Andric   // into
14200b57cec5SDimitry Andric   // the new frame as we make it, but let's not try that now.
14210b57cec5SDimitry Andric   if (m_curr_frames_sp && m_curr_frames_sp->GetAllFramesFetched())
14220b57cec5SDimitry Andric     m_prev_frames_sp.swap(m_curr_frames_sp);
14230b57cec5SDimitry Andric   m_curr_frames_sp.reset();
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric   m_extended_info.reset();
14260b57cec5SDimitry Andric   m_extended_info_fetched = false;
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric 
GetFrameWithConcreteFrameIndex(uint32_t unwind_idx)14290b57cec5SDimitry Andric lldb::StackFrameSP Thread::GetFrameWithConcreteFrameIndex(uint32_t unwind_idx) {
14300b57cec5SDimitry Andric   return GetStackFrameList()->GetFrameWithConcreteFrameIndex(unwind_idx);
14310b57cec5SDimitry Andric }
14320b57cec5SDimitry Andric 
ReturnFromFrameWithIndex(uint32_t frame_idx,lldb::ValueObjectSP return_value_sp,bool broadcast)14330b57cec5SDimitry Andric Status Thread::ReturnFromFrameWithIndex(uint32_t frame_idx,
14340b57cec5SDimitry Andric                                         lldb::ValueObjectSP return_value_sp,
14350b57cec5SDimitry Andric                                         bool broadcast) {
14360b57cec5SDimitry Andric   StackFrameSP frame_sp = GetStackFrameAtIndex(frame_idx);
14370b57cec5SDimitry Andric   Status return_error;
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   if (!frame_sp) {
14400b57cec5SDimitry Andric     return_error.SetErrorStringWithFormat(
14410b57cec5SDimitry Andric         "Could not find frame with index %d in thread 0x%" PRIx64 ".",
14420b57cec5SDimitry Andric         frame_idx, GetID());
14430b57cec5SDimitry Andric   }
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric   return ReturnFromFrame(frame_sp, return_value_sp, broadcast);
14460b57cec5SDimitry Andric }
14470b57cec5SDimitry Andric 
ReturnFromFrame(lldb::StackFrameSP frame_sp,lldb::ValueObjectSP return_value_sp,bool broadcast)14480b57cec5SDimitry Andric Status Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp,
14490b57cec5SDimitry Andric                                lldb::ValueObjectSP return_value_sp,
14500b57cec5SDimitry Andric                                bool broadcast) {
14510b57cec5SDimitry Andric   Status return_error;
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric   if (!frame_sp) {
14540b57cec5SDimitry Andric     return_error.SetErrorString("Can't return to a null frame.");
14550b57cec5SDimitry Andric     return return_error;
14560b57cec5SDimitry Andric   }
14570b57cec5SDimitry Andric 
14580b57cec5SDimitry Andric   Thread *thread = frame_sp->GetThread().get();
14590b57cec5SDimitry Andric   uint32_t older_frame_idx = frame_sp->GetFrameIndex() + 1;
14600b57cec5SDimitry Andric   StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx);
14610b57cec5SDimitry Andric   if (!older_frame_sp) {
14620b57cec5SDimitry Andric     return_error.SetErrorString("No older frame to return to.");
14630b57cec5SDimitry Andric     return return_error;
14640b57cec5SDimitry Andric   }
14650b57cec5SDimitry Andric 
14660b57cec5SDimitry Andric   if (return_value_sp) {
14670b57cec5SDimitry Andric     lldb::ABISP abi = thread->GetProcess()->GetABI();
14680b57cec5SDimitry Andric     if (!abi) {
14690b57cec5SDimitry Andric       return_error.SetErrorString("Could not find ABI to set return value.");
14700b57cec5SDimitry Andric       return return_error;
14710b57cec5SDimitry Andric     }
14720b57cec5SDimitry Andric     SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextFunction);
14730b57cec5SDimitry Andric 
14740b57cec5SDimitry Andric     // FIXME: ValueObject::Cast doesn't currently work correctly, at least not
14750b57cec5SDimitry Andric     // for scalars.
14760b57cec5SDimitry Andric     // Turn that back on when that works.
14770b57cec5SDimitry Andric     if (/* DISABLES CODE */ (false) && sc.function != nullptr) {
14780b57cec5SDimitry Andric       Type *function_type = sc.function->GetType();
14790b57cec5SDimitry Andric       if (function_type) {
14800b57cec5SDimitry Andric         CompilerType return_type =
14810b57cec5SDimitry Andric             sc.function->GetCompilerType().GetFunctionReturnType();
14820b57cec5SDimitry Andric         if (return_type) {
14830b57cec5SDimitry Andric           StreamString s;
14840b57cec5SDimitry Andric           return_type.DumpTypeDescription(&s);
14850b57cec5SDimitry Andric           ValueObjectSP cast_value_sp = return_value_sp->Cast(return_type);
14860b57cec5SDimitry Andric           if (cast_value_sp) {
14870b57cec5SDimitry Andric             cast_value_sp->SetFormat(eFormatHex);
14880b57cec5SDimitry Andric             return_value_sp = cast_value_sp;
14890b57cec5SDimitry Andric           }
14900b57cec5SDimitry Andric         }
14910b57cec5SDimitry Andric       }
14920b57cec5SDimitry Andric     }
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric     return_error = abi->SetReturnValueObject(older_frame_sp, return_value_sp);
14950b57cec5SDimitry Andric     if (!return_error.Success())
14960b57cec5SDimitry Andric       return return_error;
14970b57cec5SDimitry Andric   }
14980b57cec5SDimitry Andric 
14990b57cec5SDimitry Andric   // Now write the return registers for the chosen frame: Note, we can't use
15000b57cec5SDimitry Andric   // ReadAllRegisterValues->WriteAllRegisterValues, since the read & write cook
15010b57cec5SDimitry Andric   // their data
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric   StackFrameSP youngest_frame_sp = thread->GetStackFrameAtIndex(0);
15040b57cec5SDimitry Andric   if (youngest_frame_sp) {
15050b57cec5SDimitry Andric     lldb::RegisterContextSP reg_ctx_sp(youngest_frame_sp->GetRegisterContext());
15060b57cec5SDimitry Andric     if (reg_ctx_sp) {
15070b57cec5SDimitry Andric       bool copy_success = reg_ctx_sp->CopyFromRegisterContext(
15080b57cec5SDimitry Andric           older_frame_sp->GetRegisterContext());
15090b57cec5SDimitry Andric       if (copy_success) {
15100b57cec5SDimitry Andric         thread->DiscardThreadPlans(true);
15110b57cec5SDimitry Andric         thread->ClearStackFrames();
1512*a58f00eaSDimitry Andric         if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged)) {
1513*a58f00eaSDimitry Andric           auto data_sp = std::make_shared<ThreadEventData>(shared_from_this());
1514*a58f00eaSDimitry Andric           BroadcastEvent(eBroadcastBitStackChanged, data_sp);
1515*a58f00eaSDimitry Andric         }
15160b57cec5SDimitry Andric       } else {
15170b57cec5SDimitry Andric         return_error.SetErrorString("Could not reset register values.");
15180b57cec5SDimitry Andric       }
15190b57cec5SDimitry Andric     } else {
15200b57cec5SDimitry Andric       return_error.SetErrorString("Frame has no register context.");
15210b57cec5SDimitry Andric     }
15220b57cec5SDimitry Andric   } else {
15230b57cec5SDimitry Andric     return_error.SetErrorString("Returned past top frame.");
15240b57cec5SDimitry Andric   }
15250b57cec5SDimitry Andric   return return_error;
15260b57cec5SDimitry Andric }
15270b57cec5SDimitry Andric 
DumpAddressList(Stream & s,const std::vector<Address> & list,ExecutionContextScope * exe_scope)15280b57cec5SDimitry Andric static void DumpAddressList(Stream &s, const std::vector<Address> &list,
15290b57cec5SDimitry Andric                             ExecutionContextScope *exe_scope) {
15300b57cec5SDimitry Andric   for (size_t n = 0; n < list.size(); n++) {
15310b57cec5SDimitry Andric     s << "\t";
15320b57cec5SDimitry Andric     list[n].Dump(&s, exe_scope, Address::DumpStyleResolvedDescription,
15330b57cec5SDimitry Andric                  Address::DumpStyleSectionNameOffset);
15340b57cec5SDimitry Andric     s << "\n";
15350b57cec5SDimitry Andric   }
15360b57cec5SDimitry Andric }
15370b57cec5SDimitry Andric 
JumpToLine(const FileSpec & file,uint32_t line,bool can_leave_function,std::string * warnings)15380b57cec5SDimitry Andric Status Thread::JumpToLine(const FileSpec &file, uint32_t line,
15390b57cec5SDimitry Andric                           bool can_leave_function, std::string *warnings) {
15400b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetStackFrameAtIndex(0));
15410b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
15420b57cec5SDimitry Andric   TargetSP target_sp = exe_ctx.GetTargetSP();
15430b57cec5SDimitry Andric   RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
15440b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
15450b57cec5SDimitry Andric   const SymbolContext &sc = frame->GetSymbolContext(eSymbolContextFunction);
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric   // Find candidate locations.
15480b57cec5SDimitry Andric   std::vector<Address> candidates, within_function, outside_function;
15490b57cec5SDimitry Andric   target->GetImages().FindAddressesForLine(target_sp, file, line, sc.function,
15500b57cec5SDimitry Andric                                            within_function, outside_function);
15510b57cec5SDimitry Andric 
15520b57cec5SDimitry Andric   // If possible, we try and stay within the current function. Within a
15530b57cec5SDimitry Andric   // function, we accept multiple locations (optimized code may do this,
15540b57cec5SDimitry Andric   // there's no solution here so we do the best we can). However if we're
15550b57cec5SDimitry Andric   // trying to leave the function, we don't know how to pick the right
15560b57cec5SDimitry Andric   // location, so if there's more than one then we bail.
15570b57cec5SDimitry Andric   if (!within_function.empty())
15580b57cec5SDimitry Andric     candidates = within_function;
15590b57cec5SDimitry Andric   else if (outside_function.size() == 1 && can_leave_function)
15600b57cec5SDimitry Andric     candidates = outside_function;
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric   // Check if we got anything.
15630b57cec5SDimitry Andric   if (candidates.empty()) {
15640b57cec5SDimitry Andric     if (outside_function.empty()) {
15650b57cec5SDimitry Andric       return Status("Cannot locate an address for %s:%i.",
15660b57cec5SDimitry Andric                     file.GetFilename().AsCString(), line);
15670b57cec5SDimitry Andric     } else if (outside_function.size() == 1) {
15680b57cec5SDimitry Andric       return Status("%s:%i is outside the current function.",
15690b57cec5SDimitry Andric                     file.GetFilename().AsCString(), line);
15700b57cec5SDimitry Andric     } else {
15710b57cec5SDimitry Andric       StreamString sstr;
15720b57cec5SDimitry Andric       DumpAddressList(sstr, outside_function, target);
15730b57cec5SDimitry Andric       return Status("%s:%i has multiple candidate locations:\n%s",
15740b57cec5SDimitry Andric                     file.GetFilename().AsCString(), line, sstr.GetData());
15750b57cec5SDimitry Andric     }
15760b57cec5SDimitry Andric   }
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric   // Accept the first location, warn about any others.
15790b57cec5SDimitry Andric   Address dest = candidates[0];
15800b57cec5SDimitry Andric   if (warnings && candidates.size() > 1) {
15810b57cec5SDimitry Andric     StreamString sstr;
15820b57cec5SDimitry Andric     sstr.Printf("%s:%i appears multiple times in this function, selecting the "
15830b57cec5SDimitry Andric                 "first location:\n",
15840b57cec5SDimitry Andric                 file.GetFilename().AsCString(), line);
15850b57cec5SDimitry Andric     DumpAddressList(sstr, candidates, target);
15865ffd83dbSDimitry Andric     *warnings = std::string(sstr.GetString());
15870b57cec5SDimitry Andric   }
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric   if (!reg_ctx->SetPC(dest))
15900b57cec5SDimitry Andric     return Status("Cannot change PC to target address.");
15910b57cec5SDimitry Andric 
15920b57cec5SDimitry Andric   return Status();
15930b57cec5SDimitry Andric }
15940b57cec5SDimitry Andric 
DumpUsingFormat(Stream & strm,uint32_t frame_idx,const FormatEntity::Entry * format)1595c9157d92SDimitry Andric bool Thread::DumpUsingFormat(Stream &strm, uint32_t frame_idx,
1596c9157d92SDimitry Andric                              const FormatEntity::Entry *format) {
15970b57cec5SDimitry Andric   ExecutionContext exe_ctx(shared_from_this());
15980b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1599c9157d92SDimitry Andric   if (!process || !format)
1600c9157d92SDimitry Andric     return false;
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric   StackFrameSP frame_sp;
16030b57cec5SDimitry Andric   SymbolContext frame_sc;
16040b57cec5SDimitry Andric   if (frame_idx != LLDB_INVALID_FRAME_ID) {
16050b57cec5SDimitry Andric     frame_sp = GetStackFrameAtIndex(frame_idx);
16060b57cec5SDimitry Andric     if (frame_sp) {
16070b57cec5SDimitry Andric       exe_ctx.SetFrameSP(frame_sp);
16080b57cec5SDimitry Andric       frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
16090b57cec5SDimitry Andric     }
16100b57cec5SDimitry Andric   }
16110b57cec5SDimitry Andric 
1612c9157d92SDimitry Andric   return FormatEntity::Format(*format, strm, frame_sp ? &frame_sc : nullptr,
1613c9157d92SDimitry Andric                               &exe_ctx, nullptr, nullptr, false, false);
1614c9157d92SDimitry Andric }
1615c9157d92SDimitry Andric 
DumpUsingSettingsFormat(Stream & strm,uint32_t frame_idx,bool stop_format)1616c9157d92SDimitry Andric void Thread::DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx,
1617c9157d92SDimitry Andric                                      bool stop_format) {
1618c9157d92SDimitry Andric   ExecutionContext exe_ctx(shared_from_this());
1619c9157d92SDimitry Andric 
16200b57cec5SDimitry Andric   const FormatEntity::Entry *thread_format;
16210b57cec5SDimitry Andric   if (stop_format)
16220b57cec5SDimitry Andric     thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadStopFormat();
16230b57cec5SDimitry Andric   else
16240b57cec5SDimitry Andric     thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat();
16250b57cec5SDimitry Andric 
16260b57cec5SDimitry Andric   assert(thread_format);
16270b57cec5SDimitry Andric 
1628c9157d92SDimitry Andric   DumpUsingFormat(strm, frame_idx, thread_format);
16290b57cec5SDimitry Andric }
16300b57cec5SDimitry Andric 
SettingsInitialize()16310b57cec5SDimitry Andric void Thread::SettingsInitialize() {}
16320b57cec5SDimitry Andric 
SettingsTerminate()16330b57cec5SDimitry Andric void Thread::SettingsTerminate() {}
16340b57cec5SDimitry Andric 
GetThreadPointer()1635c9157d92SDimitry Andric lldb::addr_t Thread::GetThreadPointer() {
1636c9157d92SDimitry Andric   if (m_reg_context_sp)
1637c9157d92SDimitry Andric     return m_reg_context_sp->GetThreadPointer();
1638c9157d92SDimitry Andric   return LLDB_INVALID_ADDRESS;
1639c9157d92SDimitry Andric }
16400b57cec5SDimitry Andric 
GetThreadLocalData(const ModuleSP module,lldb::addr_t tls_file_addr)16410b57cec5SDimitry Andric addr_t Thread::GetThreadLocalData(const ModuleSP module,
16420b57cec5SDimitry Andric                                   lldb::addr_t tls_file_addr) {
16430b57cec5SDimitry Andric   // The default implementation is to ask the dynamic loader for it. This can
16440b57cec5SDimitry Andric   // be overridden for specific platforms.
16450b57cec5SDimitry Andric   DynamicLoader *loader = GetProcess()->GetDynamicLoader();
16460b57cec5SDimitry Andric   if (loader)
16470b57cec5SDimitry Andric     return loader->GetThreadLocalData(module, shared_from_this(),
16480b57cec5SDimitry Andric                                       tls_file_addr);
16490b57cec5SDimitry Andric   else
16500b57cec5SDimitry Andric     return LLDB_INVALID_ADDRESS;
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric 
SafeToCallFunctions()16530b57cec5SDimitry Andric bool Thread::SafeToCallFunctions() {
16540b57cec5SDimitry Andric   Process *process = GetProcess().get();
16550b57cec5SDimitry Andric   if (process) {
1656bdd1243dSDimitry Andric     DynamicLoader *loader = GetProcess()->GetDynamicLoader();
1657bdd1243dSDimitry Andric     if (loader && loader->IsFullyInitialized() == false)
1658bdd1243dSDimitry Andric       return false;
1659bdd1243dSDimitry Andric 
16600b57cec5SDimitry Andric     SystemRuntime *runtime = process->GetSystemRuntime();
16610b57cec5SDimitry Andric     if (runtime) {
16620b57cec5SDimitry Andric       return runtime->SafeToCallFunctionsOnThisThread(shared_from_this());
16630b57cec5SDimitry Andric     }
16640b57cec5SDimitry Andric   }
16650b57cec5SDimitry Andric   return true;
16660b57cec5SDimitry Andric }
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric lldb::StackFrameSP
GetStackFrameSPForStackFramePtr(StackFrame * stack_frame_ptr)16690b57cec5SDimitry Andric Thread::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
16700b57cec5SDimitry Andric   return GetStackFrameList()->GetStackFrameSPForStackFramePtr(stack_frame_ptr);
16710b57cec5SDimitry Andric }
16720b57cec5SDimitry Andric 
StopReasonAsString(lldb::StopReason reason)1673e8d8bef9SDimitry Andric std::string Thread::StopReasonAsString(lldb::StopReason reason) {
16740b57cec5SDimitry Andric   switch (reason) {
16750b57cec5SDimitry Andric   case eStopReasonInvalid:
16760b57cec5SDimitry Andric     return "invalid";
16770b57cec5SDimitry Andric   case eStopReasonNone:
16780b57cec5SDimitry Andric     return "none";
16790b57cec5SDimitry Andric   case eStopReasonTrace:
16800b57cec5SDimitry Andric     return "trace";
16810b57cec5SDimitry Andric   case eStopReasonBreakpoint:
16820b57cec5SDimitry Andric     return "breakpoint";
16830b57cec5SDimitry Andric   case eStopReasonWatchpoint:
16840b57cec5SDimitry Andric     return "watchpoint";
16850b57cec5SDimitry Andric   case eStopReasonSignal:
16860b57cec5SDimitry Andric     return "signal";
16870b57cec5SDimitry Andric   case eStopReasonException:
16880b57cec5SDimitry Andric     return "exception";
16890b57cec5SDimitry Andric   case eStopReasonExec:
16900b57cec5SDimitry Andric     return "exec";
1691fe6060f1SDimitry Andric   case eStopReasonFork:
1692fe6060f1SDimitry Andric     return "fork";
1693fe6060f1SDimitry Andric   case eStopReasonVFork:
1694fe6060f1SDimitry Andric     return "vfork";
1695fe6060f1SDimitry Andric   case eStopReasonVForkDone:
1696fe6060f1SDimitry Andric     return "vfork done";
16970b57cec5SDimitry Andric   case eStopReasonPlanComplete:
16980b57cec5SDimitry Andric     return "plan complete";
16990b57cec5SDimitry Andric   case eStopReasonThreadExiting:
17000b57cec5SDimitry Andric     return "thread exiting";
17010b57cec5SDimitry Andric   case eStopReasonInstrumentation:
17020b57cec5SDimitry Andric     return "instrumentation break";
1703fe6060f1SDimitry Andric   case eStopReasonProcessorTrace:
1704fe6060f1SDimitry Andric     return "processor trace";
17050b57cec5SDimitry Andric   }
17060b57cec5SDimitry Andric 
1707e8d8bef9SDimitry Andric   return "StopReason = " + std::to_string(reason);
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric 
RunModeAsString(lldb::RunMode mode)1710e8d8bef9SDimitry Andric std::string Thread::RunModeAsString(lldb::RunMode mode) {
17110b57cec5SDimitry Andric   switch (mode) {
17120b57cec5SDimitry Andric   case eOnlyThisThread:
17130b57cec5SDimitry Andric     return "only this thread";
17140b57cec5SDimitry Andric   case eAllThreads:
17150b57cec5SDimitry Andric     return "all threads";
17160b57cec5SDimitry Andric   case eOnlyDuringStepping:
17170b57cec5SDimitry Andric     return "only during stepping";
17180b57cec5SDimitry Andric   }
17190b57cec5SDimitry Andric 
1720e8d8bef9SDimitry Andric   return "RunMode = " + std::to_string(mode);
17210b57cec5SDimitry Andric }
17220b57cec5SDimitry Andric 
GetStatus(Stream & strm,uint32_t start_frame,uint32_t num_frames,uint32_t num_frames_with_source,bool stop_format,bool only_stacks)17230b57cec5SDimitry Andric size_t Thread::GetStatus(Stream &strm, uint32_t start_frame,
17240b57cec5SDimitry Andric                          uint32_t num_frames, uint32_t num_frames_with_source,
17250b57cec5SDimitry Andric                          bool stop_format, bool only_stacks) {
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric   if (!only_stacks) {
17280b57cec5SDimitry Andric     ExecutionContext exe_ctx(shared_from_this());
17290b57cec5SDimitry Andric     Target *target = exe_ctx.GetTargetPtr();
17300b57cec5SDimitry Andric     Process *process = exe_ctx.GetProcessPtr();
17310b57cec5SDimitry Andric     strm.Indent();
17320b57cec5SDimitry Andric     bool is_selected = false;
17330b57cec5SDimitry Andric     if (process) {
17340b57cec5SDimitry Andric       if (process->GetThreadList().GetSelectedThread().get() == this)
17350b57cec5SDimitry Andric         is_selected = true;
17360b57cec5SDimitry Andric     }
17370b57cec5SDimitry Andric     strm.Printf("%c ", is_selected ? '*' : ' ');
17380b57cec5SDimitry Andric     if (target && target->GetDebugger().GetUseExternalEditor()) {
17390b57cec5SDimitry Andric       StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame);
17400b57cec5SDimitry Andric       if (frame_sp) {
17410b57cec5SDimitry Andric         SymbolContext frame_sc(
17420b57cec5SDimitry Andric             frame_sp->GetSymbolContext(eSymbolContextLineEntry));
17430b57cec5SDimitry Andric         if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) {
1744fe013be4SDimitry Andric           if (llvm::Error e = Host::OpenFileInExternalEditor(
1745fe013be4SDimitry Andric                   target->GetDebugger().GetExternalEditor(),
1746fe013be4SDimitry Andric                   frame_sc.line_entry.file, frame_sc.line_entry.line)) {
1747fe013be4SDimitry Andric             LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e),
1748fe013be4SDimitry Andric                            "OpenFileInExternalEditor failed: {0}");
1749fe013be4SDimitry Andric           }
17500b57cec5SDimitry Andric         }
17510b57cec5SDimitry Andric       }
17520b57cec5SDimitry Andric     }
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric     DumpUsingSettingsFormat(strm, start_frame, stop_format);
17550b57cec5SDimitry Andric   }
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric   size_t num_frames_shown = 0;
17580b57cec5SDimitry Andric   if (num_frames > 0) {
17590b57cec5SDimitry Andric     strm.IndentMore();
17600b57cec5SDimitry Andric 
17610b57cec5SDimitry Andric     const bool show_frame_info = true;
17620b57cec5SDimitry Andric     const bool show_frame_unique = only_stacks;
17630b57cec5SDimitry Andric     const char *selected_frame_marker = nullptr;
17640b57cec5SDimitry Andric     if (num_frames == 1 || only_stacks ||
17650b57cec5SDimitry Andric         (GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID()))
17660b57cec5SDimitry Andric       strm.IndentMore();
17670b57cec5SDimitry Andric     else
17680b57cec5SDimitry Andric       selected_frame_marker = "* ";
17690b57cec5SDimitry Andric 
17700b57cec5SDimitry Andric     num_frames_shown = GetStackFrameList()->GetStatus(
17710b57cec5SDimitry Andric         strm, start_frame, num_frames, show_frame_info, num_frames_with_source,
17720b57cec5SDimitry Andric         show_frame_unique, selected_frame_marker);
17730b57cec5SDimitry Andric     if (num_frames == 1)
17740b57cec5SDimitry Andric       strm.IndentLess();
17750b57cec5SDimitry Andric     strm.IndentLess();
17760b57cec5SDimitry Andric   }
17770b57cec5SDimitry Andric   return num_frames_shown;
17780b57cec5SDimitry Andric }
17790b57cec5SDimitry Andric 
GetDescription(Stream & strm,lldb::DescriptionLevel level,bool print_json_thread,bool print_json_stopinfo)17800b57cec5SDimitry Andric bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level,
17810b57cec5SDimitry Andric                             bool print_json_thread, bool print_json_stopinfo) {
17820b57cec5SDimitry Andric   const bool stop_format = false;
17830b57cec5SDimitry Andric   DumpUsingSettingsFormat(strm, 0, stop_format);
17840b57cec5SDimitry Andric   strm.Printf("\n");
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric   StructuredData::ObjectSP thread_info = GetExtendedInfo();
17870b57cec5SDimitry Andric 
17880b57cec5SDimitry Andric   if (print_json_thread || print_json_stopinfo) {
17890b57cec5SDimitry Andric     if (thread_info && print_json_thread) {
17900b57cec5SDimitry Andric       thread_info->Dump(strm);
17910b57cec5SDimitry Andric       strm.Printf("\n");
17920b57cec5SDimitry Andric     }
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric     if (print_json_stopinfo && m_stop_info_sp) {
17950b57cec5SDimitry Andric       StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo();
17960b57cec5SDimitry Andric       if (stop_info) {
17970b57cec5SDimitry Andric         stop_info->Dump(strm);
17980b57cec5SDimitry Andric         strm.Printf("\n");
17990b57cec5SDimitry Andric       }
18000b57cec5SDimitry Andric     }
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric     return true;
18030b57cec5SDimitry Andric   }
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric   if (thread_info) {
18060b57cec5SDimitry Andric     StructuredData::ObjectSP activity =
18070b57cec5SDimitry Andric         thread_info->GetObjectForDotSeparatedPath("activity");
18080b57cec5SDimitry Andric     StructuredData::ObjectSP breadcrumb =
18090b57cec5SDimitry Andric         thread_info->GetObjectForDotSeparatedPath("breadcrumb");
18100b57cec5SDimitry Andric     StructuredData::ObjectSP messages =
18110b57cec5SDimitry Andric         thread_info->GetObjectForDotSeparatedPath("trace_messages");
18120b57cec5SDimitry Andric 
18130b57cec5SDimitry Andric     bool printed_activity = false;
18140b57cec5SDimitry Andric     if (activity && activity->GetType() == eStructuredDataTypeDictionary) {
18150b57cec5SDimitry Andric       StructuredData::Dictionary *activity_dict = activity->GetAsDictionary();
18160b57cec5SDimitry Andric       StructuredData::ObjectSP id = activity_dict->GetValueForKey("id");
18170b57cec5SDimitry Andric       StructuredData::ObjectSP name = activity_dict->GetValueForKey("name");
18180b57cec5SDimitry Andric       if (name && name->GetType() == eStructuredDataTypeString && id &&
18190b57cec5SDimitry Andric           id->GetType() == eStructuredDataTypeInteger) {
18200b57cec5SDimitry Andric         strm.Format("  Activity '{0}', {1:x}\n",
18210b57cec5SDimitry Andric                     name->GetAsString()->GetValue(),
1822fe013be4SDimitry Andric                     id->GetUnsignedIntegerValue());
18230b57cec5SDimitry Andric       }
18240b57cec5SDimitry Andric       printed_activity = true;
18250b57cec5SDimitry Andric     }
18260b57cec5SDimitry Andric     bool printed_breadcrumb = false;
18270b57cec5SDimitry Andric     if (breadcrumb && breadcrumb->GetType() == eStructuredDataTypeDictionary) {
18280b57cec5SDimitry Andric       if (printed_activity)
18290b57cec5SDimitry Andric         strm.Printf("\n");
18300b57cec5SDimitry Andric       StructuredData::Dictionary *breadcrumb_dict =
18310b57cec5SDimitry Andric           breadcrumb->GetAsDictionary();
18320b57cec5SDimitry Andric       StructuredData::ObjectSP breadcrumb_text =
18330b57cec5SDimitry Andric           breadcrumb_dict->GetValueForKey("name");
18340b57cec5SDimitry Andric       if (breadcrumb_text &&
18350b57cec5SDimitry Andric           breadcrumb_text->GetType() == eStructuredDataTypeString) {
18360b57cec5SDimitry Andric         strm.Format("  Current Breadcrumb: {0}\n",
18370b57cec5SDimitry Andric                     breadcrumb_text->GetAsString()->GetValue());
18380b57cec5SDimitry Andric       }
18390b57cec5SDimitry Andric       printed_breadcrumb = true;
18400b57cec5SDimitry Andric     }
18410b57cec5SDimitry Andric     if (messages && messages->GetType() == eStructuredDataTypeArray) {
18420b57cec5SDimitry Andric       if (printed_breadcrumb)
18430b57cec5SDimitry Andric         strm.Printf("\n");
18440b57cec5SDimitry Andric       StructuredData::Array *messages_array = messages->GetAsArray();
18450b57cec5SDimitry Andric       const size_t msg_count = messages_array->GetSize();
18460b57cec5SDimitry Andric       if (msg_count > 0) {
18470b57cec5SDimitry Andric         strm.Printf("  %zu trace messages:\n", msg_count);
18480b57cec5SDimitry Andric         for (size_t i = 0; i < msg_count; i++) {
18490b57cec5SDimitry Andric           StructuredData::ObjectSP message = messages_array->GetItemAtIndex(i);
18500b57cec5SDimitry Andric           if (message && message->GetType() == eStructuredDataTypeDictionary) {
18510b57cec5SDimitry Andric             StructuredData::Dictionary *message_dict =
18520b57cec5SDimitry Andric                 message->GetAsDictionary();
18530b57cec5SDimitry Andric             StructuredData::ObjectSP message_text =
18540b57cec5SDimitry Andric                 message_dict->GetValueForKey("message");
18550b57cec5SDimitry Andric             if (message_text &&
18560b57cec5SDimitry Andric                 message_text->GetType() == eStructuredDataTypeString) {
18570b57cec5SDimitry Andric               strm.Format("    {0}\n", message_text->GetAsString()->GetValue());
18580b57cec5SDimitry Andric             }
18590b57cec5SDimitry Andric           }
18600b57cec5SDimitry Andric         }
18610b57cec5SDimitry Andric       }
18620b57cec5SDimitry Andric     }
18630b57cec5SDimitry Andric   }
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric   return true;
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric 
GetStackFrameStatus(Stream & strm,uint32_t first_frame,uint32_t num_frames,bool show_frame_info,uint32_t num_frames_with_source)18680b57cec5SDimitry Andric size_t Thread::GetStackFrameStatus(Stream &strm, uint32_t first_frame,
18690b57cec5SDimitry Andric                                    uint32_t num_frames, bool show_frame_info,
18700b57cec5SDimitry Andric                                    uint32_t num_frames_with_source) {
18710b57cec5SDimitry Andric   return GetStackFrameList()->GetStatus(
18720b57cec5SDimitry Andric       strm, first_frame, num_frames, show_frame_info, num_frames_with_source);
18730b57cec5SDimitry Andric }
18740b57cec5SDimitry Andric 
GetUnwinder()18755ffd83dbSDimitry Andric Unwind &Thread::GetUnwinder() {
18765ffd83dbSDimitry Andric   if (!m_unwinder_up)
18775ffd83dbSDimitry Andric     m_unwinder_up = std::make_unique<UnwindLLDB>(*this);
18785ffd83dbSDimitry Andric   return *m_unwinder_up;
18790b57cec5SDimitry Andric }
18800b57cec5SDimitry Andric 
Flush()18810b57cec5SDimitry Andric void Thread::Flush() {
18820b57cec5SDimitry Andric   ClearStackFrames();
18830b57cec5SDimitry Andric   m_reg_context_sp.reset();
18840b57cec5SDimitry Andric }
18850b57cec5SDimitry Andric 
IsStillAtLastBreakpointHit()18860b57cec5SDimitry Andric bool Thread::IsStillAtLastBreakpointHit() {
18870b57cec5SDimitry Andric   // If we are currently stopped at a breakpoint, always return that stopinfo
18880b57cec5SDimitry Andric   // and don't reset it. This allows threads to maintain their breakpoint
18890b57cec5SDimitry Andric   // stopinfo, such as when thread-stepping in multithreaded programs.
18900b57cec5SDimitry Andric   if (m_stop_info_sp) {
18910b57cec5SDimitry Andric     StopReason stop_reason = m_stop_info_sp->GetStopReason();
18920b57cec5SDimitry Andric     if (stop_reason == lldb::eStopReasonBreakpoint) {
18930b57cec5SDimitry Andric       uint64_t value = m_stop_info_sp->GetValue();
18940b57cec5SDimitry Andric       lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
18950b57cec5SDimitry Andric       if (reg_ctx_sp) {
18960b57cec5SDimitry Andric         lldb::addr_t pc = reg_ctx_sp->GetPC();
18970b57cec5SDimitry Andric         BreakpointSiteSP bp_site_sp =
18980b57cec5SDimitry Andric             GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
18990b57cec5SDimitry Andric         if (bp_site_sp && static_cast<break_id_t>(value) == bp_site_sp->GetID())
19000b57cec5SDimitry Andric           return true;
19010b57cec5SDimitry Andric       }
19020b57cec5SDimitry Andric     }
19030b57cec5SDimitry Andric   }
19040b57cec5SDimitry Andric   return false;
19050b57cec5SDimitry Andric }
19060b57cec5SDimitry Andric 
StepIn(bool source_step,LazyBool step_in_avoids_code_without_debug_info,LazyBool step_out_avoids_code_without_debug_info)19070b57cec5SDimitry Andric Status Thread::StepIn(bool source_step,
19080b57cec5SDimitry Andric                       LazyBool step_in_avoids_code_without_debug_info,
19090b57cec5SDimitry Andric                       LazyBool step_out_avoids_code_without_debug_info)
19100b57cec5SDimitry Andric 
19110b57cec5SDimitry Andric {
19120b57cec5SDimitry Andric   Status error;
19130b57cec5SDimitry Andric   Process *process = GetProcess().get();
19140b57cec5SDimitry Andric   if (StateIsStoppedState(process->GetState(), true)) {
19150b57cec5SDimitry Andric     StackFrameSP frame_sp = GetStackFrameAtIndex(0);
19160b57cec5SDimitry Andric     ThreadPlanSP new_plan_sp;
19170b57cec5SDimitry Andric     const lldb::RunMode run_mode = eOnlyThisThread;
19180b57cec5SDimitry Andric     const bool abort_other_plans = false;
19190b57cec5SDimitry Andric 
19200b57cec5SDimitry Andric     if (source_step && frame_sp && frame_sp->HasDebugInformation()) {
19210b57cec5SDimitry Andric       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
19220b57cec5SDimitry Andric       new_plan_sp = QueueThreadPlanForStepInRange(
19230b57cec5SDimitry Andric           abort_other_plans, sc.line_entry, sc, nullptr, run_mode, error,
19240b57cec5SDimitry Andric           step_in_avoids_code_without_debug_info,
19250b57cec5SDimitry Andric           step_out_avoids_code_without_debug_info);
19260b57cec5SDimitry Andric     } else {
19270b57cec5SDimitry Andric       new_plan_sp = QueueThreadPlanForStepSingleInstruction(
19280b57cec5SDimitry Andric           false, abort_other_plans, run_mode, error);
19290b57cec5SDimitry Andric     }
19300b57cec5SDimitry Andric 
1931349cc55cSDimitry Andric     new_plan_sp->SetIsControllingPlan(true);
19320b57cec5SDimitry Andric     new_plan_sp->SetOkayToDiscard(false);
19330b57cec5SDimitry Andric 
19340b57cec5SDimitry Andric     // Why do we need to set the current thread by ID here???
19350b57cec5SDimitry Andric     process->GetThreadList().SetSelectedThreadByID(GetID());
19360b57cec5SDimitry Andric     error = process->Resume();
19370b57cec5SDimitry Andric   } else {
19380b57cec5SDimitry Andric     error.SetErrorString("process not stopped");
19390b57cec5SDimitry Andric   }
19400b57cec5SDimitry Andric   return error;
19410b57cec5SDimitry Andric }
19420b57cec5SDimitry Andric 
StepOver(bool source_step,LazyBool step_out_avoids_code_without_debug_info)19430b57cec5SDimitry Andric Status Thread::StepOver(bool source_step,
19440b57cec5SDimitry Andric                         LazyBool step_out_avoids_code_without_debug_info) {
19450b57cec5SDimitry Andric   Status error;
19460b57cec5SDimitry Andric   Process *process = GetProcess().get();
19470b57cec5SDimitry Andric   if (StateIsStoppedState(process->GetState(), true)) {
19480b57cec5SDimitry Andric     StackFrameSP frame_sp = GetStackFrameAtIndex(0);
19490b57cec5SDimitry Andric     ThreadPlanSP new_plan_sp;
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric     const lldb::RunMode run_mode = eOnlyThisThread;
19520b57cec5SDimitry Andric     const bool abort_other_plans = false;
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric     if (source_step && frame_sp && frame_sp->HasDebugInformation()) {
19550b57cec5SDimitry Andric       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
19560b57cec5SDimitry Andric       new_plan_sp = QueueThreadPlanForStepOverRange(
19570b57cec5SDimitry Andric           abort_other_plans, sc.line_entry, sc, run_mode, error,
19580b57cec5SDimitry Andric           step_out_avoids_code_without_debug_info);
19590b57cec5SDimitry Andric     } else {
19600b57cec5SDimitry Andric       new_plan_sp = QueueThreadPlanForStepSingleInstruction(
19610b57cec5SDimitry Andric           true, abort_other_plans, run_mode, error);
19620b57cec5SDimitry Andric     }
19630b57cec5SDimitry Andric 
1964349cc55cSDimitry Andric     new_plan_sp->SetIsControllingPlan(true);
19650b57cec5SDimitry Andric     new_plan_sp->SetOkayToDiscard(false);
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric     // Why do we need to set the current thread by ID here???
19680b57cec5SDimitry Andric     process->GetThreadList().SetSelectedThreadByID(GetID());
19690b57cec5SDimitry Andric     error = process->Resume();
19700b57cec5SDimitry Andric   } else {
19710b57cec5SDimitry Andric     error.SetErrorString("process not stopped");
19720b57cec5SDimitry Andric   }
19730b57cec5SDimitry Andric   return error;
19740b57cec5SDimitry Andric }
19750b57cec5SDimitry Andric 
StepOut(uint32_t frame_idx)197681ad6265SDimitry Andric Status Thread::StepOut(uint32_t frame_idx) {
19770b57cec5SDimitry Andric   Status error;
19780b57cec5SDimitry Andric   Process *process = GetProcess().get();
19790b57cec5SDimitry Andric   if (StateIsStoppedState(process->GetState(), true)) {
19800b57cec5SDimitry Andric     const bool first_instruction = false;
19810b57cec5SDimitry Andric     const bool stop_other_threads = false;
19820b57cec5SDimitry Andric     const bool abort_other_plans = false;
19830b57cec5SDimitry Andric 
19840b57cec5SDimitry Andric     ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut(
19850b57cec5SDimitry Andric         abort_other_plans, nullptr, first_instruction, stop_other_threads,
198681ad6265SDimitry Andric         eVoteYes, eVoteNoOpinion, frame_idx, error));
19870b57cec5SDimitry Andric 
1988349cc55cSDimitry Andric     new_plan_sp->SetIsControllingPlan(true);
19890b57cec5SDimitry Andric     new_plan_sp->SetOkayToDiscard(false);
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric     // Why do we need to set the current thread by ID here???
19920b57cec5SDimitry Andric     process->GetThreadList().SetSelectedThreadByID(GetID());
19930b57cec5SDimitry Andric     error = process->Resume();
19940b57cec5SDimitry Andric   } else {
19950b57cec5SDimitry Andric     error.SetErrorString("process not stopped");
19960b57cec5SDimitry Andric   }
19970b57cec5SDimitry Andric   return error;
19980b57cec5SDimitry Andric }
19990b57cec5SDimitry Andric 
GetCurrentException()20000b57cec5SDimitry Andric ValueObjectSP Thread::GetCurrentException() {
20010b57cec5SDimitry Andric   if (auto frame_sp = GetStackFrameAtIndex(0))
20020b57cec5SDimitry Andric     if (auto recognized_frame = frame_sp->GetRecognizedFrame())
20030b57cec5SDimitry Andric       if (auto e = recognized_frame->GetExceptionObject())
20040b57cec5SDimitry Andric         return e;
20050b57cec5SDimitry Andric 
20060b57cec5SDimitry Andric   // NOTE: Even though this behavior is generalized, only ObjC is actually
20070b57cec5SDimitry Andric   // supported at the moment.
20080b57cec5SDimitry Andric   for (LanguageRuntime *runtime : GetProcess()->GetLanguageRuntimes()) {
20090b57cec5SDimitry Andric     if (auto e = runtime->GetExceptionObjectForThread(shared_from_this()))
20100b57cec5SDimitry Andric       return e;
20110b57cec5SDimitry Andric   }
20120b57cec5SDimitry Andric 
20130b57cec5SDimitry Andric   return ValueObjectSP();
20140b57cec5SDimitry Andric }
20150b57cec5SDimitry Andric 
GetCurrentExceptionBacktrace()20160b57cec5SDimitry Andric ThreadSP Thread::GetCurrentExceptionBacktrace() {
20170b57cec5SDimitry Andric   ValueObjectSP exception = GetCurrentException();
20180b57cec5SDimitry Andric   if (!exception)
20190b57cec5SDimitry Andric     return ThreadSP();
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric   // NOTE: Even though this behavior is generalized, only ObjC is actually
20220b57cec5SDimitry Andric   // supported at the moment.
20230b57cec5SDimitry Andric   for (LanguageRuntime *runtime : GetProcess()->GetLanguageRuntimes()) {
20240b57cec5SDimitry Andric     if (auto bt = runtime->GetBacktraceThreadFromException(exception))
20250b57cec5SDimitry Andric       return bt;
20260b57cec5SDimitry Andric   }
20270b57cec5SDimitry Andric 
20280b57cec5SDimitry Andric   return ThreadSP();
20290b57cec5SDimitry Andric }
20301fd87a68SDimitry Andric 
GetSiginfoValue()20311fd87a68SDimitry Andric lldb::ValueObjectSP Thread::GetSiginfoValue() {
20321fd87a68SDimitry Andric   ProcessSP process_sp = GetProcess();
20331fd87a68SDimitry Andric   assert(process_sp);
20341fd87a68SDimitry Andric   Target &target = process_sp->GetTarget();
20351fd87a68SDimitry Andric   PlatformSP platform_sp = target.GetPlatform();
20361fd87a68SDimitry Andric   assert(platform_sp);
20371fd87a68SDimitry Andric   ArchSpec arch = target.GetArchitecture();
20381fd87a68SDimitry Andric 
20391fd87a68SDimitry Andric   CompilerType type = platform_sp->GetSiginfoType(arch.GetTriple());
20401fd87a68SDimitry Andric   if (!type.IsValid())
20411fd87a68SDimitry Andric     return ValueObjectConstResult::Create(&target, Status("no siginfo_t for the platform"));
20421fd87a68SDimitry Andric 
2043bdd1243dSDimitry Andric   std::optional<uint64_t> type_size = type.GetByteSize(nullptr);
20441fd87a68SDimitry Andric   assert(type_size);
2045fcaf7f86SDimitry Andric   llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> data =
2046bdd1243dSDimitry Andric       GetSiginfo(*type_size);
20471fd87a68SDimitry Andric   if (!data)
20481fd87a68SDimitry Andric     return ValueObjectConstResult::Create(&target, Status(data.takeError()));
20491fd87a68SDimitry Andric 
20501fd87a68SDimitry Andric   DataExtractor data_extractor{data.get()->getBufferStart(), data.get()->getBufferSize(),
20511fd87a68SDimitry Andric     process_sp->GetByteOrder(), arch.GetAddressByteSize()};
20521fd87a68SDimitry Andric   return ValueObjectConstResult::Create(&target, type, ConstString("__lldb_siginfo"), data_extractor);
20531fd87a68SDimitry Andric }
2054