aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target')
-rw-r--r--lldb/source/Target/BorrowedStackFrame.cpp187
-rw-r--r--lldb/source/Target/CMakeLists.txt3
-rw-r--r--lldb/source/Target/ExecutionContext.cpp17
-rw-r--r--lldb/source/Target/InstrumentationRuntime.cpp3
-rw-r--r--lldb/source/Target/Language.cpp42
-rw-r--r--lldb/source/Target/ModuleCache.cpp2
-rw-r--r--lldb/source/Target/Platform.cpp44
-rw-r--r--lldb/source/Target/Process.cpp24
-rw-r--r--lldb/source/Target/RemoteAwarePlatform.cpp11
-rw-r--r--lldb/source/Target/StackFrame.cpp20
-rw-r--r--lldb/source/Target/StackFrameList.cpp49
-rw-r--r--lldb/source/Target/SyntheticFrameProvider.cpp121
-rw-r--r--lldb/source/Target/Target.cpp154
-rw-r--r--lldb/source/Target/TargetList.cpp13
-rw-r--r--lldb/source/Target/Thread.cpp72
-rw-r--r--lldb/source/Target/ThreadPlanStepOut.cpp11
-rw-r--r--lldb/source/Target/ThreadPlanStepRange.cpp4
-rw-r--r--lldb/source/Target/ThreadSpec.cpp4
-rw-r--r--lldb/source/Target/UnixSignals.cpp7
-rw-r--r--lldb/source/Target/VerboseTrapFrameRecognizer.cpp156
20 files changed, 683 insertions, 261 deletions
diff --git a/lldb/source/Target/BorrowedStackFrame.cpp b/lldb/source/Target/BorrowedStackFrame.cpp
new file mode 100644
index 0000000..5afadf2
--- /dev/null
+++ b/lldb/source/Target/BorrowedStackFrame.cpp
@@ -0,0 +1,187 @@
+//===----------------------------------------------------------------------===//
+//
+// 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/BorrowedStackFrame.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+char BorrowedStackFrame::ID;
+
+BorrowedStackFrame::BorrowedStackFrame(
+ StackFrameSP borrowed_frame_sp, uint32_t new_frame_index,
+ std::optional<uint32_t> new_concrete_frame_index)
+ : StackFrame(
+ borrowed_frame_sp->GetThread(), new_frame_index,
+ borrowed_frame_sp->GetConcreteFrameIndex(),
+ borrowed_frame_sp->GetRegisterContextSP(),
+ borrowed_frame_sp->GetStackID().GetPC(),
+ borrowed_frame_sp->GetStackID().GetCallFrameAddressWithoutMetadata(),
+ borrowed_frame_sp->m_behaves_like_zeroth_frame,
+ &borrowed_frame_sp->GetSymbolContext(eSymbolContextEverything)),
+ m_borrowed_frame_sp(borrowed_frame_sp),
+ m_new_frame_index(new_frame_index) {
+ if (new_concrete_frame_index)
+ m_new_concrete_frame_index = *new_concrete_frame_index;
+ else
+ m_new_concrete_frame_index =
+ IsInlined() ? LLDB_INVALID_FRAME_ID : new_frame_index;
+}
+
+uint32_t BorrowedStackFrame::GetFrameIndex() const { return m_new_frame_index; }
+
+void BorrowedStackFrame::SetFrameIndex(uint32_t index) {
+ m_new_frame_index = index;
+}
+
+uint32_t BorrowedStackFrame::GetConcreteFrameIndex() {
+ // FIXME: We need to find where the concrete frame into which this frame was
+ // inlined landed in the new stack frame list as that is the correct concrete
+ // frame index in this
+ // stack frame.
+ return m_new_concrete_frame_index;
+}
+
+StackID &BorrowedStackFrame::GetStackID() {
+ return m_borrowed_frame_sp->GetStackID();
+}
+
+const Address &BorrowedStackFrame::GetFrameCodeAddress() {
+ return m_borrowed_frame_sp->GetFrameCodeAddress();
+}
+
+Address BorrowedStackFrame::GetFrameCodeAddressForSymbolication() {
+ return m_borrowed_frame_sp->GetFrameCodeAddressForSymbolication();
+}
+
+bool BorrowedStackFrame::ChangePC(addr_t pc) {
+ return m_borrowed_frame_sp->ChangePC(pc);
+}
+
+const SymbolContext &
+BorrowedStackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
+ return m_borrowed_frame_sp->GetSymbolContext(resolve_scope);
+}
+
+llvm::Error BorrowedStackFrame::GetFrameBaseValue(Scalar &value) {
+ return m_borrowed_frame_sp->GetFrameBaseValue(value);
+}
+
+DWARFExpressionList *
+BorrowedStackFrame::GetFrameBaseExpression(Status *error_ptr) {
+ return m_borrowed_frame_sp->GetFrameBaseExpression(error_ptr);
+}
+
+Block *BorrowedStackFrame::GetFrameBlock() {
+ return m_borrowed_frame_sp->GetFrameBlock();
+}
+
+RegisterContextSP BorrowedStackFrame::GetRegisterContext() {
+ return m_borrowed_frame_sp->GetRegisterContext();
+}
+
+VariableList *BorrowedStackFrame::GetVariableList(bool get_file_globals,
+ Status *error_ptr) {
+ return m_borrowed_frame_sp->GetVariableList(get_file_globals, error_ptr);
+}
+
+VariableListSP
+BorrowedStackFrame::GetInScopeVariableList(bool get_file_globals,
+ bool must_have_valid_location) {
+ return m_borrowed_frame_sp->GetInScopeVariableList(get_file_globals,
+ must_have_valid_location);
+}
+
+ValueObjectSP BorrowedStackFrame::GetValueForVariableExpressionPath(
+ llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
+ VariableSP &var_sp, Status &error) {
+ return m_borrowed_frame_sp->GetValueForVariableExpressionPath(
+ var_expr, use_dynamic, options, var_sp, error);
+}
+
+bool BorrowedStackFrame::HasDebugInformation() {
+ return m_borrowed_frame_sp->HasDebugInformation();
+}
+
+const char *BorrowedStackFrame::Disassemble() {
+ return m_borrowed_frame_sp->Disassemble();
+}
+
+ValueObjectSP BorrowedStackFrame::GetValueObjectForFrameVariable(
+ const VariableSP &variable_sp, DynamicValueType use_dynamic) {
+ return m_borrowed_frame_sp->GetValueObjectForFrameVariable(variable_sp,
+ use_dynamic);
+}
+
+bool BorrowedStackFrame::IsInlined() {
+ return m_borrowed_frame_sp->IsInlined();
+}
+
+bool BorrowedStackFrame::IsSynthetic() const {
+ return m_borrowed_frame_sp->IsSynthetic();
+}
+
+bool BorrowedStackFrame::IsHistorical() const {
+ return m_borrowed_frame_sp->IsHistorical();
+}
+
+bool BorrowedStackFrame::IsArtificial() const {
+ return m_borrowed_frame_sp->IsArtificial();
+}
+
+bool BorrowedStackFrame::IsHidden() { return m_borrowed_frame_sp->IsHidden(); }
+
+const char *BorrowedStackFrame::GetFunctionName() {
+ return m_borrowed_frame_sp->GetFunctionName();
+}
+
+const char *BorrowedStackFrame::GetDisplayFunctionName() {
+ return m_borrowed_frame_sp->GetDisplayFunctionName();
+}
+
+ValueObjectSP BorrowedStackFrame::FindVariable(ConstString name) {
+ return m_borrowed_frame_sp->FindVariable(name);
+}
+
+SourceLanguage BorrowedStackFrame::GetLanguage() {
+ return m_borrowed_frame_sp->GetLanguage();
+}
+
+SourceLanguage BorrowedStackFrame::GuessLanguage() {
+ return m_borrowed_frame_sp->GuessLanguage();
+}
+
+ValueObjectSP BorrowedStackFrame::GuessValueForAddress(addr_t addr) {
+ return m_borrowed_frame_sp->GuessValueForAddress(addr);
+}
+
+ValueObjectSP
+BorrowedStackFrame::GuessValueForRegisterAndOffset(ConstString reg,
+ int64_t offset) {
+ return m_borrowed_frame_sp->GuessValueForRegisterAndOffset(reg, offset);
+}
+
+StructuredData::ObjectSP BorrowedStackFrame::GetLanguageSpecificData() {
+ return m_borrowed_frame_sp->GetLanguageSpecificData();
+}
+
+RecognizedStackFrameSP BorrowedStackFrame::GetRecognizedFrame() {
+ return m_borrowed_frame_sp->GetRecognizedFrame();
+}
+
+StackFrameSP BorrowedStackFrame::GetBorrowedFrame() const {
+ return m_borrowed_frame_sp;
+}
+
+bool BorrowedStackFrame::isA(const void *ClassID) const {
+ return ClassID == &ID || StackFrame::isA(ClassID);
+}
+
+bool BorrowedStackFrame::classof(const StackFrame *obj) {
+ return obj->isA(&ID);
+}
diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt
index b7788e8..df2ee03 100644
--- a/lldb/source/Target/CMakeLists.txt
+++ b/lldb/source/Target/CMakeLists.txt
@@ -38,8 +38,10 @@ add_lldb_library(lldbTarget
RegisterNumber.cpp
RemoteAwarePlatform.cpp
ScriptedThreadPlan.cpp
+ SyntheticFrameProvider.cpp
SectionLoadHistory.cpp
SectionLoadList.cpp
+ BorrowedStackFrame.cpp
StackFrame.cpp
StackFrameList.cpp
StackFrameRecognizer.cpp
@@ -80,7 +82,6 @@ add_lldb_library(lldbTarget
UnixSignals.cpp
UnwindAssembly.cpp
UnwindLLDB.cpp
- VerboseTrapFrameRecognizer.cpp
ADDITIONAL_HEADER_DIRS
${LLDB_INCLUDE_DIR}/lldb/Target
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp
index a795913..b16ff26 100644
--- a/lldb/source/Target/ExecutionContext.cpp
+++ b/lldb/source/Target/ExecutionContext.cpp
@@ -466,10 +466,13 @@ operator=(const ExecutionContext &exe_ctx) {
else
m_tid = LLDB_INVALID_THREAD_ID;
lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
- if (frame_sp)
+ if (frame_sp) {
m_stack_id = frame_sp->GetStackID();
- else
+ m_frame_list_wp = frame_sp->GetContainingStackFrameList();
+ } else {
m_stack_id.Clear();
+ m_frame_list_wp.reset();
+ }
return *this;
}
@@ -511,6 +514,7 @@ void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
if (frame_sp) {
m_stack_id = frame_sp->GetStackID();
+ m_frame_list_wp = frame_sp->GetContainingStackFrameList();
SetThreadSP(frame_sp->GetThread());
} else {
ClearFrame();
@@ -638,6 +642,15 @@ lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
if (m_stack_id.IsValid()) {
+ // Try the remembered frame list first to avoid circular dependencies
+ // during frame provider initialization.
+ if (auto frame_list_sp = m_frame_list_wp.lock()) {
+ if (auto frame_sp = frame_list_sp->GetFrameWithStackID(m_stack_id))
+ return frame_sp;
+ }
+
+ // Fallback: ask the thread, which might re-trigger the frame provider
+ // initialization.
lldb::ThreadSP thread_sp(GetThreadSP());
if (thread_sp)
return thread_sp->GetFrameWithStackID(m_stack_id);
diff --git a/lldb/source/Target/InstrumentationRuntime.cpp b/lldb/source/Target/InstrumentationRuntime.cpp
index 7e58e8b..d9800a8 100644
--- a/lldb/source/Target/InstrumentationRuntime.cpp
+++ b/lldb/source/Target/InstrumentationRuntime.cpp
@@ -55,7 +55,8 @@ void InstrumentationRuntime::ModulesDidLoad(
return IterationAction::Continue;
const RegularExpression &runtime_regex = GetPatternForRuntimeLibrary();
- if (runtime_regex.Execute(file_spec.GetFilename().GetCString()) ||
+ if (MatchAllModules() ||
+ runtime_regex.Execute(file_spec.GetFilename().GetCString()) ||
module_sp->IsExecutable()) {
if (CheckIfRuntimeIsValid(module_sp)) {
SetRuntimeModuleSP(module_sp);
diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 8268d4a..c8b09c3 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -159,6 +159,48 @@ void Language::ForEach(
}
}
+llvm::Expected<LanguageType>
+Language::GetExceptionLanguageForLanguage(llvm::StringRef lang_name) {
+ LanguageType language = Language::GetLanguageTypeFromString(lang_name);
+ LanguageType exception_language = eLanguageTypeUnknown;
+
+ llvm::StringRef error_context;
+ switch (language) {
+ case eLanguageTypeC89:
+ case eLanguageTypeC:
+ case eLanguageTypeC99:
+ case eLanguageTypeC11:
+ exception_language = eLanguageTypeC;
+ break;
+ case eLanguageTypeC_plus_plus:
+ case eLanguageTypeC_plus_plus_03:
+ case eLanguageTypeC_plus_plus_11:
+ case eLanguageTypeC_plus_plus_14:
+ exception_language = eLanguageTypeC_plus_plus;
+ break;
+ case eLanguageTypeObjC_plus_plus:
+ error_context =
+ "Set exception breakpoints separately for c++ and objective-c";
+ break;
+ case eLanguageTypeUnknown:
+ error_context = "Unknown language type for exception breakpoint";
+ break;
+ default:
+ if (Language *languagePlugin = Language::FindPlugin(language)) {
+ if (languagePlugin->SupportsExceptionBreakpointsOnThrow() ||
+ languagePlugin->SupportsExceptionBreakpointsOnCatch()) {
+ exception_language = language;
+ break;
+ }
+ }
+ error_context = "Unsupported language type for exception breakpoint";
+ }
+ if (!error_context.empty())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ error_context);
+ return exception_language;
+}
+
bool Language::IsTopLevelFunction(Function &function) { return false; }
lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
diff --git a/lldb/source/Target/ModuleCache.cpp b/lldb/source/Target/ModuleCache.cpp
index f737836..9978946 100644
--- a/lldb/source/Target/ModuleCache.cpp
+++ b/lldb/source/Target/ModuleCache.cpp
@@ -255,7 +255,7 @@ Status ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname,
cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec();
error = ModuleList::GetSharedModule(cached_module_spec, cached_module_sp,
- nullptr, nullptr, did_create_ptr, false);
+ nullptr, did_create_ptr, false);
if (error.Fail())
return error;
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 8681ada..5b0930c 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -163,11 +163,12 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module,
Status Platform::GetSharedModule(
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
if (IsHost())
- return ModuleList::GetSharedModule(module_spec, module_sp,
- module_search_paths_ptr, old_modules,
+ // Note: module_search_paths_ptr functionality is now handled internally
+ // by getting target from module_spec and calling
+ // target->GetExecutableSearchPaths()
+ return ModuleList::GetSharedModule(module_spec, module_sp, old_modules,
did_create_ptr, false);
// Module resolver lambda.
@@ -180,16 +181,14 @@ Status Platform::GetSharedModule(
resolved_spec = spec;
resolved_spec.GetFileSpec().PrependPathComponent(m_sdk_sysroot);
// Try to get shared module with resolved spec.
- error = ModuleList::GetSharedModule(resolved_spec, module_sp,
- module_search_paths_ptr, old_modules,
+ error = ModuleList::GetSharedModule(resolved_spec, module_sp, old_modules,
did_create_ptr, false);
}
// If we don't have sysroot or it didn't work then
// try original module spec.
if (!error.Success()) {
resolved_spec = spec;
- error = ModuleList::GetSharedModule(resolved_spec, module_sp,
- module_search_paths_ptr, old_modules,
+ error = ModuleList::GetSharedModule(resolved_spec, module_sp, old_modules,
did_create_ptr, false);
}
if (error.Success() && module_sp)
@@ -731,10 +730,8 @@ bool Platform::SetOSVersion(llvm::VersionTuple version) {
return false;
}
-Status
-Platform::ResolveExecutable(const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
+Status Platform::ResolveExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &exe_module_sp) {
// We may connect to a process and use the provided executable (Don't use
// local $PATH).
@@ -750,9 +747,8 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec,
if (resolved_module_spec.GetArchitecture().IsValid() ||
resolved_module_spec.GetUUID().IsValid()) {
- Status error =
- ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr, nullptr, nullptr);
+ Status error = ModuleList::GetSharedModule(resolved_module_spec,
+ exe_module_sp, nullptr, nullptr);
if (exe_module_sp && exe_module_sp->GetObjectFile())
return error;
@@ -767,9 +763,9 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec,
Status error;
for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) {
resolved_module_spec.GetArchitecture() = arch;
- error =
- ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr, nullptr, nullptr);
+
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr);
if (error.Success()) {
if (exe_module_sp && exe_module_sp->GetObjectFile())
break;
@@ -1446,16 +1442,13 @@ const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() {
return m_trap_handlers;
}
-Status
-Platform::GetCachedExecutable(ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) {
+Status Platform::GetCachedExecutable(ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp) {
FileSpec platform_spec = module_spec.GetFileSpec();
Status error = GetRemoteSharedModule(
module_spec, nullptr, module_sp,
[&](const ModuleSpec &spec) {
- return Platform::ResolveExecutable(spec, module_sp,
- module_search_paths_ptr);
+ return Platform::ResolveExecutable(spec, module_sp);
},
nullptr);
if (error.Success()) {
@@ -1497,7 +1490,7 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec,
for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) {
arch_module_spec.GetArchitecture() = arch;
error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr,
- nullptr, nullptr);
+ nullptr);
// Did we find an executable using one of the
if (error.Success() && module_sp)
break;
@@ -1673,11 +1666,12 @@ void Platform::CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec,
cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5
// content hash instead of real UUID.
cached_module_spec.GetFileSpec() = module_file_spec;
+ cached_module_spec.GetSymbolFileSpec() = symbol_file_spec;
cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec();
cached_module_spec.SetObjectOffset(0);
error = ModuleList::GetSharedModule(cached_module_spec, module_sp, nullptr,
- nullptr, did_create_ptr, false);
+ did_create_ptr, false, false);
if (error.Success() && module_sp) {
// Succeeded to load the module file.
LLDB_LOGF(log, "%s: locate module callback succeeded: module=%s symbol=%s",
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index fb9e7eb..9c8e8fa7 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -65,7 +65,6 @@
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Target/ThreadPlanStack.h"
#include "lldb/Target/UnixSignals.h"
-#include "lldb/Target/VerboseTrapFrameRecognizer.h"
#include "lldb/Utility/AddressableBits.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/LLDBLog.h"
@@ -513,7 +512,6 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
// We should have a plugin do the registration instead, for example, a
// common C LanguageRuntime plugin.
RegisterAssertFrameRecognizer(this);
- RegisterVerboseTrapFrameRecognizer(*this);
}
Process::~Process() {
@@ -2454,8 +2452,10 @@ size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size,
scalar = data.GetMaxU32(&offset, byte_size);
else
scalar = data.GetMaxU64(&offset, byte_size);
- if (is_signed)
+ if (is_signed) {
+ scalar.MakeSigned();
scalar.SignExtend(byte_size * 8);
+ }
return bytes_read;
}
} else {
@@ -3258,6 +3258,7 @@ Status Process::ConnectRemote(llvm::StringRef remote_url) {
if (state == eStateStopped || state == eStateCrashed) {
// If we attached and actually have a process on the other end, then
// this ended up being the equivalent of an attach.
+ SetShouldDetach(true);
CompleteAttach();
// This delays passing the stopped event to listeners till
@@ -6546,7 +6547,7 @@ Status Process::WriteMemoryTags(lldb::addr_t addr, size_t len,
// Create a CoreFileMemoryRange from a MemoryRegionInfo
static CoreFileMemoryRange
-CreateCoreFileMemoryRange(const MemoryRegionInfo &region) {
+CreateCoreFileMemoryRange(const lldb_private::MemoryRegionInfo &region) {
const addr_t addr = region.GetRange().GetRangeBase();
llvm::AddressRange range(addr, addr + region.GetRange().GetByteSize());
return {range, region.GetLLDBPermissions()};
@@ -6555,7 +6556,7 @@ CreateCoreFileMemoryRange(const MemoryRegionInfo &region) {
// Add dirty pages to the core file ranges and return true if dirty pages
// were added. Return false if the dirty page information is not valid or in
// the region.
-static bool AddDirtyPages(const MemoryRegionInfo &region,
+static bool AddDirtyPages(const lldb_private::MemoryRegionInfo &region,
CoreFileMemoryRanges &ranges) {
const auto &dirty_page_list = region.GetDirtyPageList();
if (!dirty_page_list)
@@ -6594,8 +6595,8 @@ static bool AddDirtyPages(const MemoryRegionInfo &region,
// given region. If the region has dirty page information, only dirty pages
// will be added to \a ranges, else the entire range will be added to \a
// ranges.
-static void AddRegion(const MemoryRegionInfo &region, bool try_dirty_pages,
- CoreFileMemoryRanges &ranges) {
+static void AddRegion(const lldb_private::MemoryRegionInfo &region,
+ bool try_dirty_pages, CoreFileMemoryRanges &ranges) {
// Don't add empty ranges.
if (region.GetRange().GetByteSize() == 0)
return;
@@ -6618,7 +6619,7 @@ static void SaveDynamicLoaderSections(Process &process,
if (!dyld)
return;
- std::vector<MemoryRegionInfo> dynamic_loader_mem_regions;
+ std::vector<lldb_private::MemoryRegionInfo> dynamic_loader_mem_regions;
std::function<bool(const lldb_private::Thread &)> save_thread_predicate =
[&](const lldb_private::Thread &t) -> bool {
return options.ShouldThreadBeSaved(t.GetID());
@@ -6743,10 +6744,11 @@ static void GetCoreFileSaveRangesStackOnly(Process &process,
// TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and
// then add an intersect method on it, or MemoryRegionInfo.
-static MemoryRegionInfo Intersect(const MemoryRegionInfo &lhs,
- const MemoryRegionInfo::RangeType &rhs) {
+static lldb_private::MemoryRegionInfo
+Intersect(const lldb_private::MemoryRegionInfo &lhs,
+ const lldb_private::MemoryRegionInfo::RangeType &rhs) {
- MemoryRegionInfo region_info;
+ lldb_private::MemoryRegionInfo region_info;
region_info.SetLLDBPermissions(lhs.GetLLDBPermissions());
region_info.GetRange() = lhs.GetRange().Intersect(rhs);
diff --git a/lldb/source/Target/RemoteAwarePlatform.cpp b/lldb/source/Target/RemoteAwarePlatform.cpp
index cac738e..89b946b 100644
--- a/lldb/source/Target/RemoteAwarePlatform.cpp
+++ b/lldb/source/Target/RemoteAwarePlatform.cpp
@@ -29,9 +29,8 @@ bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec,
return false;
}
-Status RemoteAwarePlatform::ResolveExecutable(
- const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
+Status RemoteAwarePlatform::ResolveExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &exe_module_sp) {
ModuleSpec resolved_module_spec(module_spec);
// The host platform can resolve the path more aggressively.
@@ -47,12 +46,10 @@ Status RemoteAwarePlatform::ResolveExecutable(
if (!FileSystem::Instance().Exists(resolved_file_spec))
FileSystem::Instance().ResolveExecutableLocation(resolved_file_spec);
} else if (m_remote_platform_sp) {
- return GetCachedExecutable(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr);
+ return GetCachedExecutable(resolved_module_spec, exe_module_sp);
}
- return Platform::ResolveExecutable(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr);
+ return Platform::ResolveExecutable(resolved_module_spec, exe_module_sp);
}
Status RemoteAwarePlatform::RunShellCommand(
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 2ed58c53..3bbb851 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -45,6 +45,9 @@
using namespace lldb;
using namespace lldb_private;
+// LLVM RTTI support.
+char StackFrame::ID;
+
// The first bits in the flags are reserved for the SymbolContext::Scope bits
// so we know if we have tried to look up information in our internal symbol
// context (m_sc) already.
@@ -328,6 +331,13 @@ StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
// following the function call instruction...
Address lookup_addr(GetFrameCodeAddressForSymbolication());
+ // For PC-less frames (e.g., scripted frames), skip PC-based symbol
+ // resolution and preserve any already-populated SymbolContext fields.
+ if (!lookup_addr.IsValid()) {
+ m_flags.Set(resolve_scope | resolved);
+ return m_sc;
+ }
+
if (m_sc.module_sp) {
// We have something in our stack frame symbol context, lets check if we
// haven't already tried to lookup one of those things. If we haven't
@@ -1344,18 +1354,18 @@ const char *StackFrame::GetDisplayFunctionName() {
SourceLanguage StackFrame::GetLanguage() {
CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
if (cu)
- return cu->GetLanguage();
+ return SourceLanguage{cu->GetLanguage()};
return {};
}
SourceLanguage StackFrame::GuessLanguage() {
SourceLanguage lang_type = GetLanguage();
- if (lang_type == eLanguageTypeUnknown) {
+ if (!lang_type) {
SymbolContext sc =
GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol);
if (sc.function)
- lang_type = LanguageType(sc.function->GetMangled().GuessLanguage());
+ lang_type = SourceLanguage(sc.function->GetMangled().GuessLanguage());
else if (sc.symbol)
lang_type = SourceLanguage(sc.symbol->GetMangled().GuessLanguage());
}
@@ -2054,10 +2064,10 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
disasm_display = debugger.GetStopDisassemblyDisplay();
GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
- if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
+ if (m_sc.comp_unit || m_sc.line_entry.IsValid()) {
have_debuginfo = true;
if (source_lines_before > 0 || source_lines_after > 0) {
- SupportFileSP source_file_sp = m_sc.line_entry.file_sp;
+ SupportFileNSP source_file_sp = m_sc.line_entry.file_sp;
uint32_t start_line = m_sc.line_entry.line;
if (!start_line && m_sc.function) {
m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index ccf874f..896a760 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -20,6 +20,7 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/SyntheticFrameProvider.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Unwind.h"
@@ -55,6 +56,49 @@ StackFrameList::~StackFrameList() {
Clear();
}
+SyntheticStackFrameList::SyntheticStackFrameList(
+ Thread &thread, lldb::StackFrameListSP input_frames,
+ const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames)
+ : StackFrameList(thread, prev_frames_sp, show_inline_frames),
+ m_input_frames(std::move(input_frames)) {}
+
+bool SyntheticStackFrameList::FetchFramesUpTo(
+ uint32_t end_idx, InterruptionControl allow_interrupt) {
+
+ size_t num_synthetic_frames = 0;
+ // Check if the thread has a synthetic frame provider.
+ if (auto provider_sp = m_thread.GetFrameProvider()) {
+ // Use the synthetic frame provider to generate frames lazily.
+ // Keep fetching until we reach end_idx or the provider returns an error.
+ for (uint32_t idx = m_frames.size(); idx <= end_idx; idx++) {
+ if (allow_interrupt &&
+ m_thread.GetProcess()->GetTarget().GetDebugger().InterruptRequested())
+ return true;
+ auto frame_or_err = provider_sp->GetFrameAtIndex(idx);
+ if (!frame_or_err) {
+ // Provider returned error - we've reached the end.
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), frame_or_err.takeError(),
+ "Frame provider reached end at index {0}: {1}", idx);
+ SetAllFramesFetched();
+ break;
+ }
+ StackFrameSP frame_sp = *frame_or_err;
+ if (frame_sp->IsSynthetic())
+ frame_sp->GetStackID().SetCFA(num_synthetic_frames++,
+ GetThread().GetProcess().get());
+ // Set the frame list weak pointer so ExecutionContextRef can resolve
+ // the frame without calling Thread::GetStackFrameList().
+ frame_sp->m_frame_list_wp = shared_from_this();
+ m_frames.push_back(frame_sp);
+ }
+
+ return false; // Not interrupted.
+ }
+
+ // If no provider, fall back to the base implementation.
+ return StackFrameList::FetchFramesUpTo(end_idx, allow_interrupt);
+}
+
void StackFrameList::CalculateCurrentInlinedDepth() {
uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
if (cur_inlined_depth == UINT32_MAX) {
@@ -330,6 +374,7 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) {
m_thread.shared_from_this(), frame_idx, concrete_frame_idx, cfa,
cfa_is_valid, pc, StackFrame::Kind::Regular, artificial,
behaves_like_zeroth_frame, &sc);
+ synth_frame->m_frame_list_wp = shared_from_this();
m_frames.push_back(synth_frame);
LLDB_LOG(log, "Pushed frame {0} at {1:x}", callee->GetDisplayName(), pc);
}
@@ -445,6 +490,7 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
unwind_frame_sp = std::make_shared<StackFrame>(
m_thread.shared_from_this(), m_frames.size(), idx, reg_ctx_sp,
cfa, pc, behaves_like_zeroth_frame, nullptr);
+ unwind_frame_sp->m_frame_list_wp = shared_from_this();
m_frames.push_back(unwind_frame_sp);
}
} else {
@@ -479,6 +525,7 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
// although its concrete index will stay the same.
SynthesizeTailCallFrames(*unwind_frame_sp.get());
+ unwind_frame_sp->m_frame_list_wp = shared_from_this();
m_frames.push_back(unwind_frame_sp);
}
@@ -503,6 +550,7 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
unwind_frame_sp->GetRegisterContextSP(), cfa, next_frame_address,
behaves_like_zeroth_frame, &next_frame_sc));
+ frame_sp->m_frame_list_wp = shared_from_this();
m_frames.push_back(frame_sp);
unwind_sc = next_frame_sc;
curr_frame_address = next_frame_address;
@@ -559,6 +607,7 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame);
// Now copy the fixed up previous frame into the current frames so the
// pointer doesn't change.
+ prev_frame_sp->m_frame_list_wp = shared_from_this();
m_frames[curr_frame_idx] = prev_frame_sp;
#if defined(DEBUG_STACK_FRAMES)
diff --git a/lldb/source/Target/SyntheticFrameProvider.cpp b/lldb/source/Target/SyntheticFrameProvider.cpp
new file mode 100644
index 0000000..97ff42d
--- /dev/null
+++ b/lldb/source/Target/SyntheticFrameProvider.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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/SyntheticFrameProvider.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SyntheticFrameProvider::SyntheticFrameProvider(StackFrameListSP input_frames)
+ : m_input_frames(std::move(input_frames)) {}
+
+SyntheticFrameProvider::~SyntheticFrameProvider() = default;
+
+void ScriptedFrameProviderDescriptor::Dump(Stream *s) const {
+ if (!s)
+ return;
+
+ s->Format(" ID: {0:x}\n", GetID());
+ s->Printf(" Name: %s\n", GetName().str().c_str());
+
+ std::string description = GetDescription();
+ if (!description.empty())
+ s->Printf(" Description: %s\n", description.c_str());
+
+ // Show thread filter information.
+ if (thread_specs.empty()) {
+ s->PutCString(" Thread Filter: (applies to all threads)\n");
+ } else {
+ s->Printf(" Thread Filter: %zu specification(s)\n", thread_specs.size());
+ for (size_t i = 0; i < thread_specs.size(); ++i) {
+ const ThreadSpec &spec = thread_specs[i];
+ s->Printf(" [%zu] ", i);
+ spec.GetDescription(s, lldb::eDescriptionLevelVerbose);
+ s->PutChar('\n');
+ }
+ }
+}
+
+uint32_t ScriptedFrameProviderDescriptor::GetID() const {
+ if (!scripted_metadata_sp)
+ return 0;
+
+ return scripted_metadata_sp->GetID();
+}
+
+std::string ScriptedFrameProviderDescriptor::GetDescription() const {
+ // If we have an interface, call get_description() to fetch it.
+ if (interface_sp && scripted_metadata_sp)
+ return interface_sp->GetDescription(scripted_metadata_sp->GetClassName());
+ return {};
+}
+
+llvm::Expected<SyntheticFrameProviderSP> SyntheticFrameProvider::CreateInstance(
+ StackFrameListSP input_frames,
+ const ScriptedFrameProviderDescriptor &descriptor) {
+ if (!input_frames)
+ return llvm::createStringError(
+ "cannot create synthetic frame provider: invalid input frames");
+
+ // Iterate through all registered ScriptedFrameProvider plugins.
+ ScriptedFrameProviderCreateInstance create_callback = nullptr;
+ for (uint32_t idx = 0;
+ (create_callback =
+ PluginManager::GetScriptedFrameProviderCreateCallbackAtIndex(
+ idx)) != nullptr;
+ ++idx) {
+ auto provider_or_err = create_callback(input_frames, descriptor);
+ if (!provider_or_err) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Target), provider_or_err.takeError(),
+ "Failed to create synthetic frame provider: {0}");
+ continue;
+ }
+
+ if (auto frame_provider_up = std::move(*provider_or_err))
+ return std::move(frame_provider_up);
+ }
+
+ return llvm::createStringError(
+ "cannot create synthetic frame provider: no suitable plugin found");
+}
+
+llvm::Expected<SyntheticFrameProviderSP> SyntheticFrameProvider::CreateInstance(
+ StackFrameListSP input_frames, llvm::StringRef plugin_name,
+ const std::vector<ThreadSpec> &thread_specs) {
+ if (!input_frames)
+ return llvm::createStringError(
+ "cannot create synthetic frame provider: invalid input frames");
+
+ // Look up the specific C++ plugin by name.
+ SyntheticFrameProviderCreateInstance create_callback =
+ PluginManager::GetSyntheticFrameProviderCreateCallbackForPluginName(
+ plugin_name);
+
+ if (!create_callback)
+ return llvm::createStringError(
+ "cannot create synthetic frame provider: C++ plugin '%s' not found",
+ plugin_name.str().c_str());
+
+ auto provider_or_err = create_callback(input_frames, thread_specs);
+ if (!provider_or_err)
+ return provider_or_err.takeError();
+
+ if (auto frame_provider_sp = std::move(*provider_or_err))
+ return std::move(frame_provider_sp);
+
+ return llvm::createStringError(
+ "cannot create synthetic frame provider: C++ plugin '%s' returned null",
+ plugin_name.str().c_str());
+}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index d070c3d..2305f10 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Target/Target.h"
+#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointPrecondition.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
@@ -155,8 +156,6 @@ static Status installExecutable(const Installer &installer) {
return Status();
}
-constexpr std::chrono::milliseconds EvaluateExpressionOptions::default_timeout;
-
Target::Arch::Arch(const ArchSpec &spec)
: m_spec(spec),
m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}
@@ -186,6 +185,8 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
m_internal_stop_hooks(), m_latest_stop_hook_id(0), m_valid(true),
m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target),
m_target_unique_id(g_target_unique_id++),
+ m_target_session_name(
+ llvm::formatv("Session {0}", m_target_unique_id).str()),
m_frame_recognizer_manager_up(
std::make_unique<StackFrameRecognizerManager>()) {
SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
@@ -193,6 +194,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
+ SetEventName(eBroadcastBitNewTargetCreated, "new-target-created");
CheckInWithManager();
@@ -1778,9 +1780,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform,
arch_spec.GetArchitectureName(),
arch_spec.GetTriple().getTriple().c_str());
ModuleSpec module_spec(executable_sp->GetFileSpec(), other);
- FileSpecList search_paths = GetExecutableSearchPaths();
+ module_spec.SetTarget(shared_from_this());
Status error = ModuleList::GetSharedModule(module_spec, executable_sp,
- &search_paths, nullptr, nullptr);
+ nullptr, nullptr);
if (!error.Fail() && executable_sp) {
SetExecutableModule(executable_sp, eLoadDependentsYes);
@@ -1854,6 +1856,9 @@ void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) {
}
void Target::ModulesDidLoad(ModuleList &module_list) {
+ if (GetPreloadSymbols())
+ module_list.PreloadSymbols(GetParallelModuleLoad());
+
const size_t num_images = module_list.GetSize();
if (m_valid && num_images) {
for (size_t idx = 0; idx < num_images; ++idx) {
@@ -2278,8 +2283,10 @@ size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_si
else
scalar = data.GetMaxU64(&offset, byte_size);
- if (is_signed)
+ if (is_signed) {
+ scalar.MakeSigned();
scalar.SignExtend(byte_size * 8);
+ }
return bytes_read;
}
} else {
@@ -2294,7 +2301,7 @@ int64_t Target::ReadSignedIntegerFromMemory(const Address &addr,
int64_t fail_value, Status &error,
bool force_live_memory) {
Scalar scalar;
- if (ReadScalarIntegerFromMemory(addr, integer_byte_size, false, scalar, error,
+ if (ReadScalarIntegerFromMemory(addr, integer_byte_size, true, scalar, error,
force_live_memory))
return scalar.SLongLong(fail_value);
return fail_value;
@@ -2349,6 +2356,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,
// Apply any remappings specified in target.object-map:
ModuleSpec module_spec(orig_module_spec);
+ module_spec.SetTarget(shared_from_this());
PathMappingList &obj_mapping = GetObjectPathMap();
if (std::optional<FileSpec> remapped_obj_file =
obj_mapping.RemapPath(orig_module_spec.GetFileSpec().GetPath(),
@@ -2407,9 +2415,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,
transformed_spec.GetFileSpec().SetDirectory(transformed_dir);
transformed_spec.GetFileSpec().SetFilename(
module_spec.GetFileSpec().GetFilename());
+ transformed_spec.SetTarget(shared_from_this());
error = ModuleList::GetSharedModule(transformed_spec, module_sp,
- &search_paths, &old_modules,
- &did_create_module);
+ &old_modules, &did_create_module);
}
}
}
@@ -2425,9 +2433,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,
// cache.
if (module_spec.GetUUID().IsValid()) {
// We have a UUID, it is OK to check the global module list...
- error =
- ModuleList::GetSharedModule(module_spec, module_sp, &search_paths,
- &old_modules, &did_create_module);
+ error = ModuleList::GetSharedModule(module_spec, module_sp,
+ &old_modules, &did_create_module);
}
if (!module_sp) {
@@ -2435,8 +2442,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,
// module in the shared module cache.
if (m_platform_sp) {
error = m_platform_sp->GetSharedModule(
- module_spec, m_process_sp.get(), module_sp, &search_paths,
- &old_modules, &did_create_module);
+ module_spec, m_process_sp.get(), module_sp, &old_modules,
+ &did_create_module);
} else {
error = Status::FromErrorString("no platform is currently set");
}
@@ -2508,10 +2515,6 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,
if (symbol_file_spec)
module_sp->SetSymbolFileFileSpec(symbol_file_spec);
- // Preload symbols outside of any lock, so hopefully we can do this for
- // each library in parallel.
- if (GetPreloadSymbols())
- module_sp->PreloadSymbols();
llvm::SmallVector<ModuleSP, 1> replaced_modules;
for (ModuleSP &old_module_sp : old_modules) {
if (m_images.GetIndexForModule(old_module_sp.get()) !=
@@ -3206,6 +3209,11 @@ bool Target::RunStopHooks(bool at_initial_stop) {
bool should_stop = false;
bool requested_continue = false;
+ // A stop hook might get deleted while running stop hooks.
+ // We have to decide what that means. We will follow the rule that deleting
+ // a stop hook while processing these stop hooks will delete it for FUTURE
+ // stops but not this stop. Fortunately, copying the m_stop_hooks to the
+ // active_hooks list before iterating over the hooks has this effect.
for (auto cur_hook_sp : active_hooks) {
bool any_thread_matched = false;
for (auto exc_ctx : exc_ctx_with_reasons) {
@@ -3712,6 +3720,61 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
return error;
}
+llvm::Expected<uint32_t> Target::AddScriptedFrameProviderDescriptor(
+ const ScriptedFrameProviderDescriptor &descriptor) {
+ if (!descriptor.IsValid())
+ return llvm::createStringError("invalid frame provider descriptor");
+
+ llvm::StringRef name = descriptor.GetName();
+ if (name.empty())
+ return llvm::createStringError(
+ "frame provider descriptor has no class name");
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_frame_provider_descriptors_mutex);
+
+ uint32_t descriptor_id = descriptor.GetID();
+ m_frame_provider_descriptors[descriptor_id] = descriptor;
+
+ // Clear frame providers on existing threads so they reload with new config.
+ if (ProcessSP process_sp = GetProcessSP())
+ for (ThreadSP thread_sp : process_sp->Threads())
+ thread_sp->ClearScriptedFrameProvider();
+
+ return descriptor_id;
+}
+
+bool Target::RemoveScriptedFrameProviderDescriptor(uint32_t id) {
+ std::lock_guard<std::recursive_mutex> guard(
+ m_frame_provider_descriptors_mutex);
+ bool removed = m_frame_provider_descriptors.erase(id);
+
+ if (removed)
+ if (ProcessSP process_sp = GetProcessSP())
+ for (ThreadSP thread_sp : process_sp->Threads())
+ thread_sp->ClearScriptedFrameProvider();
+
+ return removed;
+}
+
+void Target::ClearScriptedFrameProviderDescriptors() {
+ std::lock_guard<std::recursive_mutex> guard(
+ m_frame_provider_descriptors_mutex);
+
+ m_frame_provider_descriptors.clear();
+
+ if (ProcessSP process_sp = GetProcessSP())
+ for (ThreadSP thread_sp : process_sp->Threads())
+ thread_sp->ClearScriptedFrameProvider();
+}
+
+const llvm::DenseMap<uint32_t, ScriptedFrameProviderDescriptor> &
+Target::GetScriptedFrameProviderDescriptors() const {
+ std::lock_guard<std::recursive_mutex> guard(
+ m_frame_provider_descriptors_mutex);
+ return m_frame_provider_descriptors;
+}
+
void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
Log *log = GetLog(LLDBLog::Process);
@@ -3961,9 +4024,7 @@ void Target::StopHook::GetDescription(Stream &s,
return;
}
- unsigned indent_level = s.GetIndentLevel();
-
- s.SetIndentLevel(indent_level + 2);
+ auto indent_scope = s.MakeIndentScope();
s.Printf("Hook: %" PRIu64 "\n", GetID());
if (m_active)
@@ -3977,19 +4038,17 @@ void Target::StopHook::GetDescription(Stream &s,
if (m_specifier_sp) {
s.Indent();
s.PutCString("Specifier:\n");
- s.SetIndentLevel(indent_level + 4);
+ auto indent_scope = s.MakeIndentScope();
m_specifier_sp->GetDescription(&s, level);
- s.SetIndentLevel(indent_level + 2);
}
if (m_thread_spec_up) {
StreamString tmp;
s.Indent("Thread:\n");
m_thread_spec_up->GetDescription(&tmp, level);
- s.SetIndentLevel(indent_level + 4);
+ auto indent_scope = s.MakeIndentScope();
s.Indent(tmp.GetString());
s.PutCString("\n");
- s.SetIndentLevel(indent_level + 2);
}
GetSubclassDescription(s, level);
}
@@ -4002,14 +4061,13 @@ void Target::StopHookCommandLine::GetSubclassDescription(
s.PutCString(m_commands.GetStringAtIndex(0));
return;
}
- s.Indent("Commands: \n");
- s.SetIndentLevel(s.GetIndentLevel() + 4);
+ s.Indent("Commands:\n");
+ auto indent_scope = s.MakeIndentScope(4);
uint32_t num_commands = m_commands.GetSize();
for (uint32_t i = 0; i < num_commands; i++) {
s.Indent(m_commands.GetStringAtIndex(i));
s.PutCString("\n");
}
- s.SetIndentLevel(s.GetIndentLevel() - 4);
}
// Target::StopHookCommandLine
@@ -4144,7 +4202,7 @@ void Target::StopHookScripted::GetSubclassDescription(
return;
s.Indent("Args:\n");
- s.SetIndentLevel(s.GetIndentLevel() + 4);
+ auto indent_scope = s.MakeIndentScope(4);
auto print_one_element = [&s](llvm::StringRef key,
StructuredData::Object *object) {
@@ -4154,8 +4212,6 @@ void Target::StopHookScripted::GetSubclassDescription(
};
as_dict->ForEach(print_one_element);
-
- s.SetIndentLevel(s.GetIndentLevel() - 4);
}
static constexpr OptionEnumValueElement g_dynamic_value_types[] = {
@@ -4951,7 +5007,7 @@ void TargetProperties::SetStandardErrorPath(llvm::StringRef path) {
SourceLanguage TargetProperties::GetLanguage() const {
const uint32_t idx = ePropertyLanguage;
- return {GetPropertyAtIndexAs<LanguageType>(idx, {})};
+ return SourceLanguage{GetPropertyAtIndexAs<LanguageType>(idx, {})};
}
llvm::StringRef TargetProperties::GetExpressionPrefixContents() {
@@ -5089,17 +5145,17 @@ void TargetProperties::SetProcessLaunchInfo(
const FileAction *input_file_action =
launch_info.GetFileActionForFD(STDIN_FILENO);
if (input_file_action) {
- SetStandardInputPath(input_file_action->GetPath());
+ SetStandardInputPath(input_file_action->GetFileSpec().GetPath());
}
const FileAction *output_file_action =
launch_info.GetFileActionForFD(STDOUT_FILENO);
if (output_file_action) {
- SetStandardOutputPath(output_file_action->GetPath());
+ SetStandardOutputPath(output_file_action->GetFileSpec().GetPath());
}
const FileAction *error_file_action =
launch_info.GetFileActionForFD(STDERR_FILENO);
if (error_file_action) {
- SetStandardErrorPath(error_file_action->GetPath());
+ SetStandardErrorPath(error_file_action->GetFileSpec().GetPath());
}
SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));
SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));
@@ -5202,6 +5258,11 @@ Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp,
const ModuleList &module_list)
: EventData(), m_target_sp(target_sp), m_module_list(module_list) {}
+Target::TargetEventData::TargetEventData(
+ const lldb::TargetSP &target_sp, const lldb::TargetSP &created_target_sp)
+ : EventData(), m_target_sp(target_sp),
+ m_created_target_sp(created_target_sp), m_module_list() {}
+
Target::TargetEventData::~TargetEventData() = default;
llvm::StringRef Target::TargetEventData::GetFlavorString() {
@@ -5236,6 +5297,15 @@ TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) {
return target_sp;
}
+TargetSP
+Target::TargetEventData::GetCreatedTargetFromEvent(const Event *event_ptr) {
+ TargetSP created_target_sp;
+ const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ created_target_sp = event_data->m_created_target_sp;
+ return created_target_sp;
+}
+
ModuleList
Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {
ModuleList module_list;
@@ -5271,3 +5341,19 @@ void Target::ClearSectionLoadList() { GetSectionLoadList().Clear(); }
void Target::DumpSectionLoadList(Stream &s) {
GetSectionLoadList().Dump(s, this);
}
+
+void Target::NotifyBreakpointChanged(Breakpoint &bp,
+ lldb::BreakpointEventType eventKind) {
+ if (EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) {
+ std::shared_ptr<Breakpoint::BreakpointEventData> data_sp =
+ std::make_shared<Breakpoint::BreakpointEventData>(
+ eventKind, bp.shared_from_this());
+ BroadcastEvent(Target::eBroadcastBitBreakpointChanged, data_sp);
+ }
+}
+
+void Target::NotifyBreakpointChanged(
+ Breakpoint &bp, const lldb::EventDataSP &breakpoint_data_sp) {
+ if (EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
+ BroadcastEvent(Target::eBroadcastBitBreakpointChanged, breakpoint_data_sp);
+}
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index 188c250..ce04e9c 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -48,7 +48,7 @@ Status TargetList::CreateTarget(Debugger &debugger,
LoadDependentFiles load_dependent_files,
const OptionGroupPlatform *platform_options,
TargetSP &target_sp) {
- std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+
auto result = TargetList::CreateTargetInternal(
debugger, user_exe_path, triple_str, load_dependent_files,
platform_options, target_sp);
@@ -63,7 +63,7 @@ Status TargetList::CreateTarget(Debugger &debugger,
const ArchSpec &specified_arch,
LoadDependentFiles load_dependent_files,
PlatformSP &platform_sp, TargetSP &target_sp) {
- std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+
auto result = TargetList::CreateTargetInternal(
debugger, user_exe_path, specified_arch, load_dependent_files,
platform_sp, target_sp);
@@ -304,13 +304,9 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
ModuleSP exe_module_sp;
if (platform_sp) {
- FileSpecList executable_search_paths(
- Target::GetDefaultExecutableSearchPaths());
ModuleSpec module_spec(file, arch);
- error = platform_sp->ResolveExecutable(module_spec, exe_module_sp,
- executable_search_paths.GetSize()
- ? &executable_search_paths
- : nullptr);
+ module_spec.SetTarget(target_sp);
+ error = platform_sp->ResolveExecutable(module_spec, exe_module_sp);
}
if (error.Success() && exe_module_sp) {
@@ -525,6 +521,7 @@ uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const {
}
void TargetList::AddTargetInternal(TargetSP target_sp, bool do_select) {
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
lldbassert(!llvm::is_contained(m_target_list, target_sp) &&
"target already exists it the list");
UnregisterInProcessTarget(target_sp);
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 8c3e197..b40e753 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -13,9 +13,12 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
@@ -26,6 +29,7 @@
#include "lldb/Target/ScriptedThreadPlan.h"
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/SyntheticFrameProvider.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlan.h"
@@ -45,6 +49,7 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/ScriptedMetadata.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
@@ -257,6 +262,7 @@ void Thread::DestroyThread() {
std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
m_curr_frames_sp.reset();
m_prev_frames_sp.reset();
+ m_frame_provider_sp.reset();
m_prev_framezero_pc.reset();
}
@@ -1439,13 +1445,76 @@ void Thread::CalculateExecutionContext(ExecutionContext &exe_ctx) {
StackFrameListSP Thread::GetStackFrameList() {
std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
- if (!m_curr_frames_sp)
+ if (m_curr_frames_sp)
+ return m_curr_frames_sp;
+
+ // First, try to load a frame provider if we don't have one yet.
+ if (!m_frame_provider_sp) {
+ ProcessSP process_sp = GetProcess();
+ if (process_sp) {
+ Target &target = process_sp->GetTarget();
+ const auto &descriptors = target.GetScriptedFrameProviderDescriptors();
+
+ // Find first descriptor that applies to this thread.
+ for (const auto &entry : descriptors) {
+ const ScriptedFrameProviderDescriptor &descriptor = entry.second;
+ if (descriptor.IsValid() && descriptor.AppliesToThread(*this)) {
+ if (llvm::Error error = LoadScriptedFrameProvider(descriptor)) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(error),
+ "Failed to load scripted frame provider: {0}");
+ }
+ break; // Use first matching descriptor (success or failure).
+ }
+ }
+ }
+ }
+
+ // Create the frame list based on whether we have a provider.
+ if (m_frame_provider_sp) {
+ // We have a provider - create synthetic frame list.
+ StackFrameListSP input_frames = m_frame_provider_sp->GetInputFrames();
+ m_curr_frames_sp = std::make_shared<SyntheticStackFrameList>(
+ *this, input_frames, m_prev_frames_sp, true);
+ } else {
+ // No provider - use normal unwinder frames.
m_curr_frames_sp =
std::make_shared<StackFrameList>(*this, m_prev_frames_sp, true);
+ }
return m_curr_frames_sp;
}
+llvm::Error Thread::LoadScriptedFrameProvider(
+ const ScriptedFrameProviderDescriptor &descriptor) {
+ std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
+
+ // Note: We don't create input_frames here - it will be created lazily
+ // by SyntheticStackFrameList when frames are first fetched.
+ // Creating them too early can cause crashes during thread initialization.
+
+ // Create a temporary StackFrameList just to get the thread reference for the
+ // provider. The provider won't actually use this - it will get real input
+ // frames from SyntheticStackFrameList later.
+ StackFrameListSP temp_frames =
+ std::make_shared<StackFrameList>(*this, m_prev_frames_sp, true);
+
+ auto provider_or_err =
+ SyntheticFrameProvider::CreateInstance(temp_frames, descriptor);
+ if (!provider_or_err)
+ return provider_or_err.takeError();
+
+ ClearScriptedFrameProvider();
+ m_frame_provider_sp = *provider_or_err;
+ return llvm::Error::success();
+}
+
+void Thread::ClearScriptedFrameProvider() {
+ std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
+ m_frame_provider_sp.reset();
+ m_curr_frames_sp.reset();
+ m_prev_frames_sp.reset();
+}
+
std::optional<addr_t> Thread::GetPreviousFrameZeroPC() {
return m_prev_framezero_pc;
}
@@ -1466,6 +1535,7 @@ void Thread::ClearStackFrames() {
m_prev_frames_sp.swap(m_curr_frames_sp);
m_curr_frames_sp.reset();
+ m_frame_provider_sp.reset();
m_extended_info.reset();
m_extended_info_fetched = false;
}
diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp
index d49a01b..0307b38 100644
--- a/lldb/source/Target/ThreadPlanStepOut.cpp
+++ b/lldb/source/Target/ThreadPlanStepOut.cpp
@@ -356,13 +356,10 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) {
}
}
- // If there was only one owner, then we're done. But if we also hit
- // some user breakpoint on our way out, we should mark ourselves as
- // done, but also not claim to explain the stop, since it is more
- // important to report the user breakpoint than the step out
- // completion.
-
- if (site_sp->GetNumberOfConstituents() == 1)
+ // If the thread also hit a user breakpoint on its way out, the plan is
+ // done but should not claim to explain the stop. It is more important
+ // to report the user breakpoint than the step out completion.
+ if (!site_sp->ContainsUserBreakpointForThread(GetThread()))
return true;
}
return false;
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index dca96cc..3a9deb6 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -431,10 +431,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
top_most_line_entry.original_file_sp =
std::make_shared<SupportFile>(call_site_file_spec);
top_most_line_entry.range = range;
- top_most_line_entry.file_sp.reset();
+ top_most_line_entry.file_sp = std::make_shared<SupportFile>();
top_most_line_entry.ApplyFileMappings(
GetThread().CalculateTarget());
- if (!top_most_line_entry.file_sp)
+ if (!top_most_line_entry.file_sp->GetSpecOnly())
top_most_line_entry.file_sp =
top_most_line_entry.original_file_sp;
}
diff --git a/lldb/source/Target/ThreadSpec.cpp b/lldb/source/Target/ThreadSpec.cpp
index ba4c3aa..624f64e 100644
--- a/lldb/source/Target/ThreadSpec.cpp
+++ b/lldb/source/Target/ThreadSpec.cpp
@@ -19,6 +19,10 @@ const char *ThreadSpec::g_option_names[static_cast<uint32_t>(
ThreadSpec::ThreadSpec() : m_name(), m_queue_name() {}
+ThreadSpec::ThreadSpec(Thread &thread)
+ : m_index(thread.GetIndexID()), m_tid(thread.GetID()),
+ m_name(thread.GetName()), m_queue_name(thread.GetQueueName()) {}
+
std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData(
const StructuredData::Dictionary &spec_dict, Status &error) {
uint32_t index = UINT32_MAX;
diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp
index 6113c66..881431f 100644
--- a/lldb/source/Target/UnixSignals.cpp
+++ b/lldb/source/Target/UnixSignals.cpp
@@ -137,6 +137,13 @@ llvm::StringRef UnixSignals::GetSignalAsStringRef(int32_t signo) const {
return pos->second.m_name;
}
+llvm::StringRef UnixSignals::GetSignalNumberDescription(int32_t signo) const {
+ const auto pos = m_signals.find(signo);
+ if (pos == m_signals.end())
+ return {};
+ return pos->second.m_description;
+}
+
std::string UnixSignals::GetSignalDescription(
int32_t signo, std::optional<int32_t> code,
std::optional<lldb::addr_t> addr, std::optional<lldb::addr_t> lower,
diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
deleted file mode 100644
index 03ab58b..0000000
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "lldb/Target/VerboseTrapFrameRecognizer.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/StackFrameRecognizer.h"
-#include "lldb/Target/Target.h"
-
-#include "lldb/Utility/LLDBLog.h"
-#include "lldb/Utility/Log.h"
-
-#include "clang/CodeGen/ModuleBuilder.h"
-
-using namespace llvm;
-using namespace lldb;
-using namespace lldb_private;
-
-/// The 0th frame is the artificial inline frame generated to store
-/// the verbose_trap message. So, starting with the current parent frame,
-/// find the first frame that's not inside of the STL.
-static StackFrameSP FindMostRelevantFrame(Thread &selected_thread) {
- // Defensive upper-bound of when we stop walking up the frames in
- // case we somehow ended up looking at an infinite recursion.
- const size_t max_stack_depth = 128;
-
- // Start at parent frame.
- size_t stack_idx = 1;
- StackFrameSP most_relevant_frame_sp =
- selected_thread.GetStackFrameAtIndex(stack_idx);
-
- while (most_relevant_frame_sp && stack_idx <= max_stack_depth) {
- auto const &sc =
- most_relevant_frame_sp->GetSymbolContext(eSymbolContextEverything);
- ConstString frame_name = sc.GetFunctionName();
- if (!frame_name)
- return nullptr;
-
- // Found a frame outside of the `std` namespace. That's the
- // first frame in user-code that ended up triggering the
- // verbose_trap. Hence that's the one we want to display.
- if (!frame_name.GetStringRef().starts_with("std::"))
- return most_relevant_frame_sp;
-
- ++stack_idx;
- most_relevant_frame_sp = selected_thread.GetStackFrameAtIndex(stack_idx);
- }
-
- return nullptr;
-}
-
-VerboseTrapRecognizedStackFrame::VerboseTrapRecognizedStackFrame(
- StackFrameSP most_relevant_frame_sp, std::string stop_desc)
- : m_most_relevant_frame(most_relevant_frame_sp) {
- m_stop_desc = std::move(stop_desc);
-}
-
-lldb::RecognizedStackFrameSP
-VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
- if (frame_sp->GetFrameIndex())
- return {};
-
- ThreadSP thread_sp = frame_sp->GetThread();
- ProcessSP process_sp = thread_sp->GetProcess();
-
- StackFrameSP most_relevant_frame_sp = FindMostRelevantFrame(*thread_sp);
-
- if (!most_relevant_frame_sp) {
- Log *log = GetLog(LLDBLog::Unwind);
- LLDB_LOG(
- log,
- "Failed to find most relevant frame: Hit unwinding bound (1 frame)!");
- return {};
- }
-
- SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
-
- if (!sc.block)
- return {};
-
- // The runtime error is set as the function name in the inlined function info
- // of frame #0 by the compiler
- const InlineFunctionInfo *inline_info = nullptr;
- Block *inline_block = sc.block->GetContainingInlinedBlock();
-
- if (!inline_block)
- return {};
-
- inline_info = sc.block->GetInlinedFunctionInfo();
-
- if (!inline_info)
- return {};
-
- auto func_name = inline_info->GetName().GetStringRef();
- if (func_name.empty())
- return {};
-
- static auto trap_regex =
- llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());
- SmallVector<llvm::StringRef, 3> matches;
- std::string regex_err_msg;
- if (!trap_regex.match(func_name, &matches, &regex_err_msg)) {
- LLDB_LOGF(GetLog(LLDBLog::Unwind),
- "Failed to parse match trap regex for '%s': %s", func_name.data(),
- regex_err_msg.c_str());
-
- return {};
- }
-
- // For `__clang_trap_msg$category$message$` we expect 3 matches:
- // 1. entire string
- // 2. category
- // 3. message
- if (matches.size() != 3) {
- LLDB_LOGF(GetLog(LLDBLog::Unwind),
- "Unexpected function name format. Expected '<trap prefix>$<trap "
- "category>$<trap message>'$ but got: '%s'.",
- func_name.data());
-
- return {};
- }
-
- auto category = matches[1];
- auto message = matches[2];
-
- std::string stop_reason =
- category.empty() ? "<empty category>" : category.str();
- if (!message.empty()) {
- stop_reason += ": ";
- stop_reason += message.str();
- }
-
- return std::make_shared<VerboseTrapRecognizedStackFrame>(
- most_relevant_frame_sp, std::move(stop_reason));
-}
-
-lldb::StackFrameSP VerboseTrapRecognizedStackFrame::GetMostRelevantFrame() {
- return m_most_relevant_frame;
-}
-
-namespace lldb_private {
-
-void RegisterVerboseTrapFrameRecognizer(Process &process) {
- RegularExpressionSP module_regex_sp = nullptr;
- auto symbol_regex_sp = std::make_shared<RegularExpression>(
- llvm::formatv("^{0}", ClangTrapPrefix).str());
-
- StackFrameRecognizerSP srf_recognizer_sp =
- std::make_shared<VerboseTrapFrameRecognizer>();
-
- process.GetTarget().GetFrameRecognizerManager().AddRecognizer(
- srf_recognizer_sp, module_regex_sp, symbol_regex_sp,
- Mangled::ePreferDemangled, false);
-}
-
-} // namespace lldb_private