]> git.feebdaed.xyz Git - 0xmirror/radare2.git/commitdiff
Fix radare2 gdb remote debugging support and add test ##debug
authorpotato <30723680+0verflowme@users.noreply.github.com>
Sun, 21 Dec 2025 09:28:00 +0000 (14:58 +0530)
committerGitHub <noreply@github.com>
Sun, 21 Dec 2025 09:28:00 +0000 (10:28 +0100)
libr/main/radare2.c
test/unit/Makefile
test/unit/test_debug.c

index 536e492f1b2673e56f64376adbb2c396740c7be8..0a2e3b5547df3bc7beac97c8fc906af78a0c9d86 100644 (file)
@@ -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) {
index 0007e9c117d44fcbbc2f52744b5c3c1aa308e921..3c2b1c2ab129c73d85cd1f5ba13627923008b2ad 100644 (file)
@@ -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 \
index 8e01b9068a302b93a7d474e11b02e75557975264..fa7116c0c2a496da453b819065fcd7bce3dd57f8 100644 (file)
@@ -1,7 +1,19 @@
+#include <r_core.h>
 #include <r_debug.h>
+#include <r_main.h>
+#include <r_util/r_file.h>
+#include <r_util/r_str.h>
+#include <r_util/r_sys.h>
 #include "minunit.h"
 #if __linux__
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/socket.h>
 #include <sys/user.h>
+#include <sys/wait.h>
+#include <unistd.h>
 
 #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;
 }