sort of remove infinite loop

This commit is contained in:
Srimanta Barua 2017-09-29 17:40:01 +05:30 committed by radare
parent 852584ffac
commit 5eebf1efba
5 changed files with 54 additions and 23 deletions

View file

@ -1013,6 +1013,9 @@ static int cb_dbg_forks(void *user, void *data) {
static int cb_dbg_gdb_page_size(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (node->i_value < 64) { // 64 is hardcoded min packet size
return false;
}
if (core->io && core->io->desc && core->io->desc->plugin
&& core->io->desc->plugin->name
&& !strcmp (core->io->desc->plugin->name, "gdb")) {
@ -1023,6 +1026,22 @@ static int cb_dbg_gdb_page_size(void *user, void *data) {
return true;
}
static int cb_dbg_gdb_retries(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (node->i_value <= 0) {
return false;
}
if (core->io && core->io->desc && core->io->desc->plugin
&& core->io->desc->plugin->name
&& !strcmp (core->io->desc->plugin->name, "gdb")) {
char cmd[64];
snprintf (cmd, sizeof (cmd), "retries %"PFMT64d, node->i_value);
r_io_system (core->io, cmd);
}
return true;
}
static int cb_dbg_execs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
@ -2410,6 +2429,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF ("dbg.exitkills", "true", "Kill process on exit");
SETPREF ("dbg.exe.path", NULL, "Path to binary being debugged");
SETICB ("dbg.gdb.page_size", 4096, &cb_dbg_gdb_page_size, "Page size on gdb target (useful for QEMU)");
SETICB ("dbg.gdb.retries", 10, &cb_dbg_gdb_retries, "Number of retries before gdb packet read times out");
SETCB ("dbg.consbreak", "false", &cb_consbreak, "SIGINT handle for attached processes");
r_config_set_getter (cfg, "dbg.swstep", (RConfigCallback)__dbg_swstep_getter);

View file

@ -217,24 +217,11 @@ static int __system(RIO *io, RIODesc *fd, const char *cmd) {
" =!inv.reg - invalidate reg cache\n"
" =!pktsz - get max packet size used\n"
" =!pktsz bytes - set max. packet size as 'bytes' bytes\n"
" =!page_size - get current setting for page size\n"
" =!page_size bytes - set page size for memory reads (useful for qemu)\n"
" =!exec_file [pid] - get file which was executed for"
" current/specified pid\n");
return true;
}
if (!strncmp (cmd, "page_size", 9)) {
int page_size;
if (isspace (cmd[9]) && isdigit (cmd[10])) {
if ((page_size = atoi (cmd + 10)) >= 64) { // 64 is hardcoded min packet size
desc->page_size = page_size;
}
return true;
}
io->cb_printf ("page size: %d bytes\n", desc->page_size);
return true;
}
if (!strncmp (cmd, "pktsz", 5)) {
if (r_str_startswith (cmd, "pktsz")) {
const char *ptr = r_str_chop_ro (cmd + 5);
if (!isdigit (*ptr)) {
io->cb_printf ("packet size: %u bytes\n",
@ -249,7 +236,7 @@ static int __system(RIO *io, RIODesc *fd, const char *cmd) {
desc->stub_features.pkt_sz = R_MAX (pktsz, 8); // min = 64
return true;
}
if (!strncmp (cmd, "detach", 6)) {
if (r_str_startswith (cmd, "detach")) {
int pid;
if (!isspace (cmd[6]) || !desc->stub_features.multiprocess) {
return gdbr_detach (desc) >= 0;
@ -260,7 +247,7 @@ static int __system(RIO *io, RIODesc *fd, const char *cmd) {
}
return gdbr_detach_pid (desc, pid) >= 0;
}
if (!strncmp (cmd, "pkt ", 4)) {
if (r_str_startswith (cmd, "pkt ")) {
if (send_msg (desc, cmd + 4) == -1) {
return false;
}
@ -272,14 +259,14 @@ static int __system(RIO *io, RIODesc *fd, const char *cmd) {
}
return r >= 0;
}
if (!strncmp (cmd, "pid", 3)) {
if (r_str_startswith (cmd, "pid")) {
int pid = desc ? desc->pid : -1;
if (!cmd[3]) {
io->cb_printf ("%d\n", pid);
}
return pid;
}
if (!strncmp (cmd, "monitor", 7)) {
if (r_str_startswith (cmd, "monitor")) {
const char *qrcmd = cmd + 8;
if (!isspace (cmd[7])) {
qrcmd = "help";
@ -290,7 +277,7 @@ static int __system(RIO *io, RIODesc *fd, const char *cmd) {
}
return true;
}
if (!strncmp (cmd, "inv.reg", 7)) {
if (r_str_startswith (cmd, "inv.reg")) {
gdbr_invalidate_reg_cache ();
return true;
}
@ -321,8 +308,30 @@ static int __system(RIO *io, RIODesc *fd, const char *cmd) {
free (file);
return true;
}
// This is internal, not available to user. Sets a flag that next call to
// get memmap will be for getting baddr
// These are internal, not available to user directly
if (r_str_startswith (cmd, "retries")) {
int num_retries;
if (isspace (cmd[7]) && isdigit (cmd[8])) {
if ((num_retries = atoi (cmd + 8)) >= 1) {
desc->num_retries = num_retries;
}
return true;
}
io->cb_printf ("num_retries: %d bytes\n", desc->page_size);
return true;
}
if (r_str_startswith (cmd, "page_size")) {
int page_size;
if (isspace (cmd[9]) && isdigit (cmd[10])) {
if ((page_size = atoi (cmd + 10)) >= 64) {
desc->page_size = page_size;
}
return true;
}
io->cb_printf ("page size: %d bytes\n", desc->page_size);
return true;
}
// Sets a flag that next call to get memmap will be for getting baddr
if (!strcmp (cmd, "baddr")) {
desc->get_baddr = true;
return true;

View file

@ -177,6 +177,7 @@ typedef struct libgdbr_t {
libgdbr_stub_features_t stub_features;
int remote_file_fd; // For remote file I/O
int num_retries; // number of retries for packet reading
int remote_type;
bool no_ack;

View file

@ -18,6 +18,7 @@ int gdbr_init(libgdbr_t *g, bool is_server) {
g->send_max = 2500;
g->send_buff = (char *) calloc (g->send_max, 1);
g->page_size = 4096;
g->num_retries = 10; // safe number, should be ~2.5 seconds
if (!g->send_buff) {
return -1;
}

View file

@ -141,7 +141,7 @@ static int unpack(libgdbr_t *g, struct parse_ctx *ctx, int len) {
int read_packet(libgdbr_t *g, bool vcont) {
struct parse_ctx ctx = { 0 };
int ret;
int ret, i;
if (!g) {
eprintf ("Initialize libgdbr_t first\n");
return -1;
@ -159,7 +159,7 @@ int read_packet(libgdbr_t *g, bool vcont) {
}
}
g->data_len = 0;
while (1) {
for (i = 0; i < g->num_retries; vcont ? 0 : i++) {
ret = r_socket_ready (g->sock, 0, READ_TIMEOUT);
if (ret == 0 && !vcont) {
continue;