hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/debugger/debugger.cpp
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2025-02-08 01:59:56 +0100
committerhachem <im@hachem.wtf>2025-02-08 01:59:56 +0100
commit288f2ecea48f185205bda44a2737e74c813d29ba (patch)
treea57da01129a5ffdce44aeca6a4bfa13fdac31215 /src/debugger/debugger.cpp
parent66000c76d2c192df515d7a06af605587462d60be (diff)
feat: source tree and symbols panel
Diffstat (limited to 'src/debugger/debugger.cpp')
-rw-r--r--src/debugger/debugger.cpp92
1 files changed, 92 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);