mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 03:58:12 +00:00
Debugger: Support shared libraries
This makes our cli debugger, 'sdb', conform to the updated DebugSession API and support shared libraries.
This commit is contained in:
parent
4b91e7c821
commit
dcdb68a013
1 changed files with 40 additions and 34 deletions
|
@ -100,6 +100,33 @@ static bool handle_disassemble_command(const String& command, void* first_instru
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool insert_breakpoint_at_address(FlatPtr address)
|
||||||
|
{
|
||||||
|
return g_debug_session->insert_breakpoint((void*)address);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool insert_breakpoint_at_source_position(const String& file, size_t line)
|
||||||
|
{
|
||||||
|
auto result = g_debug_session->insert_breakpoint(file, line);
|
||||||
|
if (!result.has_value()) {
|
||||||
|
warnln("Could not insert breakpoint at {}:{}", file, line);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
outln("Breakpoint inserted [{}:{} ({}:{:p})]", result.value().file_name, result.value().line_number, result.value().library_name, result.value().address);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool insert_breakpoint_at_symbol(const String& symbol)
|
||||||
|
{
|
||||||
|
auto result = g_debug_session->insert_breakpoint(symbol);
|
||||||
|
if (!result.has_value()) {
|
||||||
|
warnln("Could not insert breakpoint at symbol: {}", symbol);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
outln("Breakpoint inserted [{}:{:p}]", result.value().library_name, result.value().address);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool handle_breakpoint_command(const String& command)
|
static bool handle_breakpoint_command(const String& command)
|
||||||
{
|
{
|
||||||
auto parts = command.split(' ');
|
auto parts = command.split(' ');
|
||||||
|
@ -110,8 +137,6 @@ static bool handle_breakpoint_command(const String& command)
|
||||||
if (argument.is_empty())
|
if (argument.is_empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u32 breakpoint_address = 0;
|
|
||||||
|
|
||||||
if (argument.contains(":")) {
|
if (argument.contains(":")) {
|
||||||
auto source_arguments = argument.split(':');
|
auto source_arguments = argument.split(':');
|
||||||
if (source_arguments.size() != 2)
|
if (source_arguments.size() != 2)
|
||||||
|
@ -120,32 +145,13 @@ static bool handle_breakpoint_command(const String& command)
|
||||||
if (!line.has_value())
|
if (!line.has_value())
|
||||||
return false;
|
return false;
|
||||||
auto file = source_arguments[0];
|
auto file = source_arguments[0];
|
||||||
if (!file.contains("/"))
|
return insert_breakpoint_at_source_position(file, line.value());
|
||||||
file = String::formatted("./{}", file);
|
}
|
||||||
auto result = g_debug_session->debug_info().get_instruction_from_source(file, line.value());
|
if ((argument.starts_with("0x"))) {
|
||||||
if (!result.has_value()) {
|
return insert_breakpoint_at_address(strtoul(argument.characters() + 2, nullptr, 16));
|
||||||
outln("No matching instruction found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
breakpoint_address = result.value();
|
|
||||||
} else if ((argument.starts_with("0x"))) {
|
|
||||||
breakpoint_address = strtoul(argument.characters() + 2, nullptr, 16);
|
|
||||||
} else {
|
|
||||||
auto symbol = g_debug_session->elf().find_demangled_function(argument);
|
|
||||||
if (!symbol.has_value()) {
|
|
||||||
outln("symbol {} not found", parts[1]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
breakpoint_address = reinterpret_cast<u32>(symbol.value().value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = g_debug_session->insert_breakpoint(reinterpret_cast<void*>(breakpoint_address));
|
return insert_breakpoint_at_symbol(argument);
|
||||||
if (!success) {
|
|
||||||
warnln("could not insert breakpoint at: {:p}", breakpoint_address);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
warnln("breakpoint inserted at: {:p}", breakpoint_address);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool handle_examine_command(const String& command)
|
static bool handle_examine_command(const String& command)
|
||||||
|
@ -212,14 +218,10 @@ int main(int argc, char** argv)
|
||||||
sa.sa_handler = handle_sigint;
|
sa.sa_handler = handle_sigint;
|
||||||
sigaction(SIGINT, &sa, nullptr);
|
sigaction(SIGINT, &sa, nullptr);
|
||||||
|
|
||||||
// bool rc = g_debug_session->insert_breakpoint(g_debug_session->elf().entry().as_ptr());
|
|
||||||
// bool rc = g_debug_session->insert_breakpoint((void*)0x08048f49);
|
|
||||||
// ASSERT(rc);
|
|
||||||
|
|
||||||
Debug::DebugInfo::SourcePosition previous_source_position;
|
Debug::DebugInfo::SourcePosition previous_source_position;
|
||||||
bool in_step_line = false;
|
bool in_step_line = false;
|
||||||
|
|
||||||
g_debug_session->run([&](Debug::DebugSession::DebugBreakReason reason, Optional<PtraceRegisters> optional_regs) {
|
g_debug_session->run(Debug::DebugSession::DesiredInitialDebugeeState::Stopped, [&](Debug::DebugSession::DebugBreakReason reason, Optional<PtraceRegisters> optional_regs) {
|
||||||
if (reason == Debug::DebugSession::DebugBreakReason::Exited) {
|
if (reason == Debug::DebugSession::DebugBreakReason::Exited) {
|
||||||
outln("Program exited.");
|
outln("Program exited.");
|
||||||
return Debug::DebugSession::DebugDecision::Detach;
|
return Debug::DebugSession::DebugDecision::Detach;
|
||||||
|
@ -228,8 +230,9 @@ int main(int argc, char** argv)
|
||||||
ASSERT(optional_regs.has_value());
|
ASSERT(optional_regs.has_value());
|
||||||
const PtraceRegisters& regs = optional_regs.value();
|
const PtraceRegisters& regs = optional_regs.value();
|
||||||
|
|
||||||
auto symbol_at_ip = g_debug_session->elf().symbolicate(regs.eip);
|
auto symbol_at_ip = g_debug_session->symbolicate(regs.eip);
|
||||||
auto source_position = g_debug_session->debug_info().get_source_position(regs.eip);
|
|
||||||
|
auto source_position = g_debug_session->get_source_position(regs.eip);
|
||||||
|
|
||||||
if (in_step_line) {
|
if (in_step_line) {
|
||||||
bool no_source_info = !source_position.has_value();
|
bool no_source_info = !source_position.has_value();
|
||||||
|
@ -242,7 +245,10 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outln("Program is stopped at: {:p} ({})", regs.eip, symbol_at_ip);
|
if (symbol_at_ip.has_value())
|
||||||
|
outln("Program is stopped at: {:p} ({}:{})", regs.eip, symbol_at_ip.value().library_name, symbol_at_ip.value().symbol);
|
||||||
|
else
|
||||||
|
outln("Program is stopped at: {:p}", regs.eip);
|
||||||
|
|
||||||
if (source_position.has_value()) {
|
if (source_position.has_value()) {
|
||||||
previous_source_position = source_position.value();
|
previous_source_position = source_position.value();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue