diff options
Diffstat (limited to 'src/debugger')
| -rw-r--r-- | src/debugger/debugger.cpp | 92 | ||||
| -rw-r--r-- | src/debugger/debugger.h | 3 |
2 files changed, 95 insertions, 0 deletions
diff --git a/src/debugger/debugger.cpp b/src/debugger/debugger.cpp index 2d7d06b..9086f40 100644 --- a/src/debugger/debugger.cpp +++ b/src/debugger/debugger.cpp @@ -7,6 +7,7 @@ #include <algorithm> #include <array> +#include <set> #include <source_location> #include <cstdlib> @@ -300,6 +301,78 @@ namespace Hsdbg return symbols; } + auto is_system_source(const std::filesystem::path& path) -> bool + { + const std::string text = path.generic_string(); + + constexpr std::string_view markers[] = { + "/usr/", + "/opt/", + "/Library/", + "/Applications/", + "/System/", + "/c++/v1/", + "\\Program Files", + "\\Windows Kits", + }; + + return std::ranges::any_of(markers, [&](std::string_view marker) + { + return text.find(marker) != std::string::npos; + }); + } + + auto normalize_source(const std::filesystem::path& path) -> std::filesystem::path + { + std::error_code error; + std::filesystem::path canonical = std::filesystem::weakly_canonical(path, error); + + return error ? path.lexically_normal() : canonical; + } + + auto module_source_files(lldb::SBTarget& target) -> std::vector<std::filesystem::path> + { + std::set<std::filesystem::path> files; + + lldb::SBModule module = target.FindModule(target.GetExecutable()); + + if (!module.IsValid()) + return {}; + + for (uint32_t index = 0; index < module.GetNumCompileUnits(); ++index) + { + lldb::SBCompileUnit unit = module.GetCompileUnitAtIndex(index); + + if (!unit.IsValid()) + continue; + + if (std::filesystem::path cu = path_of(unit.GetFileSpec()); !cu.empty()) + { + cu = normalize_source(cu); + + if (std::filesystem::is_regular_file(cu)) + files.insert(cu); + } + + for (uint32_t support = 0; support < unit.GetNumSupportFiles(); ++support) + { + std::filesystem::path path = path_of(unit.GetSupportFileAtIndex(support)); + + if (path.empty() || is_system_source(path)) + continue; + + path = normalize_source(path); + + if (!std::filesystem::is_regular_file(path)) + continue; + + files.insert(std::move(path)); + } + } + + return { files.begin(), files.end() }; + } + auto display_of(lldb::SBValue& value) -> std::string { const char* text = value.GetValue(); @@ -441,6 +514,7 @@ namespace Hsdbg m_disassembly.clear(); m_disassembly_name.clear(); m_selected_symbol = 0; + refresh_source_files(); refresh_disassembly(); return {}; @@ -463,6 +537,7 @@ namespace Hsdbg m_locals.clear(); m_registers.clear(); m_symbols.clear(); + m_source_files.clear(); m_disassembly.clear(); m_disassembly_name.clear(); m_console_output.clear(); @@ -618,6 +693,9 @@ namespace Hsdbg Log::info("debugger: attached to pid {}", m_process_id); + if (m_source_files.empty()) + refresh_source_files(); + sync_after_start(); return {}; @@ -1355,6 +1433,16 @@ namespace Hsdbg m_symbols = module_symbols(m_session->target); } + auto Debugger::refresh_source_files() -> void + { + m_source_files.clear(); + + if (!m_session->target.IsValid()) + return; + + m_source_files = module_source_files(m_session->target); + } + auto Debugger::load_disassembly(uint64_t file_address) -> void { m_disassembly.clear(); @@ -1409,6 +1497,7 @@ namespace Hsdbg if (!m_session->target.IsValid()) { m_symbols.clear(); + m_source_files.clear(); m_disassembly.clear(); m_disassembly_name.clear(); m_selected_symbol = 0; @@ -1418,6 +1507,9 @@ namespace Hsdbg if (m_symbols.empty()) refresh_symbols(); + if (m_source_files.empty()) + refresh_source_files(); + for (Symbol& symbol : m_symbols) { lldb::SBAddress address = m_session->target.ResolveFileAddress(symbol.file_address); diff --git a/src/debugger/debugger.h b/src/debugger/debugger.h index 04b5e61..06b6ae9 100644 --- a/src/debugger/debugger.h +++ b/src/debugger/debugger.h @@ -54,6 +54,7 @@ namespace Hsdbg auto locals() const -> std::span<const Variable> { return m_locals; } auto registers() const -> std::span<const Register> { return m_registers; } auto symbols() const -> std::span<const Symbol> { return m_symbols; } + auto source_files() const -> std::span<const std::filesystem::path> { return m_source_files; } auto disassembly() const -> std::span<const Instruction> { return m_disassembly; } auto disassembly_name() const -> std::string_view { return m_disassembly_name; } auto evaluate(std::string_view expression) -> Result<std::string>; @@ -97,6 +98,7 @@ namespace Hsdbg auto refresh_call_stack() -> void; auto refresh_frame_data() -> void; auto refresh_symbols() -> void; + auto refresh_source_files() -> void; auto refresh_disassembly() -> void; auto load_disassembly(uint64_t file_address) -> void; @@ -116,6 +118,7 @@ namespace Hsdbg std::vector<Variable> m_locals; std::vector<Register> m_registers; std::vector<Symbol> m_symbols; + std::vector<std::filesystem::path> m_source_files; std::vector<Instruction> m_disassembly; std::string m_disassembly_name; std::vector<std::string> m_console_output; |
