[Lldb-commits] [lldb] [llvm] Add support for ondemand sourcefile fetch using python callback (PR #119118)
via lldb-commits
lldb-commits at lists.llvm.org
Sat Dec 7 22:53:48 PST 2024
https://github.com/rchamala created https://github.com/llvm/llvm-project/pull/119118
None
>From 1b984ba9747618e277c8ffb2c48467aec7c2a6a3 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 10 Jun 2024 12:08:38 -0700
Subject: [PATCH 1/2] [BOLT][NFC] Add sink block to flow CFG in profile
inference
Test Plan: tbd
Reviewers:
Subscribers:
Tasks:
Tags:
Differential Revision: https://phabricator.intern.facebook.com/D58380996
---
bolt/lib/Profile/StaleProfileMatching.cpp | 38 ++++++++++++++++---
.../Transforms/Utils/SampleProfileInference.h | 3 +-
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/bolt/lib/Profile/StaleProfileMatching.cpp b/bolt/lib/Profile/StaleProfileMatching.cpp
index 365bc5389266df..8ecfb618072abf 100644
--- a/bolt/lib/Profile/StaleProfileMatching.cpp
+++ b/bolt/lib/Profile/StaleProfileMatching.cpp
@@ -309,22 +309,33 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
FlowFunction Func;
// Add a special "dummy" source so that there is always a unique entry point.
- // Because of the extra source, for all other blocks in FlowFunction it holds
- // that Block.Index == BB->getIndex() + 1
FlowBlock EntryBlock;
EntryBlock.Index = 0;
Func.Blocks.push_back(EntryBlock);
+ auto BinaryBlockIsExit = [&](const BinaryBasicBlock &BB) {
+ if (BB.successors().empty())
+ return true;
+ return false;
+ };
+
// Create FlowBlock for every basic block in the binary function
for (const BinaryBasicBlock *BB : BlockOrder) {
Func.Blocks.emplace_back();
FlowBlock &Block = Func.Blocks.back();
Block.Index = Func.Blocks.size() - 1;
+ Block.HasSuccessors = BinaryBlockIsExit(*BB);
(void)BB;
assert(Block.Index == BB->getIndex() + 1 &&
"incorrectly assigned basic block index");
}
+ // Add a special "dummy" sink block so there is always a unique sink
+ FlowBlock SinkBlock;
+ SinkBlock.Index = Func.Blocks.size();
+ Func.Blocks.push_back(SinkBlock);
+ Func.Sink = SinkBlock.Index;
+
// Create FlowJump for each jump between basic blocks in the binary function
std::vector<uint64_t> InDegree(Func.Blocks.size(), 0);
for (const BinaryBasicBlock *SrcBB : BlockOrder) {
@@ -360,18 +371,29 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
// Add dummy edges to the extra sources. If there are multiple entry blocks,
// add an unlikely edge from 0 to the subsequent ones
assert(InDegree[0] == 0 && "dummy entry blocks shouldn't have predecessors");
- for (uint64_t I = 1; I < Func.Blocks.size(); I++) {
+ for (uint64_t I = 1; I < BlockOrder.size() + 1; I++) {
const BinaryBasicBlock *BB = BlockOrder[I - 1];
if (BB->isEntryPoint() || InDegree[I] == 0) {
Func.Jumps.emplace_back();
FlowJump &Jump = Func.Jumps.back();
- Jump.Source = 0;
+ Jump.Source = Func.Entry;
Jump.Target = I;
if (!BB->isEntryPoint())
Jump.IsUnlikely = true;
}
}
+ // Add dummy edges from the exit blocks to the sink block.
+ for (uint64_t I = 1; I < BlockOrder.size() + 1; I++) {
+ FlowBlock &Block = Func.Blocks[I];
+ if (Block.HasSuccessors) {
+ Func.Jumps.emplace_back();
+ FlowJump &Jump = Func.Jumps.back();
+ Jump.Source = I;
+ Jump.Target = Func.Sink;
+ }
+ }
+
// Create necessary metadata for the flow function
for (FlowJump &Jump : Func.Jumps) {
assert(Jump.Source < Func.Blocks.size());
@@ -379,6 +401,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
assert(Jump.Target < Func.Blocks.size());
Func.Blocks[Jump.Target].PredJumps.push_back(&Jump);
}
+
return Func;
}
@@ -395,7 +418,7 @@ void matchWeightsByHashes(BinaryContext &BC,
const BinaryFunction::BasicBlockOrderType &BlockOrder,
const yaml::bolt::BinaryFunctionProfile &YamlBF,
FlowFunction &Func) {
- assert(Func.Blocks.size() == BlockOrder.size() + 1);
+ assert(Func.Blocks.size() == BlockOrder.size() + 2);
std::vector<FlowBlock *> Blocks;
std::vector<BlendedBlockHash> BlendedHashes;
@@ -618,7 +641,7 @@ void assignProfile(BinaryFunction &BF,
FlowFunction &Func) {
BinaryContext &BC = BF.getBinaryContext();
- assert(Func.Blocks.size() == BlockOrder.size() + 1);
+ assert(Func.Blocks.size() == BlockOrder.size() + 2);
for (uint64_t I = 0; I < BlockOrder.size(); I++) {
FlowBlock &Block = Func.Blocks[I + 1];
BinaryBasicBlock *BB = BlockOrder[I];
@@ -640,6 +663,9 @@ void assignProfile(BinaryFunction &BF,
if (Jump->Flow == 0)
continue;
+ // Skip the artificial sink block
+ if (Jump->Target == Func.Sink)
+ continue;
BinaryBasicBlock &SuccBB = *BlockOrder[Jump->Target - 1];
// Check if the edge corresponds to a regular jump or a landing pad
if (BB->getSuccessor(SuccBB.getLabel())) {
diff --git a/llvm/include/llvm/Transforms/Utils/SampleProfileInference.h b/llvm/include/llvm/Transforms/Utils/SampleProfileInference.h
index b4ea1ad840f9d9..b2af05a24c7055 100644
--- a/llvm/include/llvm/Transforms/Utils/SampleProfileInference.h
+++ b/llvm/include/llvm/Transforms/Utils/SampleProfileInference.h
@@ -31,10 +31,10 @@ struct FlowBlock {
uint64_t Flow{0};
std::vector<FlowJump *> SuccJumps;
std::vector<FlowJump *> PredJumps;
+ bool HasSuccessors{false};
/// Check if it is the entry block in the function.
bool isEntry() const { return PredJumps.empty(); }
-
/// Check if it is an exit block in the function.
bool isExit() const { return SuccJumps.empty(); }
};
@@ -57,6 +57,7 @@ struct FlowFunction {
std::vector<FlowJump> Jumps;
/// The index of the entry block.
uint64_t Entry{0};
+ uint64_t Sink{0};
};
/// Various thresholds and options controlling the behavior of the profile
>From 5a97d761a5e2e0b112e54cfb988418b97d350d9f Mon Sep 17 00:00:00 2001
From: Rahul Reddy Chamala <rachamal at fb.com>
Date: Mon, 30 Sep 2024 12:26:41 -0700
Subject: [PATCH 2/2] Add support for ondemand sourcefile fetch using python
callback
Summary:
Test Plan:
Reviewers:
Subscribers:
Tasks:
Tags:
Differential Revision: https://phabricator.intern.facebook.com/D66931972
---
lldb/bindings/python/python-typemaps.swig | 44 ++++++++++++++++++
lldb/bindings/python/python-wrapper.swig | 48 +++++++++++++++++++-
lldb/include/lldb/API/SBDefines.h | 8 +++-
lldb/include/lldb/API/SBPlatform.h | 3 ++
lldb/include/lldb/Symbol/LineEntry.h | 3 +-
lldb/include/lldb/Target/Platform.h | 14 ++++++
lldb/source/API/SBPlatform.cpp | 36 +++++++++++++++
lldb/source/Symbol/LineEntry.cpp | 44 +++++++++++++++++-
lldb/source/Target/Platform.cpp | 54 +++++++++++++++++++++++
lldb/source/Target/StackFrame.cpp | 2 +-
lldb/source/Target/StackFrameList.cpp | 3 +-
11 files changed, 253 insertions(+), 6 deletions(-)
diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35ca..787787994a62c9 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -696,3 +696,47 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
$1 = $input == Py_None;
$1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
}
+
+// For lldb::SBPlatformResolveSourceFileCallback
+%typemap(in) (lldb::SBPlatformResolveSourceFileCallback callback, void *callback_baton) {
+ if (!($input == Py_None ||
+ PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
+ PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+ SWIG_fail;
+ }
+
+ if ($input == Py_None) {
+ $1 = nullptr;
+ $2 = nullptr;
+ } else {
+ PythonCallable callable = Retain<PythonCallable>($input);
+ if (!callable.IsValid()) {
+ PyErr_SetString(PyExc_TypeError, "Need a valid callable object");
+ SWIG_fail;
+ }
+
+ llvm::Expected<PythonCallable::ArgInfo> arg_info = callable.GetArgInfo();
+ if (!arg_info) {
+ PyErr_SetString(PyExc_TypeError,
+ ("Could not get arguments: " +
+ llvm::toString(arg_info.takeError())).c_str());
+ SWIG_fail;
+ }
+
+ if (arg_info.get().max_positional_args != 3) {
+ PyErr_SetString(PyExc_TypeError, "Expected 3 argument callable object");
+ SWIG_fail;
+ }
+
+ Py_INCREF($input);
+
+ $1 = LLDBSwigPythonCallResolveSourceFileCallback;
+ $2 = $input;
+ }
+}
+
+%typemap(typecheck) (lldb::SBPlatformResolveSourceFileCallback callback,
+ void *callback_baton) {
+ $1 = $input == Py_None;
+ $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
+}
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43f..e10b8c5a9481e7 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -844,7 +844,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallParsedCommandObject(
auto pfunc = self.ResolveName<PythonCallable>("__call__");
if (!pfunc.IsAllocated()) {
- cmd_retobj.AppendError("Could not find '__call__' method in implementation class");
+ cmd_retobj.AppendError("Could not find '__call__' method in implementation class");
return false;
}
@@ -1148,4 +1148,50 @@ static SBError LLDBSwigPythonCallLocateModuleCallback(
return *sb_error_ptr;
}
+
+static SBError LLDBSwigPythonCallResolveSourceFileCallback(
+ void *callback_baton,
+ const char* build_id,
+ const SBFileSpec &original_source_file_spec_sb,
+ SBFileSpec &resolved_source_file_spec_sb) {
+ SWIG_Python_Thread_Block swig_thread_block;
+
+ PyErr_Cleaner py_err_cleaner(true);
+
+ PyObject *py_build_id = PyUnicode_FromString(build_id);
+ PythonObject build_id_arg(PyRefType::Borrowed,py_build_id);
+ PythonObject original_source_file_spec_arg = SWIGBridge::ToSWIGWrapper(
+ std::make_unique<SBFileSpec>(original_source_file_spec_sb));
+ PythonObject resolved_source_file_spec_arg = SWIGBridge::ToSWIGWrapper(
+ std::make_unique<SBFileSpec>(resolved_source_file_spec_sb));
+
+ PythonCallable callable =
+ Retain<PythonCallable>(reinterpret_cast<PyObject *>(callback_baton));
+ if (!callable.IsValid()) {
+ return SBError("The callback callable is not valid.");
+ }
+
+ PythonObject result = callable(build_id_arg, original_source_file_spec_arg,
+ resolved_source_file_spec_arg);
+
+ if (!result.IsAllocated())
+ return SBError("No result.");
+ lldb::SBError *sb_error_ptr = nullptr;
+ if (SWIG_ConvertPtr(result.get(), (void **)&sb_error_ptr,
+ SWIGTYPE_p_lldb__SBError, 0) == -1) {
+ return SBError("Result is not SBError.");
+ }
+
+ if (sb_error_ptr->Success()) {
+ lldb::SBFileSpec *sb_resolved_source_file_spec_ptr = nullptr;
+ if (SWIG_ConvertPtr(resolved_source_file_spec_arg.get(),
+ (void **)&sb_resolved_source_file_spec_ptr,
+ SWIGTYPE_p_lldb__SBFileSpec, 0) == -1)
+ return SBError("resolved_source_file_spec is not SBFileSpec.");
+
+ resolved_source_file_spec_sb = *sb_resolved_source_file_spec_ptr;
+ }
+
+ return *sb_error_ptr;
+}
%}
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index 87c0a1c3661ca3..94ba0082c7bc7f 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -12,6 +12,7 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
#include "lldb/lldb-types.h"
#include "lldb/lldb-versioning.h"
@@ -141,9 +142,14 @@ typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process,
typedef void (*SBDebuggerDestroyCallback)(lldb::user_id_t debugger_id,
void *baton);
-typedef SBError (*SBPlatformLocateModuleCallback)(
+typedef lldb::SBError (*SBPlatformLocateModuleCallback)(
void *baton, const SBModuleSpec &module_spec, SBFileSpec &module_file_spec,
SBFileSpec &symbol_file_spec);
+
+typedef lldb::SBError (*SBPlatformResolveSourceFileCallback)(
+ void *baton, const char *buildId,
+ const SBFileSpec &original_source_file_spec,
+ SBFileSpec &resolved_source_file_spec);
}
#endif // LLDB_API_SBDEFINES_H
diff --git a/lldb/include/lldb/API/SBPlatform.h b/lldb/include/lldb/API/SBPlatform.h
index d63d2ed1eaba62..37ab2ef0441cf5 100644
--- a/lldb/include/lldb/API/SBPlatform.h
+++ b/lldb/include/lldb/API/SBPlatform.h
@@ -190,6 +190,9 @@ class LLDB_API SBPlatform {
SBError SetLocateModuleCallback(lldb::SBPlatformLocateModuleCallback callback,
void *callback_baton);
+ SBError SetResolveSourceFileCallback(
+ lldb::SBPlatformResolveSourceFileCallback callback, void *callback_baton);
+
protected:
friend class SBDebugger;
friend class SBTarget;
diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h
index 8da59cf0bd24aa..38916d31b31f4e 100644
--- a/lldb/include/lldb/Symbol/LineEntry.h
+++ b/lldb/include/lldb/Symbol/LineEntry.h
@@ -128,7 +128,7 @@ struct LineEntry {
///
/// \param[in] target_sp
/// Shared pointer to the target this LineEntry belongs to.
- void ApplyFileMappings(lldb::TargetSP target_sp);
+ void ApplyFileMappings(lldb::TargetSP target_sp, const Address &address);
/// Helper to access the file.
const FileSpec &GetFile() const { return file_sp->GetSpecOnly(); }
@@ -181,6 +181,7 @@ struct LineEntry {
/// Returns \b true if lhs < rhs, false otherwise.
bool operator<(const LineEntry &lhs, const LineEntry &rhs);
+// Add signature for CallFetchSourceFileCallBack
} // namespace lldb_private
#endif // LLDB_SYMBOL_LINEENTRY_H
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index e05c79cb501bf0..85d208c4752320 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -329,6 +329,10 @@ class Platform : public PluginInterface {
virtual bool GetModuleSpec(const FileSpec &module_file_spec,
const ArchSpec &arch, ModuleSpec &module_spec);
+ void CallResolveSourceFileCallbackIfSet(
+ const char *build_id, const FileSpec &original_source_file_spec,
+ FileSpec &resolved_source_file_spec, bool *did_create_ptr);
+
virtual Status ConnectRemote(Args &args);
virtual Status DisconnectRemote();
@@ -921,6 +925,11 @@ class Platform : public PluginInterface {
FileSpec &symbol_file_spec)>
LocateModuleCallback;
+ typedef std::function<Status(const char *buildId,
+ const FileSpec &original_fileSpec,
+ FileSpec &newFileSpec)>
+ ResolveSourceFileCallback;
+
/// Set locate module callback. This allows users to implement their own
/// module cache system. For example, to leverage artifacts of build system,
/// to bypass pulling files from remote platform, or to search symbol files
@@ -929,6 +938,10 @@ class Platform : public PluginInterface {
LocateModuleCallback GetLocateModuleCallback() const;
+ void SetResolveSourceFileCallback(ResolveSourceFileCallback callback);
+
+ ResolveSourceFileCallback GetResolveSourceFileCallback() const;
+
protected:
/// Create a list of ArchSpecs with the given OS and a architectures. The
/// vendor field is left as an "unspecified unknown".
@@ -977,6 +990,7 @@ class Platform : public PluginInterface {
bool m_calculated_trap_handlers;
const std::unique_ptr<ModuleCache> m_module_cache;
LocateModuleCallback m_locate_module_callback;
+ ResolveSourceFileCallback m_resolve_source_file_callback;
/// Ask the Platform subclass to fill in the list of trap handler names
///
diff --git a/lldb/source/API/SBPlatform.cpp b/lldb/source/API/SBPlatform.cpp
index 3623fd35bcdf13..b01a396091f9fa 100644
--- a/lldb/source/API/SBPlatform.cpp
+++ b/lldb/source/API/SBPlatform.cpp
@@ -734,3 +734,39 @@ SBError SBPlatform::SetLocateModuleCallback(
});
return SBError();
}
+
+SBError SBPlatform::SetResolveSourceFileCallback(
+ lldb::SBPlatformResolveSourceFileCallback callback, void *callback_baton) {
+ LLDB_INSTRUMENT_VA(this, callback, callback_baton);
+ PlatformSP platform_sp(GetSP());
+ if (!platform_sp) {
+ return SBError("invalid platform");
+ }
+
+ if (!callback) {
+ // Clear the callback.
+ platform_sp->SetResolveSourceFileCallback(nullptr);
+ return SBError("invalid callback");
+ }
+
+ // Platform.h does not accept lldb::SBPlatformFetchSourceFileCallback
+ // directly because of the SBFileSpec dependencies. Use a lambda to convert
+ // FileSpec <--> SBFileSpec for the callback arguments.
+ platform_sp->SetResolveSourceFileCallback(
+ [callback, callback_baton](const char *build_id,
+ const FileSpec &original_source_file_spec,
+ FileSpec &resolved_source_file_spec) {
+ SBFileSpec resolved_source_file_spec_sb(resolved_source_file_spec);
+
+ SBError error =
+ callback(callback_baton, build_id, original_source_file_spec,
+ resolved_source_file_spec_sb);
+
+ if (error.Success()) {
+ resolved_source_file_spec = resolved_source_file_spec_sb.ref();
+ }
+
+ return error.ref();
+ });
+ return SBError();
+}
diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp
index 461399e0326e91..c175f3ace6d309 100644
--- a/lldb/source/Symbol/LineEntry.cpp
+++ b/lldb/source/Symbol/LineEntry.cpp
@@ -7,7 +7,10 @@
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -240,8 +243,47 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange(
return complete_line_range;
}
-void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {
+void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp,
+ const Address &address) {
if (target_sp) {
+
+ SymbolContext sc;
+ target_sp->GetImages().ResolveSymbolContextForAddress(
+ address, lldb::eSymbolContextModule, sc);
+ lldb::ModuleSP module_sp = sc.module_sp;
+
+ auto spec = original_file_sp->GetSpecOnly();
+ std::string path = spec.GetPath();
+
+ if (module_sp) {
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ module_sp->GetFileSpec();
+ if (obj_file) {
+
+ UUID build_id = obj_file->GetUUID();
+ auto buildId_string = new std::string(build_id.GetAsString());
+
+ const char *build_id_ptr = buildId_string->c_str();
+
+ FileSpec newSpec;
+ // Fetches the new spec file
+ bool *didFetchSourceFile = new bool(false);
+
+ lldb::PlatformSP platform_sp = target_sp->GetPlatform();
+ if (!platform_sp)
+ return;
+
+ FileSpec resolved_source_file_spec;
+ platform_sp->CallResolveSourceFileCallbackIfSet(
+ build_id_ptr, spec, resolved_source_file_spec, didFetchSourceFile);
+ if (didFetchSourceFile) {
+ original_file_sp =
+ std::make_shared<SupportFile>(resolved_source_file_spec);
+ file_sp = std::make_shared<SupportFile>(resolved_source_file_spec);
+ }
+ }
+ }
+
// Apply any file remappings to our file.
if (auto new_file_spec = target_sp->GetSourcePathMap().FindFile(
original_file_sp->GetSpecOnly()))
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index ee1f92470e162e..f2dc82ab515b30 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1756,6 +1756,50 @@ void Platform::CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec,
}
}
+void Platform::CallResolveSourceFileCallbackIfSet(
+ const char *build_id, const FileSpec &original_source_file_spec,
+ FileSpec &resolved_source_file_spec, bool *did_create_ptr) {
+ if (!m_resolve_source_file_callback) {
+ // Fetch source file callback is not set.
+ return;
+ }
+
+ FileSpec module_file_spec;
+ Status error = m_resolve_source_file_callback(
+ build_id, original_source_file_spec, resolved_source_file_spec);
+
+ // Fetch source file callback is set and called. Check the error.
+ Log *log = GetLog(LLDBLog::Platform);
+ if (error.Fail()) {
+ LLDB_LOGF(log, "%s: Fetch source file callback failed: %s",
+ LLVM_PRETTY_FUNCTION, error.AsCString());
+ return;
+ }
+
+ if (!resolved_source_file_spec) {
+ LLDB_LOGF(log,
+ "%s: fetch source file callback did not set "
+ "resolved_source_file_spec",
+ LLVM_PRETTY_FUNCTION);
+ return;
+ }
+
+ // If the callback returned a source file, it should exist.
+ if (resolved_source_file_spec &&
+ !FileSystem::Instance().Exists(resolved_source_file_spec)) {
+ LLDB_LOGF(log,
+ "%s: fetch source file callback set a non-existent file to "
+ "source_file_spec: %s",
+ LLVM_PRETTY_FUNCTION,
+ resolved_source_file_spec.GetPath().c_str());
+ // Clear source_file_spec for the error.
+ resolved_source_file_spec.Clear();
+ return;
+ }
+
+ *did_create_ptr = true;
+}
+
bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec,
lldb::ModuleSP &module_sp,
bool *did_create_ptr) {
@@ -2161,6 +2205,16 @@ Platform::LocateModuleCallback Platform::GetLocateModuleCallback() const {
return m_locate_module_callback;
}
+void Platform::SetResolveSourceFileCallback(
+ ResolveSourceFileCallback callback) {
+ m_resolve_source_file_callback = callback;
+}
+
+Platform::ResolveSourceFileCallback
+Platform::GetResolveSourceFileCallback() const {
+ return m_resolve_source_file_callback;
+}
+
PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const PlatformSP &platform_sp : m_platforms) {
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 3a2b4d05b28810..988f66f038c258 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -395,7 +395,7 @@ StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
if ((resolved & eSymbolContextLineEntry) &&
!m_sc.line_entry.IsValid()) {
m_sc.line_entry = sc.line_entry;
- m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
+ m_sc.line_entry.ApplyFileMappings(m_sc.target_sp, lookup_addr);
}
}
} else {
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index 314b5e39c71699..e676e3c4053816 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -551,7 +551,8 @@ bool StackFrameList::GetFramesUpTo(uint32_t end_idx,
while (unwind_sc.GetParentOfInlinedScope(
curr_frame_address, next_frame_sc, next_frame_address)) {
- next_frame_sc.line_entry.ApplyFileMappings(target_sp);
+ next_frame_sc.line_entry.ApplyFileMappings(target_sp,
+ curr_frame_address);
behaves_like_zeroth_frame = false;
StackFrameSP frame_sp(new StackFrame(
m_thread.shared_from_this(), m_frames.size(), idx,
More information about the lldb-commits
mailing list