Added reverse step and continue support to gdbr ##debug

This feature only works with server implementations that have ReverseStep
and ReverseContinue enabled, such as rr. The official gdbserver doesn't support it.
This commit is contained in:
yossizap 2020-01-14 22:46:07 +00:00 committed by radare
parent abb30be72a
commit f64f2211fb
2 changed files with 63 additions and 0 deletions

View File

@ -216,6 +216,9 @@ static char *__system(RIO *io, RIODesc *fd, const char *cmd) {
eprintf ("Usage: =!cmd args\n"
" =!pid - show targeted pid\n"
" =!pkt s - send packet 's'\n"
" =!rd - show reverse debugging availability\n"
" =!dsb - step backwards\n"
" =!dcb - continue backwards\n"
" =!monitor cmd - hex-encode monitor command and pass"
" to target interpreter\n"
" =!detach [pid] - detach from remote/detach specific pid\n"
@ -270,6 +273,62 @@ static char *__system(RIO *io, RIODesc *fd, const char *cmd) {
gdbr_lock_leave (desc);
return NULL;
}
if (r_str_startswith (cmd, "rd")) {
PJ *pj = pj_new ();
pj_o (pj);
pj_kb (pj, "reverse-continue", desc->stub_features.ReverseStep);
pj_kb (pj, "reverse-step", desc->stub_features.ReverseContinue);
pj_end (pj);
io->cb_printf ("%s\n", pj_string (pj));
pj_free (pj);
return NULL;
}
if (r_str_startswith (cmd, "dsb")) {
if (!desc->stub_features.ReverseStep) {
eprintf ("Stepping backwards is not supported in this gdbserver implementation\n");
return NULL;
}
gdbr_lock_enter (desc);
if (send_msg (desc, "bs") >= 0) {
(void)read_packet (desc);
desc->data[desc->data_len] = '\0';
if (!desc->no_ack) {
eprintf ("[waiting for ack]\n");
} else {
handle_stop_reason (desc);
if (desc->stop_reason.is_valid == false) {
eprintf("Thread (%d) stopped for an invalid reason: %d\n",
desc->stop_reason.thread, desc->stop_reason.reason);
}
}
gdbr_invalidate_reg_cache ();
}
gdbr_lock_leave (desc);
return NULL;
}
if (r_str_startswith (cmd, "dcb")) {
if (!desc->stub_features.ReverseContinue) {
eprintf ("Continue backwards is not supported in this gdbserver implementation\n");
return NULL;
}
gdbr_lock_enter (desc);
if (send_msg (desc, "bc") >= 0) {
(void)read_packet (desc);
desc->data[desc->data_len] = '\0';
if (!desc->no_ack) {
eprintf ("[waiting for ack]\n");
} else {
handle_stop_reason (desc);
if (desc->stop_reason.is_valid == false) {
eprintf("Thread (%d) stopped for an invalid reason: %d\n",
desc->stop_reason.thread, desc->stop_reason.reason);
}
}
gdbr_invalidate_reg_cache ();
}
gdbr_lock_leave (desc);
return NULL;
}
if (r_str_startswith (cmd, "pid")) {
int pid = desc ? desc->pid : -1;
if (!cmd[3]) {

View File

@ -113,6 +113,10 @@ int handle_qSupported(libgdbr_t *g) {
} else if (r_str_startswith (tok, "qEcho")) {
g->remote_type = GDB_REMOTE_TYPE_LLDB;
g->stub_features.lldb.qEcho = (tok[strlen ("qEcho")] == '+');
} else if (r_str_startswith (tok, "ReverseStep")) {
g->stub_features.ReverseStep = (tok[strlen ("ReverseStep")] == '+');
} else if (r_str_startswith (tok, "ReverseContinue")) {
g->stub_features.ReverseContinue = (tok[strlen ("ReverseContinue")] == '+');
}
// TODO
tok = strtok (NULL, ";");