aboutsummaryrefslogtreecommitdiff
path: root/src/debugger
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-18 12:25:58 +0200
committerhachem <im@hachem.wtf>2026-09-18 12:25:58 +0200
commit4f74d1400180ca4ad7cfcd1903386fda8779818d (patch)
tree258a332c3076045461b5d6f8592a52140225abd1 /src/debugger
parent0846724177d823b632f2a4deffdcb5b6e226cd56 (diff)
feat: improve layout and themes
Diffstat (limited to 'src/debugger')
-rw-r--r--src/debugger/debugger.cpp42
-rw-r--r--src/debugger/debugger.h3
-rw-r--r--src/debugger/types.h9
3 files changed, 52 insertions, 2 deletions
diff --git a/src/debugger/debugger.cpp b/src/debugger/debugger.cpp
index 525ad65..c2b4c22 100644
--- a/src/debugger/debugger.cpp
+++ b/src/debugger/debugger.cpp
@@ -558,6 +558,19 @@ namespace Hsdbg
lldb::SBDebugger::Terminate();
}
+ auto Debugger::backend_version() -> std::string
+ {
+ // "lldb version 22.1.0 (https://… revision …)\n clang revision …": keep the number
+ std::string banner = lldb::SBDebugger::GetVersionString();
+ if (const size_t cut = banner.find_first_of("(\n"); cut != std::string::npos)
+ banner.resize(cut);
+ if (banner.starts_with("lldb version "))
+ banner.erase(0, 13);
+ while (!banner.empty() && banner.back() == ' ')
+ banner.pop_back();
+ return banner;
+ }
+
auto Debugger::load_target(const std::filesystem::path& executable) -> Result<void>
{
std::error_code error;
@@ -2142,6 +2155,19 @@ namespace Hsdbg
frame.line = entry.GetLine();
}
+ // the function's first and last line entries: its opening and, via
+ // the last instruction, its closing line
+ if (lldb::SBFunction function = source.GetFunction(); function.IsValid())
+ {
+ if (lldb::SBLineEntry first = function.GetStartAddress().GetLineEntry(); first.IsValid())
+ frame.function_first_line = first.GetLine();
+
+ const lldb::addr_t end = function.GetEndAddress().GetLoadAddress(m_session->target);
+ lldb::SBAddress tail = m_session->target.ResolveLoadAddress(end - 1);
+ if (lldb::SBLineEntry last = tail.GetLineEntry(); last.IsValid())
+ frame.function_last_line = std::max(last.GetLine(), frame.line);
+ }
+
m_call_stack.push_back(std::move(frame));
}
}
@@ -2162,13 +2188,25 @@ namespace Hsdbg
return;
lldb::SBValueList variables = frame.GetVariables(true, true, false, true);
+ const std::filesystem::path frame_file = path_of(frame.GetLineEntry().GetFileSpec());
for (uint32_t index = 0; index < variables.GetSize(); ++index)
{
lldb::SBValue value = variables.GetValueAtIndex(index);
- if (value.IsValid())
- m_locals.push_back(to_variable(value, 0));
+ if (!value.IsValid())
+ continue;
+
+ Variable variable = to_variable(value, 0);
+
+ if (lldb::SBDeclaration declaration = value.GetDeclaration();
+ declaration.IsValid() && !frame_file.empty() &&
+ path_of(declaration.GetFileSpec()) == frame_file)
+ {
+ variable.declaration_line = declaration.GetLine();
+ }
+
+ m_locals.push_back(std::move(variable));
}
lldb::SBValueList sets = frame.GetRegisters();
diff --git a/src/debugger/debugger.h b/src/debugger/debugger.h
index 840dff1..7608934 100644
--- a/src/debugger/debugger.h
+++ b/src/debugger/debugger.h
@@ -31,6 +31,9 @@ namespace Hsdbg
auto operator=(const Debugger&) -> Debugger& = delete;
auto operator=(Debugger&&) -> Debugger& = delete;
+ // the lldb build behind the session: the first line of its version banner
+ static auto backend_version() -> std::string;
+
// target lifetime
auto load_target(const std::filesystem::path& executable) -> Result<void>;
auto unload_target() -> void;
diff --git a/src/debugger/types.h b/src/debugger/types.h
index 53c6622..288df6b 100644
--- a/src/debugger/types.h
+++ b/src/debugger/types.h
@@ -110,6 +110,11 @@ namespace Hsdbg
std::string function;
std::filesystem::path file;
uint32_t line = 0;
+
+ // the lines the function spans in that file (zero when unknown, as for
+ // an inlined frame), so the ui can keep its annotations inside it
+ uint32_t function_first_line = 0;
+ uint32_t function_last_line = 0;
};
struct Thread
@@ -125,6 +130,10 @@ namespace Hsdbg
std::string type;
std::string value;
std::vector<Variable> children;
+
+ // the line the variable is declared on in the frame's own file (a
+ // parameter's is the signature), zero when unknown or elsewhere
+ uint32_t declaration_line = 0;
};
struct Register