* Step now accepts pid+tid

* Fix attach in w32 debugger
  - use dpa and get first thread by default
* Mark with asterisks the selected pid/thread (dp/dpt)
* Fix reg_write in w32
This commit is contained in:
pancake 2010-11-17 02:31:56 +01:00
parent 8df7b217eb
commit 0aafe05b45
7 changed files with 91 additions and 85 deletions

View File

@ -192,6 +192,7 @@ int main(int argc, char **argv) {
if (debug) {
r_core_cmd (&r, "e io.ffio=true", 0);
r_core_cmd (&r, "dh native", 0);
r_core_cmdf (&r, "dpa %d", r.file->fd);
r_core_cmdf (&r, "dp=%d", r.file->fd);
r_core_cmd (&r, ".dr*", 0);
r_core_cmd (&r, "sr pc", 0);

View File

@ -3766,12 +3766,10 @@ static void cmd_debug_pid(RCore *core, const char *input) {
case 'a':
r_debug_attach (core->dbg,
(int) r_num_math (core->num, input+2));
r_debug_select (core->dbg,
(int) r_num_math (core->num, input+2),
(int) r_num_math (core->num, input+2));
r_debug_select (core->dbg, core->dbg->pid, core->dbg->tid);
break;
case 'f':
r_debug_select (core->dbg, core->file->fd, core->file->fd);
r_debug_select (core->dbg, core->file->fd, core->dbg->tid);
break;
case '=':
r_debug_select (core->dbg,
@ -3921,11 +3919,13 @@ static int cmd_debug(void *data, const char *input) {
if (ptr) {
bypassbp (core);
int old_pid = core->dbg->pid;
int old_tid = core->dbg->tid;
int pid = atoi (ptr+1);
int tid = pid; // XXX
*ptr = 0;
r_debug_select (core->dbg, pid, pid);
r_debug_select (core->dbg, pid, tid);
r_debug_continue_kill (core->dbg, atoi (input+2));
r_debug_select (core->dbg, old_pid, old_pid);
r_debug_select (core->dbg, old_pid, old_tid);
} else r_debug_continue_kill (core->dbg, atoi (input+2));
checkbpcallback (core);
break;
@ -3955,9 +3955,9 @@ static int cmd_debug(void *data, const char *input) {
int pid = atoi (input+2);
bypassbp (core);
r_reg_arena_swap (core->dbg->reg, R_TRUE);
r_debug_select (core->dbg, pid, pid);
r_debug_select (core->dbg, pid, core->dbg->tid);
r_debug_continue (core->dbg);
r_debug_select (core->dbg, old_pid, old_pid);
r_debug_select (core->dbg, old_pid, core->dbg->tid);
checkbpcallback (core);
}
break;

View File

@ -63,13 +63,15 @@ R_API int r_debug_attach(struct r_debug_t *dbg, int pid) {
int ret = R_FALSE;
if (dbg && dbg->h && dbg->h->attach) {
ret = dbg->h->attach (pid);
if (ret) {
if (ret != -1) {
eprintf ("pid = %d tid = %d\n", pid, ret);
// TODO: get arch and set io pid
//int arch = dbg->h->arch;
//r_reg_set(dbg->reg->nregs, arch); //R_DBG_ARCH_X86);
// dbg->bp->iob->system("pid %d", pid);
dbg->pid = pid;
dbg->tid = pid;
//dbg->pid = pid;
//dbg->tid = ret;
r_debug_select (dbg, pid, ret); //dbg->pid, dbg->tid);
} else eprintf ("Cannot attach to this pid\n");
} else eprintf ("dbg->attach = NULL\n");
return ret;
@ -198,7 +200,7 @@ R_API int r_debug_step_soft(RDebug *dbg) {
}
R_API int r_debug_step_hard(RDebug *dbg) {
if (!dbg->h->step (dbg, dbg->pid))
if (!dbg->h->step (dbg))
return R_FALSE;
return r_debug_wait (dbg);
}
@ -245,7 +247,7 @@ R_API int r_debug_continue_kill(RDebug *dbg, int sig) {
int ret = R_FALSE;
if (dbg && dbg->h && dbg->h->cont) {
r_bp_restore (dbg->bp, R_FALSE); // set sw breakpoints
ret = dbg->h->cont (dbg->pid, sig);
ret = dbg->h->cont (dbg->pid, dbg->tid, sig);
if (dbg->h->wait)
ret = dbg->h->wait (dbg->pid);
r_bp_restore (dbg->bp, R_TRUE); // unset sw breakpoints

View File

@ -7,7 +7,7 @@
#include <r_lib.h>
#include <signal.h>
static int r_debug_native_continue(int pid, int sig);
static int r_debug_native_continue(int pid, int tid, int sig);
static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size);
static int r_debug_native_reg_write(int pid, int tid, int type, const ut8* buf, int size);
@ -148,21 +148,18 @@ static inline void debug_arch_x86_trap_set(RDebug *dbg, int foo) {
}
#endif // __APPLE__
static int r_debug_native_step(RDebug *dbg, int pid) {
static int r_debug_native_step(RDebug *dbg) {
int ret = R_FALSE;
int pid = dbg->pid;
#if __WINDOWS__
CONTEXT regs;
//R_DEBUG_REG_T regs;
regs.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
// GetTheadContext (tid2hnd
// XXX TODO CONTINUE h
/* up TRAP flag */
CONTEXT regs __attribute__((aligned (16)));
/* set TRAP flag */
/*
r_debug_native_reg_read (dbg, R_REG_TYPE_GPR, &regs, sizeof (regs));
regs.EFlags |= 0x100;
r_debug_native_reg_write (dbg->pid, dbg->tid, R_REG_TYPE_GPR, &regs, sizeof (regs));
//single_step = pid;
r_debug_native_continue (pid, -1);
r_debug_native_reg_write (pid, dbg->tid, R_REG_TYPE_GPR, &regs, sizeof (regs));
*/
r_debug_native_continue (pid, dbg->tid, -1);
#elif __APPLE__
debug_arch_x86_trap_set (dbg, 1);
// TODO: not supported in all platforms. need dbg.swstep=
@ -193,21 +190,25 @@ static int r_debug_native_step(RDebug *dbg, int pid) {
return ret;
}
// return thread id
static int r_debug_native_attach(int pid) {
int ret = -1;
#if __WINDOWS__
HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess != (HANDLE)NULL && DebugActiveProcess (pid)) {
w32_dbg_threads (pid);
ret = 0;
ret = w32_first_thread (pid);
} else ret = -1;
ret = w32_first_thread (pid);
#elif __APPLE__
ret = ptrace (PT_ATTACH, pid, 0, 0);
if (ret!=-1)
ret = pid;
#else
ret = ptrace (PTRACE_ATTACH, pid, 0, 0);
eprintf ("attach=%d\n", ret);
if (ret!=-1)
ret = pid;
#endif
return (ret != -1)?R_TRUE:R_FALSE;
return ret;
}
static int r_debug_native_detach(int pid) {
@ -234,12 +235,13 @@ static int r_debug_native_continue_syscall(int pid, int num) {
/* TODO: specify thread? */
/* TODO: must return true/false */
static int r_debug_native_continue(int pid, int sig) {
static int r_debug_native_continue(int pid, int tid, int sig) {
void *data = NULL;
if (sig != -1)
data = (void*)(size_t)sig;
#if __WINDOWS__
if (ContinueDebugEvent (pid, pid, DBG_CONTINUE) == 0) {
if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
print_lasterr ((char *)__FUNCTION__);
eprintf ("debug_contp: error\n");
return -1;
}
@ -940,9 +942,11 @@ static int r_debug_native_reg_write(int pid, int tid, int type, const ut8* buf,
} else
if (type == R_REG_TYPE_GPR) {
#if __WINDOWS__
CONTEXT ctx;
CONTEXT ctx __attribute__((aligned(16)));
memcpy (&ctx, buf, sizeof (CONTEXT));
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
return SetThreadContext (tid2handler (pid, tid), &ctx)? 0: -1;
// eprintf ("EFLAGS =%x\n", ctx.EFlags);
return SetThreadContext (tid2handler (pid, tid), &ctx)? R_TRUE: R_FALSE;
#elif __linux__ || __sun || __NetBSD__ || __FreeBSD__ || __OpenBSD__
int ret = ptrace (PTRACE_SETREGS, pid, 0, buf);
if (sizeof (R_DEBUG_REG_T) < size)

View File

@ -113,7 +113,7 @@ static void print_lasterr(const char *str) {
0, // ignored
0, // ignored
(LPTSTR)&buffer,
size,
size-1,
(va_list*)pArgs)) {
eprintf ("(%s): Format message failed with 0x%x\n",
r_str_get (str), GetLastError());
@ -194,47 +194,43 @@ static inline int w32_h2p(HANDLE h) {
}
// TODO: not yet used !!!
static int w32_dbg_threads(int pid) {
#if 0
HANDLE th;
THREADENTRY32 te32;
TH_INFO *th_i;
int ret = -1;
te32.dwSize = sizeof (THREADENTRY32);
static int w32_first_thread(int pid) {
HANDLE th;
HANDLE thid;
THREADENTRY32 te32;
int ret = -1;
th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, ps.pid);
if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32))
goto err_load_th;
te32.dwSize = sizeof(THREADENTRY32);
//free_th ();
do {
/* get all threads of process */
if (te32.th32OwnerProcessID == pid) {
const char *path = "unk";
RDebugPid *pid = r_debug_pid_new (
path, te32.th32ThreadID, 's', 0); // TODO: add pc
eprintf ("THREAD: id=0x%08x flags=0x%08x\n",
te32.th32ThreadID, te32.dwFlags);
eprintf ("HANDLER: 0x%p\n", w32_openthread (
THREAD_ALL_ACCESS, 0, te32.th32ThreadID));
/* open a new handler */
//th_i->ht = w32_openthread(THREAD_ALL_ACCESS, 0,
// te32.th32ThreadID);
ret = te32.th32ThreadID;
//r_list_append (list, thread);
}
} while (Thread32Next (th, &te32));
err_load_th:
if (ret == -1)
if (w32_openthread == NULL) {
eprintf("w32_thread_list: no w32_openthread?\n");
return -1;
//print_lasterr((char *)__FUNCTION__);
if (th != INVALID_HANDLE_VALUE)
ClosePlugin (th);
return ret;
#endif
return 0;
}
th = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid);
if (th == INVALID_HANDLE_VALUE) {
eprintf ("w32_thread_list: invalid handle\n");
return -1;
}
if (!Thread32First (th, &te32)) {
CloseHandle (th);
eprintf ("w32_thread_list: no thread first\n");
return -1;
}
do {
/* get all threads of process */
if (te32.th32OwnerProcessID == pid) {
thid = w32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
if (thid == NULL)
goto err_load_th;
CloseHandle (th);
return te32.th32ThreadID;
}
} while (Thread32Next (th, &te32));
err_load_th:
if (ret == -1)
print_lasterr ((char *)__FUNCTION__);
eprintf ("w32thread: Oops\n");
return pid; // -1 ?
}
static int debug_exception_event (unsigned long code) {
@ -290,7 +286,7 @@ static int w32_dbg_wait(int pid) {
pid, w32_h2t (de.u.CreateProcessInfo.
hProcess),
de.u.CreateProcessInfo.lpStartAddress);
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
next_event = 1;
ret = R_DBG_REASON_NEW_PID;
break;
@ -303,45 +299,44 @@ static int w32_dbg_wait(int pid) {
case CREATE_THREAD_DEBUG_EVENT:
eprintf ("(%d) created thread (0x%x)\n",
pid, de.u.CreateThread.lpStartAddress);
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
ret = R_DBG_REASON_NEW_TID;
next_event = 1;
break;
case EXIT_THREAD_DEBUG_EVENT:
eprintf("EXIT_THREAD\n");
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
next_event = 1;
ret = R_DBG_REASON_EXIT_TID;
break;
case LOAD_DLL_DEBUG_EVENT:
eprintf("(%d) Loading %s library at 0x%x\n",
pid, "", de.u.LoadDll.lpBaseOfDll);
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
next_event = 1;
ret = R_DBG_REASON_NEW_LIB;
break;
case UNLOAD_DLL_DEBUG_EVENT:
eprintf ("UNLOAD_DLL\n");
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
next_event = 1;
ret = R_DBG_REASON_EXIT_LIB;
break;
case OUTPUT_DEBUG_STRING_EVENT:
eprintf("OUTPUT_DBUG_STING\n");
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
next_event = 1;
break;
case RIP_EVENT:
eprintf("RIP_EVENT\n");
r_debug_native_continue (pid, -1);
r_debug_native_continue (pid, tid, -1);
next_event = 1;
// XXX unknown ret = R_DBG_REASON_TRAP;
break;
case EXCEPTION_DEBUG_EVENT:
next_event = debug_exception_event (
de.u.Exception.ExceptionRecord.ExceptionCode);
ret = R_DBG_REASON_TRAP;
break;
return R_DBG_REASON_TRAP;
default:
eprintf ("Unknown event: %d\n", code);
return -1;

View File

@ -28,7 +28,9 @@ R_API int r_debug_pid_list(struct r_debug_t *dbg, int pid) {
iter = r_list_iterator (list);
while (r_list_iter_next (iter)) {
RDebugPid *p = r_list_iter_get (iter);
eprintf (" %d %c %s\n", p->pid, p->status, p->path);
eprintf (" %c %d %c %s\n",
dbg->pid==p->pid?'*':'-',
p->pid, p->status, p->path);
}
r_list_free (list);
}
@ -45,7 +47,9 @@ R_API int r_debug_thread_list(struct r_debug_t *dbg, int pid) {
iter = r_list_iterator (list);
while (r_list_iter_next (iter)) {
RDebugPid *p = r_list_iter_get (iter);
eprintf (" %d %c %s\n", p->pid, p->status, p->path);
eprintf (" %c %d %c %s\n",
dbg->tid==p->pid?'*':'-',
p->pid, p->status, p->path);
}
r_list_free (list);
}

View File

@ -135,8 +135,8 @@ typedef struct r_debug_plugin_t {
RList *(*pids)(int pid);
RFList (*backtrace)(int count);
/* flow */
int (*step)(RDebug *dbg, int pid); // if step() is NULL; reimplement it with traps
int (*cont)(int pid, int sig);
int (*step)(RDebug *dbg);
int (*cont)(int pid, int tid, int sig);
int (*wait)(int pid);
int (*kill)(RDebug *dbg, boolt thread, int sig);
int (*contsc)(int pid, int sc);