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 <shawbyo...@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 <racha...@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, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits