1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 19:57:41 +00:00

Debugger: Use LibLine

This commit is contained in:
Itamar 2020-04-16 12:41:13 +03:00 committed by Andreas Kling
parent ef6dc61291
commit 1642fdf82d
2 changed files with 13 additions and 30 deletions

View file

@ -3,6 +3,6 @@ OBJS = \
PROGRAM = Debugger PROGRAM = Debugger
LIB_DEPS = Core X86 Debug LIB_DEPS = Core X86 Debug Line
include ../../Makefile.common include ../../Makefile.common

View file

@ -33,6 +33,7 @@
#include <LibC/sys/arch/i386/regs.h> #include <LibC/sys/arch/i386/regs.h>
#include <LibCore/File.h> #include <LibCore/File.h>
#include <LibDebug/DebugSession.h> #include <LibDebug/DebugSession.h>
#include <LibLine/Editor.h>
#include <LibX86/Disassembler.h> #include <LibX86/Disassembler.h>
#include <LibX86/Instruction.h> #include <LibX86/Instruction.h>
#include <signal.h> #include <signal.h>
@ -41,6 +42,8 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
static Line::Editor editor {};
static int usage() static int usage()
{ {
printf("usage: sdb [command...]\n"); printf("usage: sdb [command...]\n");
@ -57,28 +60,6 @@ static void handle_sigint(int)
g_debug_session = nullptr; g_debug_session = nullptr;
} }
String get_command()
{
printf("(sdb) ");
fflush(stdout);
char* line = nullptr;
size_t allocated_size = 0;
ssize_t nread = getline(&line, &allocated_size, stdin);
if (nread < 0) {
if (errno == 0) {
fprintf(stderr, "\n");
} else {
perror("getline");
exit(1);
}
}
String command(line);
free(line);
if (command.ends_with('\n'))
command = command.substring(0, command.length() - 1);
return command;
}
void handle_print_registers(const PtraceRegisters& regs) void handle_print_registers(const PtraceRegisters& regs)
{ {
printf("eax: 0x%x\n", regs.eax); printf("eax: 0x%x\n", regs.eax);
@ -176,7 +157,7 @@ void print_help()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if (pledge("stdio proc exec rpath", nullptr) < 0) { if (pledge("stdio proc exec rpath tty", nullptr) < 0) {
perror("pledge"); perror("pledge");
return 1; return 1;
} }
@ -184,6 +165,8 @@ int main(int argc, char** argv)
if (argc == 1) if (argc == 1)
return usage(); return usage();
editor.initialize();
StringBuilder command; StringBuilder command;
command.append(argv[1]); command.append(argv[1]);
for (int i = 2; i < argc; ++i) { for (int i = 2; i < argc; ++i) {
@ -205,8 +188,6 @@ int main(int argc, char** argv)
bool rc = g_debug_session->insert_breakpoint(g_debug_session->elf().entry().as_ptr()); bool rc = g_debug_session->insert_breakpoint(g_debug_session->elf().entry().as_ptr());
ASSERT(rc); ASSERT(rc);
String previous_command;
g_debug_session->run([&](DebugSession::DebugBreakReason reason, Optional<PtraceRegisters> optional_regs) { g_debug_session->run([&](DebugSession::DebugBreakReason reason, Optional<PtraceRegisters> optional_regs) {
if (reason == DebugSession::DebugBreakReason::Exited) { if (reason == DebugSession::DebugBreakReason::Exited) {
printf("Program exited.\n"); printf("Program exited.\n");
@ -219,12 +200,12 @@ int main(int argc, char** argv)
auto symbol_at_ip = g_debug_session->elf().symbolicate(regs.eip); auto symbol_at_ip = g_debug_session->elf().symbolicate(regs.eip);
printf("Program is stopped at: 0x%x (%s)\n", regs.eip, symbol_at_ip.characters()); printf("Program is stopped at: 0x%x (%s)\n", regs.eip, symbol_at_ip.characters());
for (;;) { for (;;) {
auto command = get_command(); auto command = editor.get_line("(sdb) ");
bool success = false; bool success = false;
Optional<DebugSession::DebugDecision> decision; Optional<DebugSession::DebugDecision> decision;
if (command.is_empty() && !previous_command.is_empty()) { if (command.is_empty() && !editor.history().is_empty()) {
command = previous_command; command = editor.history().last();
} }
if (command == "cont") { if (command == "cont") {
decision = DebugSession::DebugDecision::Continue; decision = DebugSession::DebugDecision::Continue;
@ -247,7 +228,9 @@ int main(int argc, char** argv)
} }
if (success && !command.is_empty()) { if (success && !command.is_empty()) {
previous_command = command; // Don't add repeated commands to history
if (editor.history().is_empty() || editor.history().last() != command)
editor.add_to_history(command);
} }
if (!success) { if (!success) {
print_help(); print_help();