mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-19 12:22:43 +00:00
io_gdb: gdb://host:port/pid support; Add gdbr_{attach,detach,detach_pid,kill_pid} to gdbclient. (#7759)
Try to activate extended mode; Attach helper function requires extended mode to actually do something. Tries to attach to the given pid in io_gdb. This isn't proper, but it's better than running into the two-pid-vals-no-sync issue.
This commit is contained in:
parent
ba1bba5401
commit
d8f5cdb11c
@ -206,9 +206,7 @@ static int r_debug_gdb_attach(RDebug *dbg, int pid) {
|
||||
}
|
||||
|
||||
static int r_debug_gdb_detach(RDebug *dbg, int pid) {
|
||||
gdbr_disconnect (desc);
|
||||
free (reg_buf);
|
||||
return true;
|
||||
return gdbr_detach_pid (desc, pid);
|
||||
}
|
||||
|
||||
static const char *r_debug_gdb_reg_profile(RDebug *dbg) {
|
||||
|
@ -75,7 +75,7 @@ static int debug_gdb_write_at(const ut8 *buf, int sz, ut64 addr) {
|
||||
|
||||
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
|
||||
RIOGdb *riog;
|
||||
char host[128], *port, *p;
|
||||
char host[128], *port, *pid;
|
||||
|
||||
if (!__plugin_open (io, file, 0))
|
||||
return NULL;
|
||||
@ -87,13 +87,17 @@ static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
|
||||
host [sizeof (host)-1] = '\0';
|
||||
port = strchr (host , ':');
|
||||
if (!port) {
|
||||
eprintf ("Port not specified. Please use gdb://[host]:[port]\n");
|
||||
eprintf ("Port not specified. Please use gdb://host:port[/port]\n");
|
||||
return NULL;
|
||||
}
|
||||
*port = '\0';
|
||||
port++;
|
||||
p = strchr (port, '/');
|
||||
if (p) *p = 0;
|
||||
|
||||
pid = strchr (port, '/');
|
||||
if (pid) {
|
||||
*pid = 0;
|
||||
pid++;
|
||||
}
|
||||
|
||||
if (r_sandbox_enable (0)) {
|
||||
eprintf ("sandbox: Cannot use network\n");
|
||||
@ -102,8 +106,18 @@ static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
|
||||
riog = R_NEW0 (RIOGdb);
|
||||
gdbr_init (&riog->desc, false);
|
||||
int i_port = atoi(port);
|
||||
int i_pid = -1;
|
||||
if (pid)
|
||||
i_pid = atoi(pid);
|
||||
|
||||
if (gdbr_connect (&riog->desc, host, i_port) == 0) {
|
||||
desc = &riog->desc;
|
||||
desc->pid = i_pid;
|
||||
if (pid) { // FIXME this is here for now because RDebug's pid and libgdbr's aren't properly synced.
|
||||
int ret = gdbr_attach (desc, i_pid);
|
||||
if (ret < 0)
|
||||
eprintf ("gdbr: Failed to attach to PID %i\n", i_pid);
|
||||
}
|
||||
riogdb = r_io_desc_new (&r_io_plugin_gdb, riog->desc.sock->fd, file, rw, mode, riog);
|
||||
return riogdb;
|
||||
}
|
||||
|
@ -19,12 +19,34 @@ int gdbr_connect(libgdbr_t *g, const char *server, int port);
|
||||
*/
|
||||
int gdbr_disconnect(libgdbr_t *g);
|
||||
|
||||
/*!
|
||||
* \brief checks for extended mode availability
|
||||
* \returns a failure code (currently -1) or 0 if call successfully
|
||||
*/
|
||||
int gdbr_check_extended_mode(libgdbr_t *g);
|
||||
|
||||
/*!
|
||||
* \brief attaches to a process
|
||||
* \param pid of the process to attach to
|
||||
* \returns a failure code (currently -1) or 0 if call successfully
|
||||
*/
|
||||
int gdbr_attach(libgdbr_t *g, int pid);
|
||||
|
||||
/*!
|
||||
* \brief detaches from a process
|
||||
* \param pid of the process to detach from (only the multiprocess/pid variant)
|
||||
* \returns a failure code (currently -1) or 0 if call successfully
|
||||
*/
|
||||
int gdbr_detach(libgdbr_t *g);
|
||||
int gdbr_detach_pid(libgdbr_t *g, int pid);
|
||||
|
||||
/*!
|
||||
* \brief kills the process the remote gdbserver is debugging (TODO: handle pid)
|
||||
* \param pid of the process to detach from (only the multiprocess/pid variant)
|
||||
* \retuns a failure code (currently -1) or 0 if call successfully
|
||||
*/
|
||||
bool gdbr_kill(libgdbr_t *g);
|
||||
|
||||
bool gdbr_kill_pid(libgdbr_t *g, int pid);
|
||||
|
||||
// Commands
|
||||
int gdbr_continue(libgdbr_t *g, int thread_id);
|
||||
|
@ -13,6 +13,10 @@
|
||||
#include "../utils.h"
|
||||
#include "../arch.h"
|
||||
|
||||
#define CMD_ATTACH "vAttach;"
|
||||
#define CMD_DETACH_MP "D;"
|
||||
#define CMD_KILL_MP "vKill;"
|
||||
|
||||
#define CMD_READREGS "g"
|
||||
#define CMD_WRITEREGS "G"
|
||||
#define CMD_READREG "p"
|
||||
|
@ -28,5 +28,6 @@ int handle_fstat(libgdbr_t* g);
|
||||
int handle_qSupported(libgdbr_t* g);
|
||||
int handle_setbp(libgdbr_t* g);
|
||||
int handle_removebp(libgdbr_t* g);
|
||||
int handle_attach(libgdbr_t* g);
|
||||
|
||||
#endif // RESPONSES_H
|
||||
|
@ -83,6 +83,8 @@ typedef struct libgdbr_stub_features_t {
|
||||
bool BreakpointCommands;
|
||||
// Cannot be determined with qSupported, found out on query
|
||||
bool qC;
|
||||
|
||||
bool extended_mode;
|
||||
} libgdbr_stub_features_t;
|
||||
|
||||
/*!
|
||||
|
@ -139,6 +139,9 @@ int gdbr_connect(libgdbr_t *g, const char *host, int port) {
|
||||
if (strncmp (g->data, "OK", 2)) {
|
||||
// return -1;
|
||||
}
|
||||
|
||||
gdbr_check_extended_mode (g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -151,26 +154,170 @@ int gdbr_disconnect(libgdbr_t *g) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool gdbr_kill(libgdbr_t *g) {
|
||||
char buf[20];
|
||||
|
||||
int gdbr_check_extended_mode(libgdbr_t *g) {
|
||||
int ret;
|
||||
|
||||
// Activate extended mode if possible.
|
||||
ret = send_msg (g, "!");
|
||||
if (ret < 0) {
|
||||
g->stub_features.extended_mode = false;
|
||||
return ret;
|
||||
}
|
||||
read_packet (g);
|
||||
ret = send_ack (g);
|
||||
if (strncmp (g->data, "OK", 2)) {
|
||||
g->stub_features.extended_mode = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
g->stub_features.extended_mode = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int gdbr_attach(libgdbr_t *g, int pid) {
|
||||
int ret;
|
||||
char *cmd;
|
||||
size_t buffer_size;
|
||||
|
||||
if (!g || !g->sock || !g->stub_features.multiprocess) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!g->stub_features.extended_mode) {
|
||||
// vAttach needs extended mode to do anything.
|
||||
return -2;
|
||||
}
|
||||
|
||||
buffer_size = strlen (CMD_ATTACH) + (sizeof (int) * 2) + 1;
|
||||
cmd = calloc (buffer_size, sizeof (char));
|
||||
if (!cmd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = snprintf (cmd, buffer_size, "%s%x", CMD_ATTACH, pid);
|
||||
if (ret < 0) {
|
||||
free(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = send_msg (g, cmd);
|
||||
free(cmd);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (read_packet (g) >= 0) {
|
||||
return handle_attach (g);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gdbr_detach(libgdbr_t *g) {
|
||||
int ret;
|
||||
|
||||
if (!g || !g->sock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (g->stub_features.multiprocess) {
|
||||
if (!g->pid) {
|
||||
return -1;
|
||||
}
|
||||
return gdbr_detach_pid (g, g->pid);
|
||||
}
|
||||
|
||||
ret = send_msg (g, "D");
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdbr_detach_pid(libgdbr_t *g, int pid) {
|
||||
char *cmd;
|
||||
int ret;
|
||||
size_t buffer_size;
|
||||
|
||||
if (!g || !g->sock || !g->stub_features.multiprocess) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_size = strlen (CMD_DETACH_MP) + (sizeof (pid) * 2) + 1;
|
||||
cmd = calloc(buffer_size, sizeof (char));
|
||||
if (!cmd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((snprintf (cmd, buffer_size, "%s%x", CMD_DETACH_MP, g->pid)) < 0) {
|
||||
free(cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = send_msg (g, cmd);
|
||||
free(cmd);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
read_packet (g);
|
||||
if ((ret = send_ack (g)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strncmp (g->data, "OK", 2)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool gdbr_kill(libgdbr_t *g) {
|
||||
int ret;
|
||||
|
||||
if (!g || g->sock) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g->stub_features.multiprocess) {
|
||||
if (!g->pid) {
|
||||
return false;
|
||||
}
|
||||
snprintf (buf, sizeof (buf) - 1, "vKill;%x", g->pid);
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf) - 1, "k");
|
||||
return gdbr_kill_pid (g, g->pid);
|
||||
}
|
||||
if ((ret = send_msg (g, buf)) < 0) {
|
||||
|
||||
ret = send_msg (g, "k");
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
if (!g->stub_features.multiprocess) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gdbr_kill_pid(libgdbr_t *g, int pid) {
|
||||
char *cmd;
|
||||
int ret;
|
||||
size_t buffer_size;
|
||||
|
||||
if (!g || !g->sock || !g->stub_features.multiprocess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer_size = strlen(CMD_KILL_MP) + (sizeof(pid) * 2) + 1;
|
||||
cmd = calloc(buffer_size, sizeof (char));
|
||||
if (!cmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((snprintf (cmd, buffer_size, "%s%x", CMD_KILL_MP, g->pid)) < 0) {
|
||||
free(cmd);
|
||||
return false;
|
||||
}
|
||||
ret = send_msg (g, cmd);
|
||||
free(cmd);
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_packet (g);
|
||||
if ((ret = send_ack (g)) < 0) {
|
||||
return false;
|
||||
|
@ -170,3 +170,11 @@ int handle_setbp(libgdbr_t *g) {
|
||||
int handle_removebp(libgdbr_t *g) {
|
||||
return send_ack (g);
|
||||
}
|
||||
|
||||
int handle_attach(libgdbr_t *g) {
|
||||
if (g->data_len == 3 && g->data[0] == 'E') {
|
||||
send_ack (g);
|
||||
return -1;
|
||||
}
|
||||
return send_ack (g);
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Requires GNU Make, but some distros probably don't have the gmake symlink.
|
||||
[ -z "$MAKE" ] && MAKE=make
|
||||
|
||||
while : ; do
|
||||
if [ -f sys/rebuild.sh ]; then
|
||||
break
|
||||
@ -13,14 +16,14 @@ done
|
||||
|
||||
Rebuild() {
|
||||
cd "$1" || exit 1
|
||||
make clean
|
||||
make -j8 || exit 1
|
||||
$MAKE clean
|
||||
$MAKE -j8 || exit 1
|
||||
cd -
|
||||
}
|
||||
|
||||
Build() {
|
||||
cd "$1" || exit 1
|
||||
make -j8 || exit 1
|
||||
$MAKE -j8 || exit 1
|
||||
cd -
|
||||
}
|
||||
|
||||
@ -29,7 +32,7 @@ RebuildIOSDebug() {
|
||||
# Rebuild libr/util
|
||||
# Rebuild libr/core
|
||||
Rebuild binr/radare2
|
||||
make -C binr/radare2 ios-sign
|
||||
$MAKE -C binr/radare2 ios-sign
|
||||
if [ -n "${IOSIP}" ]; then
|
||||
scp binr/radare2/radare2 root@"${IOSIP}:."
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user