Skip to content

Commit

Permalink
Added support to thread switching in linux and fix r_debug_select ##d…
Browse files Browse the repository at this point in the history
…ebug
  • Loading branch information
yossizap authored and radare committed Oct 17, 2019
1 parent 8212297 commit d9fa409
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
13 changes: 12 additions & 1 deletion libr/debug/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,8 @@ R_API int r_debug_detach(RDebug *dbg, int pid) {
}

R_API bool r_debug_select(RDebug *dbg, int pid, int tid) {
ut64 pc = 0;

if (pid < 0) {
return false;
}
Expand Down Expand Up @@ -610,7 +612,16 @@ R_API bool r_debug_select(RDebug *dbg, int pid, int tid) {
dbg->pid = pid;
dbg->tid = tid;

r_debug_reg_sync (dbg, R_REG_TYPE_GPR, false);
// Synchronize with the current thread's data
if (dbg->corebind.core) {
RCore *core = (RCore *)dbg->corebind.core;

r_reg_arena_swap (core->dbg->reg, true);
r_debug_reg_sync (dbg, R_REG_TYPE_ALL, false);

pc = r_debug_reg_get (dbg, "PC");
core->offset = pc;
}

return true;
}
Expand Down
8 changes: 5 additions & 3 deletions libr/debug/p/debug_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,13 @@ static int r_debug_native_detach (RDebug *dbg, int pid) {
#endif
}

static int r_debug_native_select(RDebug *dbg, int pid, int tid) {
#if __WINDOWS__
static int r_debug_native_select (RDebug *dbg, int pid, int tid) {
return w32_select (dbg, pid, tid);
}
#elif __linux__
return linux_select_thread (dbg, pid, tid);
#endif
}

static int r_debug_native_continue_syscall (RDebug *dbg, int pid, int num) {
// XXX: num is ignored
Expand Down Expand Up @@ -2112,7 +2114,7 @@ RDebugPlugin r_debug_plugin_native = {
.attach = &r_debug_native_attach,
.detach = &r_debug_native_detach,
// TODO: add native select for other platforms?
#if __WINDOWS__
#if __WINDOWS__ || __linux__
.select = &r_debug_native_select,
#endif
.pids = &r_debug_native_pids,
Expand Down
32 changes: 20 additions & 12 deletions libr/debug/p/native/linux/linux_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ static void linux_add_and_attach_new_thread (RDebug *dbg, int tid);
static int linux_stop_process(int pid);

int linux_handle_signals (RDebug *dbg) {
int pid = dbg->tid;
siginfo_t siginfo = { 0 };
int ret = r_debug_ptrace (dbg, PTRACE_GETSIGINFO, dbg->pid, 0, (r_ptrace_data_t)(size_t)&siginfo);
int ret = r_debug_ptrace (dbg, PTRACE_GETSIGINFO, pid, 0, (r_ptrace_data_t)(size_t)&siginfo);
if (ret == -1) {
/* ESRCH means the process already went away :-/ */
if (errno == ESRCH) {
Expand Down Expand Up @@ -212,8 +213,9 @@ RDebugReasonType linux_ptrace_event (RDebug *dbg, int pid, int status) {

int linux_step(RDebug *dbg) {
int ret = false;
int pid = dbg->tid;
ut64 addr = r_debug_reg_get (dbg, "PC");
ret = r_debug_ptrace (dbg, PTRACE_SINGLESTEP, dbg->pid, (void*)(size_t)addr, 0);
ret = r_debug_ptrace (dbg, PTRACE_SINGLESTEP, pid, (void*)(size_t)addr, 0);
//XXX(jjd): why?? //linux_handle_signals (dbg);
if (ret == -1) {
perror ("native-singlestep");
Expand Down Expand Up @@ -284,6 +286,10 @@ static void linux_remove_thread (RDebug *dbg, int pid) {
}
}

bool linux_select_thread(RDebug *dbg, int pid, int tid) {
return linux_attach (dbg, tid);
}

void linux_attach_new_process (RDebug *dbg) {
linux_detach_all (dbg);

Expand All @@ -301,7 +307,7 @@ void linux_attach_new_process (RDebug *dbg) {

RDebugReasonType linux_dbg_wait(RDebug *dbg, int my_pid) {
RDebugReasonType reason = R_DEBUG_REASON_UNKNOWN;
int pid = (dbg->continue_all_threads && dbg->n_threads) ? -1 : dbg->main_pid;
int pid = dbg->tid;
int status, flags = __WALL;

if (pid == -1) {
Expand Down Expand Up @@ -410,7 +416,7 @@ static int linux_stop_process(int pid) {
}

static bool linux_attach_single_pid(RDebug *dbg, int ptid) {
siginfo_t sig = {0};
siginfo_t sig = { 0 };
// Safely check if the PID has already been attached to avoid printing errors.
// Attaching to a process that has already been started with PTRACE_TRACEME.
// sets errno to "Operation not permitted" which may be misleading.
Expand All @@ -422,10 +428,10 @@ static bool linux_attach_single_pid(RDebug *dbg, int ptid) {
perror ("ptrace (PT_ATTACH)");
return false;
}
}

if (!linux_set_options (dbg, ptid)) {
return false;
if (!linux_set_options (dbg, ptid)) {
return false;
}
}

return true;
Expand Down Expand Up @@ -778,7 +784,7 @@ void print_fpu (void *f){

int linux_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
bool showfpu = false;
int pid = dbg->pid;
int pid = dbg->tid;
int ret;
if (type < -1) {
showfpu = true;
Expand Down Expand Up @@ -910,6 +916,8 @@ int linux_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
}

int linux_reg_write (RDebug *dbg, int type, const ut8 *buf, int size) {
int pid = dbg->tid;

if (type == R_REG_TYPE_DRX) {
#if !__ANDROID__ && (__i386__ || __x86_64__)
int i;
Expand All @@ -918,7 +926,7 @@ int linux_reg_write (RDebug *dbg, int type, const ut8 *buf, int size) {
if (i == 4 || i == 5) {
continue;
}
if (r_debug_ptrace (dbg, PTRACE_POKEUSER, dbg->pid,
if (r_debug_ptrace (dbg, PTRACE_POKEUSER, pid,
(void *)r_offsetof (struct user, u_debugreg[i]), (r_ptrace_data_t)val[i])) {
eprintf ("ptrace error for dr %d\n", i);
r_sys_perror ("ptrace POKEUSER");
Expand All @@ -935,11 +943,11 @@ int linux_reg_write (RDebug *dbg, int type, const ut8 *buf, int size) {
.iov_base = (void*)buf,
.iov_len = sizeof (R_DEBUG_REG_T)
};
int ret = r_debug_ptrace (dbg, PTRACE_SETREGSET, dbg->pid, (void*)(size_t)NT_PRSTATUS, (r_ptrace_data_t)(size_t)&io);
int ret = r_debug_ptrace (dbg, PTRACE_SETREGSET, pid, (void*)(size_t)NT_PRSTATUS, (r_ptrace_data_t)(size_t)&io);
#elif __POWERPC__ || __sparc__
int ret = r_debug_ptrace (dbg, PTRACE_SETREGS, dbg->pid, buf, NULL);
int ret = r_debug_ptrace (dbg, PTRACE_SETREGS, pid, buf, NULL);
#else
int ret = r_debug_ptrace (dbg, PTRACE_SETREGS, dbg->pid, 0, (void*)buf);
int ret = r_debug_ptrace (dbg, PTRACE_SETREGS, pid, 0, (void*)buf);
#endif
#if DEAD_CODE
if (size > sizeof (R_DEBUG_REG_T)) {
Expand Down
1 change: 1 addition & 0 deletions libr/debug/p/native/linux/linux_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ RDebugReasonType linux_ptrace_event (RDebug *dbg, int pid, int status);
int linux_attach (RDebug *dbg, int pid);
RDebugInfo *linux_info (RDebug *dbg, const char *arg);
RList *linux_thread_list (int pid, RList *list);
bool linux_select_thread (RDebug *dbg, int pid, int tid);
RDebugPid *fill_pid_info (const char *info, const char *path, int tid);
int linux_reg_read (RDebug *dbg, int type, ut8 *buf, int size);
int linux_reg_write (RDebug *dbg, int type, const ut8 *buf, int size);
Expand Down

0 comments on commit d9fa409

Please sign in to comment.