From 9b8c604e2e7e9d8efa302bf230ac262b36f91da1 Mon Sep 17 00:00:00 2001 From: potato <30723680+0verflowme@users.noreply.github.com> Date: Sun, 21 Dec 2025 14:58:00 +0530 Subject: [PATCH] Fix radare2 gdb remote debugging support and add test ##debug --- libr/main/radare2.c | 9 +++- test/unit/Makefile | 5 ++- test/unit/test_debug.c | 99 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/libr/main/radare2.c b/libr/main/radare2.c index 536e492f1b..0a2e3b5547 100644 --- a/libr/main/radare2.c +++ b/libr/main/radare2.c @@ -1535,9 +1535,14 @@ R_API int r_main_radare2(int argc, const char **argv) { ret = 1; goto beach; } - mr.fh = r_core_file_open (r, mr.pfile, mr.perms, mr.mapaddr); + const char *binpath = mr.pfile; + if (mr.debug == 2 && mr.fh) { + binpath = NULL; + } else { + mr.fh = r_core_file_open (r, mr.pfile, mr.perms, mr.mapaddr); + } if (mr.fh) { - r_core_bin_load (r, mr.pfile, mr.baddr); + r_core_bin_load (r, binpath, mr.baddr); } } if (opt.ind < argc) { diff --git a/test/unit/Makefile b/test/unit/Makefile index 0007e9c117..3c2b1c2ab1 100644 --- a/test/unit/Makefile +++ b/test/unit/Makefile @@ -3,7 +3,7 @@ BINS=$(patsubst %.c,$(UNITS_BINDIR)/%,$(wildcard *.c)) # LDFLAGS+=$(shell pkg-config --libs r_core) -include ../../config-user.mk LDFLAGS+=-L$(LIBDIR) -LDFLAGS+=-lr_core -lm -lr_config -lr_debug -lr_bin -lr_lang -lr_anal -lr_bp -lr_egg -lr_asm -lr_flag -lr_search -lr_syscall -lr_fs -lr_io -lr_socket -lr_cons -lr_magic -lr_muta -lr_arch -lr_esil -lr_reg -lr_util -ldl +LDFLAGS+=-lr_core -lr_main -lm -lr_config -lr_debug -lr_bin -lr_lang -lr_anal -lr_bp -lr_egg -lr_asm -lr_flag -lr_search -lr_syscall -lr_fs -lr_io -lr_socket -lr_cons -lr_magic -lr_muta -lr_arch -lr_esil -lr_reg -lr_util -ldl CFLAGS+=-I$(INCLUDEDIR) CFLAGS+=-I../../libr/include CFLAGS+=-I../../subprojects/sdb/include @@ -23,6 +23,9 @@ $(UNITS_BINDIR)/%: %.c mkdir -p "$(UNITS_BINDIR)" $(CC) $< -o $@ $(CFLAGS) $(LDFLAGS) +test_debug: $(UNITS_BINDIR)/test_debug + @: + run: $(BINS) @export R2_DEBUG_ASSERT=1 ; R=0 ; r=0 ; cd .. ; \ for a in $(BINS) ; do \ diff --git a/test/unit/test_debug.c b/test/unit/test_debug.c index 8e01b9068a..fa7116c0c2 100644 --- a/test/unit/test_debug.c +++ b/test/unit/test_debug.c @@ -1,7 +1,19 @@ +#include #include +#include +#include +#include +#include #include "minunit.h" #if __linux__ +#include +#include +#include +#include +#include #include +#include +#include #ifndef offsetof #define offsetof(type, field) ((size_t) &((type *)0)->field) @@ -23,6 +35,92 @@ bool test_r_debug_use(void) { mu_end; } +static int pick_free_port(void) { +#if __linux__ + int sockfd = socket (AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + return -1; + } + struct sockaddr_in addr; + memset (&addr, 0, sizeof (addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + addr.sin_port = 0; + if (bind (sockfd, (struct sockaddr *)&addr, sizeof (addr)) < 0) { + close (sockfd); + return -1; + } + socklen_t len = sizeof (addr); + if (getsockname (sockfd, (struct sockaddr *)&addr, &len) < 0) { + close (sockfd); + return -1; + } + int port = ntohs (addr.sin_port); + close (sockfd); + return port; +#else + return -1; +#endif +} + +bool test_r2_gdb_remote_open(void) { +#if __linux__ + char *gdbserver = r_file_path ("gdbserver"); + if (!gdbserver) { + mu_ignore; + } + int port = pick_free_port (); + if (port <= 0) { + free (gdbserver); + mu_ignore; + } + char *portstr = r_str_newf ("%d", port); + char *listen = r_str_newf ("127.0.0.1:%s", portstr); + char *uri = r_str_newf ("gdb://%s", listen); + pid_t pid = r_sys_fork (); + if (pid < 0) { + free (gdbserver); + free (portstr); + free (listen); + free (uri); + mu_assert ("fork failed", false); + } + if (pid == 0) { + execl (gdbserver, "gdbserver", "--once", listen, "/bin/sleep", "2", NULL); + r_sys_exit (1, true); + } + + r_sys_usleep (500000); + const char *argv[] = { "radare2", "-q", "-d", "-D", "gdb", "-Qc", "q", uri, NULL }; + int ret = r_main_radare2 (8, argv); + int status = 0; + int waited = 0; + int wpid = 0; + while (waited < 20) { + wpid = waitpid (pid, &status, WNOHANG); + if (wpid == pid) { + break; + } + r_sys_usleep (100000); + waited++; + } + if (wpid == 0) { + kill (pid, SIGKILL); + waitpid (pid, &status, 0); + } + + free (gdbserver); + free (portstr); + free (listen); + free (uri); + + mu_assert_eq (ret, 0, "r2 gdb remote open failed"); + mu_end; +#else + mu_ignore; +#endif +} + bool test_r_debug_reg_offset(void) { #if __linux__ #ifdef __x86_64__ @@ -54,6 +152,7 @@ bool test_r_debug_reg_offset(void) { int all_tests(void) { mu_run_test (test_r_debug_use); + mu_run_test (test_r2_gdb_remote_open); mu_run_test (test_r_debug_reg_offset); return tests_passed != tests_run; } -- 2.43.0