From 8b0afcbc39e41bef2e4cbe1a29ef62269f6960e0 Mon Sep 17 00:00:00 2001 From: leberus Date: Wed, 28 Dec 2016 16:02:05 +0100 Subject: [PATCH] Fix: #4856 #4857 (#6365) --- libr/core/cmd_debug.c | 20 ++++++++++++++++++++ libr/debug/p/debug_native.c | 12 +++++++++--- libr/debug/p/native/linux/linux_debug.c | 20 +++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/libr/core/cmd_debug.c b/libr/core/cmd_debug.c index 2ac29d5c55..c037412db3 100644 --- a/libr/core/cmd_debug.c +++ b/libr/core/cmd_debug.c @@ -2948,7 +2948,27 @@ static int cmd_debug_continue (RCore *core, const char *input) { switch (input[1]) { case 0: // "dc" r_reg_arena_swap (core->dbg->reg, true); +#if __linux__ + old_pid = core->dbg->pid; r_debug_continue (core->dbg); + RList *list = core->dbg->h + ? core->dbg->h->threads (core->dbg, core->dbg->pid) + : NULL; + if (list) { + RDebugPid *th; + RListIter *it; + r_list_foreach (list, it, th) { + if (th->pid && th->pid != old_pid) { + r_debug_select (core->dbg, th->pid, + core->dbg->tid); + r_debug_continue (core->dbg); + } + } + } + r_debug_select (core->dbg, old_pid, core->dbg->tid); +#else + r_debug_continue (core->dbg); +#endif break; case 'a': // "dca" eprintf ("TODO: dca\n"); diff --git a/libr/debug/p/debug_native.c b/libr/debug/p/debug_native.c index 5ea0a56d65..d5d1a17a4d 100755 --- a/libr/debug/p/debug_native.c +++ b/libr/debug/p/debug_native.c @@ -359,7 +359,7 @@ static RDebugReasonType r_debug_native_wait (RDebug *dbg, int pid) { int ret = waitpid (-1, &status, WAITPID_FLAGS); #else //eprintf ("waiting on pid %d ...\n", pid); - int ret = waitpid (pid, &status, WAITPID_FLAGS); + int ret = waitpid (pid, &status, WAITPID_FLAGS|WNOHANG); #endif // WAIT_ON_ALL_CHILDREN if (ret == -1) { r_sys_perror ("waitpid"); @@ -395,12 +395,18 @@ static RDebugReasonType r_debug_native_wait (RDebug *dbg, int pid) { eprintf ("child received signal %d\n", WTERMSIG (status)); reason = R_DEBUG_REASON_SIGNAL; } else if (WIFSTOPPED (status)) { - if (WSTOPSIG (status) != SIGTRAP) { + if (WSTOPSIG (status) != SIGTRAP && + WSTOPSIG (status) != SIGSTOP) { eprintf ("child stopped with signal %d\n", WSTOPSIG (status)); } /* this one might be good enough... */ dbg->reason.signum = WSTOPSIG (status); + if (dbg->reason.signum == SIGSTOP) { + eprintf ("delivery\n"); + reason = R_DEBUG_REASON_NONE; + goto delivery; + } /* the ptrace documentation says GETSIGINFO is only necessary for * differentiating the various stops. @@ -438,7 +444,7 @@ static RDebugReasonType r_debug_native_wait (RDebug *dbg, int pid) { } #endif // __APPLE__ #endif // __WINDOWS__ && !__CYGWIN__ - +delivery: dbg->reason.tid = pid; dbg->reason.type = reason; return reason; diff --git a/libr/debug/p/native/linux/linux_debug.c b/libr/debug/p/native/linux/linux_debug.c index 796b239c8f..be575f0e78 100644 --- a/libr/debug/p/native/linux/linux_debug.c +++ b/libr/debug/p/native/linux/linux_debug.c @@ -195,10 +195,28 @@ bool linux_set_options (RDebug *dbg, int pid) { int linux_attach (RDebug *dbg, int pid) { linux_set_options (dbg, pid); - int ret = ptrace (PTRACE_ATTACH, pid, 0, 0); + int ret = ptrace (PTRACE_ATTACH, pid, NULL, NULL); if (ret != -1) { perror ("ptrace (PT_ATTACH)"); } + + if (dbg->h) { + RList *list = r_list_new (); + if (list) { + list = linux_thread_list (pid, list); + RDebugPid *th; + RListIter *it; + r_list_foreach (list, it, th) { + if (th->pid && th->pid != pid) { + eprintf ("Attaching to pid: %d\n", th->pid); + int ret = ptrace (PTRACE_ATTACH, th->pid, NULL, NULL); + if (ret != -1) { + perror ("ptrace (PT_ATTACH)"); + } + } + } + } + } return pid; }