diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/source/Target/ThreadPlan.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/source/Target/ThreadPlan.cpp')
-rw-r--r-- | gnu/llvm/lldb/source/Target/ThreadPlan.cpp | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Target/ThreadPlan.cpp b/gnu/llvm/lldb/source/Target/ThreadPlan.cpp new file mode 100644 index 00000000000..ba56f8d15d8 --- /dev/null +++ b/gnu/llvm/lldb/source/Target/ThreadPlan.cpp @@ -0,0 +1,275 @@ +//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" + +using namespace lldb; +using namespace lldb_private; + +// ThreadPlan constructor +ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, + Vote stop_vote, Vote run_vote) + : m_thread(thread), m_stop_vote(stop_vote), m_run_vote(run_vote), + m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false), + m_kind(kind), m_name(name), m_plan_complete_mutex(), + m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false), + m_plan_private(false), m_okay_to_discard(true), m_is_master_plan(false), + m_plan_succeeded(true) { + SetID(GetNextID()); +} + +// Destructor +ThreadPlan::~ThreadPlan() = default; + +bool ThreadPlan::PlanExplainsStop(Event *event_ptr) { + if (m_cached_plan_explains_stop == eLazyBoolCalculate) { + bool actual_value = DoPlanExplainsStop(event_ptr); + m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo; + return actual_value; + } else { + return m_cached_plan_explains_stop == eLazyBoolYes; + } +} + +bool ThreadPlan::IsPlanComplete() { + std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); + return m_plan_complete; +} + +void ThreadPlan::SetPlanComplete(bool success) { + std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); + m_plan_complete = true; + m_plan_succeeded = success; +} + +bool ThreadPlan::MischiefManaged() { + std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); + // Mark the plan is complete, but don't override the success flag. + m_plan_complete = true; + return true; +} + +Vote ThreadPlan::ShouldReportStop(Event *event_ptr) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + if (m_stop_vote == eVoteNoOpinion) { + ThreadPlan *prev_plan = GetPreviousPlan(); + if (prev_plan) { + Vote prev_vote = prev_plan->ShouldReportStop(event_ptr); + LLDB_LOG(log, "returning previous thread plan vote: {0}", prev_vote); + return prev_vote; + } + } + LLDB_LOG(log, "Returning vote: {0}", m_stop_vote); + return m_stop_vote; +} + +Vote ThreadPlan::ShouldReportRun(Event *event_ptr) { + if (m_run_vote == eVoteNoOpinion) { + ThreadPlan *prev_plan = GetPreviousPlan(); + if (prev_plan) + return prev_plan->ShouldReportRun(event_ptr); + } + return m_run_vote; +} + +bool ThreadPlan::StopOthers() { + ThreadPlan *prev_plan; + prev_plan = GetPreviousPlan(); + return (prev_plan == nullptr) ? false : prev_plan->StopOthers(); +} + +void ThreadPlan::SetStopOthers(bool new_value) { + // SetStopOthers doesn't work up the hierarchy. You have to set the explicit + // ThreadPlan you want to affect. +} + +bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) { + m_cached_plan_explains_stop = eLazyBoolCalculate; + + if (current_plan) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + if (log) { + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + assert(reg_ctx); + addr_t pc = reg_ctx->GetPC(); + addr_t sp = reg_ctx->GetSP(); + addr_t fp = reg_ctx->GetFP(); + LLDB_LOGF( + log, + "%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 + ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", " + "plan = '%s', state = %s, stop others = %d", + __FUNCTION__, m_thread.GetIndexID(), static_cast<void *>(&m_thread), + m_thread.GetID(), static_cast<uint64_t>(pc), + static_cast<uint64_t>(sp), static_cast<uint64_t>(fp), m_name.c_str(), + StateAsCString(resume_state), StopOthers()); + } + } + return DoWillResume(resume_state, current_plan); +} + +lldb::user_id_t ThreadPlan::GetNextID() { + static uint32_t g_nextPlanID = 0; + return ++g_nextPlanID; +} + +void ThreadPlan::DidPush() {} + +void ThreadPlan::WillPop() {} + +bool ThreadPlan::OkayToDiscard() { + return IsMasterPlan() ? m_okay_to_discard : true; +} + +lldb::StateType ThreadPlan::RunState() { + if (m_tracer_sp && m_tracer_sp->TracingEnabled() && + m_tracer_sp->SingleStepEnabled()) + return eStateStepping; + else + return GetPlanRunState(); +} + +bool ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason) { + switch (reason) { + case eStopReasonWatchpoint: + case eStopReasonSignal: + case eStopReasonException: + case eStopReasonExec: + case eStopReasonThreadExiting: + case eStopReasonInstrumentation: + return true; + default: + return false; + } +} + +// ThreadPlanNull + +ThreadPlanNull::ThreadPlanNull(Thread &thread) + : ThreadPlan(ThreadPlan::eKindNull, "Null Thread Plan", thread, + eVoteNoOpinion, eVoteNoOpinion) {} + +ThreadPlanNull::~ThreadPlanNull() = default; + +void ThreadPlanNull::GetDescription(Stream *s, lldb::DescriptionLevel level) { + s->PutCString("Null thread plan - thread has been destroyed."); +} + +bool ThreadPlanNull::ValidatePlan(Stream *error) { +#ifdef LLDB_CONFIGURATION_DEBUG + fprintf(stderr, + "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); +#else + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + if (log) + log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), + m_thread.GetProtocolID()); +#endif + return true; +} + +bool ThreadPlanNull::ShouldStop(Event *event_ptr) { +#ifdef LLDB_CONFIGURATION_DEBUG + fprintf(stderr, + "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); +#else + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + if (log) + log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), + m_thread.GetProtocolID()); +#endif + return true; +} + +bool ThreadPlanNull::WillStop() { +#ifdef LLDB_CONFIGURATION_DEBUG + fprintf(stderr, + "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); +#else + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + if (log) + log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), + m_thread.GetProtocolID()); +#endif + return true; +} + +bool ThreadPlanNull::DoPlanExplainsStop(Event *event_ptr) { +#ifdef LLDB_CONFIGURATION_DEBUG + fprintf(stderr, + "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); +#else + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + if (log) + log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), + m_thread.GetProtocolID()); +#endif + return true; +} + +// The null plan is never done. +bool ThreadPlanNull::MischiefManaged() { +// The null plan is never done. +#ifdef LLDB_CONFIGURATION_DEBUG + fprintf(stderr, + "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); +#else + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + if (log) + log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), + m_thread.GetProtocolID()); +#endif + return false; +} + +lldb::StateType ThreadPlanNull::GetPlanRunState() { +// Not sure what to return here. This is a dead thread. +#ifdef LLDB_CONFIGURATION_DEBUG + fprintf(stderr, + "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); +#else + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + if (log) + log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 + ", ptid = 0x%" PRIx64 ")", + LLVM_PRETTY_FUNCTION, m_thread.GetID(), + m_thread.GetProtocolID()); +#endif + return eStateRunning; +} |