Skip to content
5 changes: 4 additions & 1 deletion lldb/bindings/interface/SBModuleSpecListExtensions.i
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ STRING_EXTENSION_OUTSIDE(SBModuleSpecList)
def __iter__(self):
'''Iterate over all ModuleSpecs in a lldb.SBModuleSpecList object.'''
return lldb_iter(self, 'GetSize', 'GetSpecAtIndex')

def __getitem__(self, index):
'''Get an lldb.SBModuleSpec at a given index, an invalid SBModuleSpec will be returned if the index is invalid.'''
return self.GetSpecAtIndex(index)
%}
#endif
}

8 changes: 8 additions & 0 deletions lldb/include/lldb/API/SBModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,14 @@ class LLDB_API SBModule {
/// A const reference to the file specification object.
lldb::SBFileSpec GetSymbolFileSpec() const;

/// Get a list of filespecs associated with all the separate symbol files
/// associated with this module.
///
/// \return
/// A list of filespecs associated with all the separate symbol files
/// associated with this module.
lldb::SBModuleSpecList GetSeparateDebugInfoFiles();

lldb::SBAddress GetObjectFileHeaderAddress() const;
lldb::SBAddress GetObjectFileEntryPointAddress() const;

Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/API/SBModuleSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ class SBModuleSpecList {
bool GetDescription(lldb::SBStream &description);

private:
friend class SBModule;

SBModuleSpecList(lldb_private::ModuleSpecList &&module_spec_list);
std::unique_ptr<lldb_private::ModuleSpecList> m_opaque_up;
};

Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,8 @@ class Module : public std::enable_shared_from_this<Module>,

const FileSpec &GetSymbolFileFileSpec() const { return m_symfile_spec; }

ModuleSpecList GetSeparateDebugInfoFiles();

void PreloadSymbols();

void SetSymbolFileFileSpec(const FileSpec &file);
Expand Down
12 changes: 12 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,18 @@ class SymbolFile : public PluginInterface {
/// symbol file doesn't support DWO files, both counts will be 0.
virtual std::pair<uint32_t, uint32_t> GetDwoFileCounts() { return {0, 0}; }

/// Return a map of separate debug info files that are loaded.
///
/// Unlike GetSeparateDebugInfo(), this function will only return the list of
/// files, if there are errors they are simply ignored. This function will
/// always return a valid list, even if it is empty.
///
/// \return
/// A unique list of all the filespecs, or an empty list.
virtual lldb_private::ModuleSpecList GetSeparateDebugInfoFiles() {
return {};
}

virtual lldb::TypeSP
MakeType(lldb::user_id_t uid, ConstString name,
std::optional<uint64_t> byte_size, SymbolContextScope *context,
Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFileOnDemand.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
load_all_debug_info);
}

lldb_private::ModuleSpecList GetSeparateDebugInfoFiles() override {
return m_sym_file_impl->GetSeparateDebugInfoFiles();
}

lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name,
std::optional<uint64_t> byte_size,
SymbolContextScope *context,
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/API/SBModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,14 @@ lldb::SBFileSpec SBModule::GetSymbolFileSpec() const {
return sb_file_spec;
}

lldb::SBModuleSpecList SBModule::GetSeparateDebugInfoFiles() {
ModuleSP module_sp(GetSP());
if (module_sp)
return lldb::SBModuleSpecList(module_sp->GetSeparateDebugInfoFiles());

return lldb::SBModuleSpecList();
}

lldb::SBAddress SBModule::GetObjectFileHeaderAddress() const {
LLDB_INSTRUMENT_VA(this);

Expand Down
5 changes: 5 additions & 0 deletions lldb/source/API/SBModuleSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ SBModuleSpecList::SBModuleSpecList(const SBModuleSpecList &rhs)
LLDB_INSTRUMENT_VA(this, rhs);
}

SBModuleSpecList::SBModuleSpecList(lldb_private::ModuleSpecList &&module_spec)
: m_opaque_up(new ModuleSpecList(std::move(module_spec))) {
LLDB_INSTRUMENT_VA(this);
}

SBModuleSpecList &SBModuleSpecList::operator=(const SBModuleSpecList &rhs) {
LLDB_INSTRUMENT_VA(this, rhs);

Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,3 +1647,11 @@ DataFileCache *Module::GetIndexCache() {
.GetPath());
return g_data_file_cache;
}

lldb_private::ModuleSpecList Module::GetSeparateDebugInfoFiles() {
SymbolFile *symfile = GetSymbolFile(false);
if (!symfile)
return {};

return symfile->GetSeparateDebugInfoFiles();
}
24 changes: 24 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4215,6 +4215,30 @@ void SymbolFileDWARF::DumpClangAST(Stream &s, llvm::StringRef filter) {
clang->Dump(s.AsRawOstream(), filter);
}

lldb_private::ModuleSpecList SymbolFileDWARF::GetSeparateDebugInfoFiles() {
DWARFDebugInfo &info = DebugInfo();
const size_t num_cus = info.GetNumUnits();
lldb_private::ModuleSpecList spec_list;
for (uint32_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
DWARFUnit *unit = info.GetUnitAtIndex(cu_idx);
DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(unit);
if (dwarf_cu == nullptr)
continue;

if (!dwarf_cu->GetDWOId().has_value())
continue;

SymbolFile *dwo_symfile = dwarf_cu->GetDwoSymbolFile();
if (!dwo_symfile)
continue;

lldb_private::FileSpec symfile_spec =
dwo_symfile->GetObjectFile()->GetFileSpec();
spec_list.Append(symfile_spec);
}
return spec_list;
}

bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d,
bool errors_only,
bool load_all_debug_info) {
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ class SymbolFileDWARF : public SymbolFileCommon {

void DumpClangAST(Stream &s, llvm::StringRef filter) override;

lldb_private::ModuleSpecList GetSeparateDebugInfoFiles() override;

/// List separate dwo files.
bool GetSeparateDebugInfo(StructuredData::Dictionary &d, bool errors_only,
bool load_all_debug_info = false) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,20 @@ void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s, llvm::StringRef filter) {
});
}

lldb_private::ModuleSpecList
SymbolFileDWARFDebugMap::GetSeparateDebugInfoFiles() {
const uint32_t cu_count = GetNumCompileUnits();
lldb_private::ModuleSpecList spec_list;
for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
const auto &info = m_compile_unit_infos[cu_idx];
if (info.so_file.GetPath().empty())
continue;

spec_list.Append(lldb_private::FileSpec(info.oso_path));
}
return spec_list;
}

bool SymbolFileDWARFDebugMap::GetSeparateDebugInfo(
lldb_private::StructuredData::Dictionary &d, bool errors_only,
bool load_all_debug_info) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {

void DumpClangAST(Stream &s, llvm::StringRef filter) override;

lldb_private::ModuleSpecList GetSeparateDebugInfoFiles() override;

/// List separate oso files.
bool GetSeparateDebugInfo(StructuredData::Dictionary &d, bool errors_only,
bool load_all_debug_info = false) override;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CXX_SOURCES := main.cpp

include Makefile.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import os, signal, subprocess

from lldbsuite.test import lldbutil


class SBModuleSeparateDebugInfoCase(TestBase):
def setUp(self):
TestBase.setUp(self)
self.background_pid = None

def tearDown(self):
TestBase.tearDown(self)
if self.background_pid:
os.kill(self.background_pid, signal.SIGKILL)

@skipIf(debug_info=no_match("dwo"))
def test_get_separate_debug_info_files_dwo(self):
"""Test the SBModule::GetSeparateDebugInfoFiles"""
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)

# Target should have a DWO
main_module = target.GetModuleAtIndex(0)
file_specs = main_module.GetSeparateDebugInfoFiles()
self.assertEqual(len(file_specs), 1)
self.assertTrue(file_specs[0].GetFileSpec().GetFilename().endswith(".dwo"))

@skipUnlessDarwin
@skipIf(debug_info=no_match("dwarf"))
def test_get_separate_debug_info_files_darwin_dwarf(self):
"""Test the SBModule::GetSeparateDebugInfoFiles"""
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)

# Target should have a DWO
main_module = target.GetModuleAtIndex(0)
file_specs = main_module.GetSeparateDebugInfoFiles()
self.assertEqual(len(file_specs), 1)
self.assertTrue(file_specs[0].GetFileSpec().GetFilename().endswith(".o"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
int main() {
int x = 40;
x += 2; // break here
return x;
}
Loading