/branches/tracing/kernel/generic/include/udebug.h |
---|
7,10 → 7,83 |
#ifndef KERN_UDEBUG_H_ |
#define KERN_UDEBUG_H_ |
typedef enum { /* udebug_method_t */ |
/** Start debugging the recipient. |
* Causes all threads in the receiving task to stop. When they |
* are all stoped, an answer with retval 0 is generated. |
*/ |
UDEBUG_M_BEGIN = 1, |
/** Finish debugging the recipient. |
* Answers all pending GO and GUARD messages. |
*/ |
UDEBUG_M_END, |
/** Make sure the debugged task is still there. |
* This message is answered when the debugged task dies |
* or the debugging session ends. |
*/ |
UDEBUG_M_GUARD, |
/** Run a thread until a debugging event occurs. |
* This message is answered when the thread stops |
* in a debugging event. |
* |
* - ARG2 - id of the thread to run |
*/ |
UDEBUG_M_GO, |
/** Stop a thread being debugged. |
* Creates a special STOP event in the thread, causing |
* it to answer a pending GO message (if any). |
*/ |
UDEBUG_M_STOP, |
/** Read arguments of a syscall. |
* |
* - ARG2 - thread identification |
* - ARG3 - destination address in the caller's address space |
* - ARG4 - size of receiving buffer in bytes |
* |
* on answer, the kernel will set: |
* |
* - ARG1 - actual size in bytes of data read |
*/ |
UDEBUG_M_ARGS_READ, |
/** Read the list of the debugged tasks's threads. |
* |
* - ARG2 - destination address in the caller's address space |
* - ARG3 - size of receiving buffer in bytes |
* |
* The kernel fills the buffer with a series of sysarg_t values |
* (thread ids). On answer, the kernel will set: |
* |
* - ARG1 - number of bytes that were actually copied |
* - ARG2 - number of bytes of the complete data |
* |
*/ |
UDEBUG_M_THREAD_READ, |
/** Read the list of the debugged tasks's memory. |
* |
* - ARG2 - destination address in the caller's address space |
* - ARG3 - source address in the recipient's address space |
* - ARG4 - size of receiving buffer in bytes |
* |
*/ |
UDEBUG_M_MEM_READ |
} udebug_method_t; |
typedef enum { |
UDEBUG_EVENT_SYSCALL |
} udebug_event_t; |
#ifdef KERNEL |
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc); |
void udebug_stoppable_begin(void); |
18,5 → 91,7 |
#endif |
#endif |
/** @} |
*/ |
/branches/tracing/kernel/generic/include/ipc/ipc.h |
---|
195,72 → 195,12 |
*/ |
#define IPC_M_DATA_READ 7 |
/** Start debugging the recipient. |
* Causes all threads in the receiving task to stop. When they |
* are all stoped, an answer with retval 0 is generated. |
/** Debug the recipient. |
* - ARG1 - specifies the debug method (from udebug_method_t) |
* - other arguments are specific to the debug method |
*/ |
#define IPC_M_DEBUG_BEGIN 8 |
#define IPC_M_DEBUG_ALL 8 |
/** Finish debugging the recipient. |
* Answers all pending GO and GUARD messages. |
*/ |
#define IPC_M_DEBUG_END 9 |
/** Make sure the debugged task is still there. |
* This message is answered when the debugged task dies |
* or the debugging session ends. |
*/ |
#define IPC_M_DEBUG_GUARD 10 |
/** Run a thread until a debugging event occurs. |
* This message is answered when the thread stops |
* in a debugging event. |
* |
* - ARG1 - id of the thread to run |
*/ |
#define IPC_M_DEBUG_GO 11 |
/** Stop a thread being debugged. |
* Creates a special STOP event in the thread, causing |
* it to answer a pending GO message (if any). |
*/ |
#define IPC_M_DEBUG_STOP 12 |
/** Read arguments of a syscall. |
* |
* - ARG1 - thread identification |
* - ARG2 - destination address in the caller's address space |
* - ARG3 - size of receiving buffer in bytes |
* |
* on answer, the kernel will set: |
* |
* - ARG1 - actual size in bytes of data read |
*/ |
#define IPC_M_DEBUG_ARGS_READ 12 |
/** Read the list of the debugged tasks's threads. |
* |
* - ARG1 - destination address in the caller's address space |
* - ARG2 - size of receiving buffer in bytes |
* |
* The kernel fills the buffer with a series of sysarg_t values |
* (thread ids). On answer, the kernel will set: |
* |
* - ARG1 - number of bytes that were actually copied |
* - ARG2 - number of bytes of the complete data |
* |
*/ |
#define IPC_M_DEBUG_THREAD_READ 13 |
/** Read the list of the debugged tasks's memory. |
* |
* - ARG1 - destination address in the caller's address space |
* - ARG2 - source address in the recipient's address space |
* - ARG3 - size of receiving buffer in bytes |
* |
*/ |
#define IPC_M_DEBUG_MEM_READ 14 |
/* Well-known methods */ |
#define IPC_M_LAST_SYSTEM 511 |
#define IPC_M_PING 512 |
/branches/tracing/kernel/generic/src/ipc/sysipc.c |
---|
362,7 → 362,7 |
ta = get_lock_callee_task(phone); |
ta->debug_go_call = call; |
t = get_task_thread_by_id(ta, IPC_GET_ARG1(call->data)); |
t = get_task_thread_by_id(ta, IPC_GET_ARG2(call->data)); |
if (t == NULL) { |
spinlock_unlock(&ta->lock); |
return ENOENT; |
389,14 → 389,14 |
ta = get_lock_callee_task(phone); |
klog_printf("task %llu", ta->taskid); |
t = get_task_thread_by_id(ta, IPC_GET_ARG1(call->data)); |
t = get_task_thread_by_id(ta, IPC_GET_ARG2(call->data)); |
if (t == NULL) { |
spinlock_unlock(&ta->lock); |
return ENOENT; |
} |
uspace_buffer = (void *)IPC_GET_ARG2(call->data); |
to_copy = IPC_GET_ARG3(call->data); |
uspace_buffer = (void *)IPC_GET_ARG3(call->data); |
to_copy = IPC_GET_ARG4(call->data); |
if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t); |
rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy); |
432,8 → 432,8 |
ta = get_lock_callee_task(phone); |
klog_printf("task %llu", ta->taskid); |
uspace_buffer = (void *)IPC_GET_ARG1(call->data); |
buf_size = IPC_GET_ARG2(call->data); |
uspace_buffer = (void *)IPC_GET_ARG2(call->data); |
buf_size = IPC_GET_ARG3(call->data); |
copied = total = 0; |
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
473,7 → 473,32 |
return 1; /* actually need becksend with retval 0 */ |
} |
#include <udebug.h> |
static int debug_request_preprocess(call_t *call, phone_t *phone) |
{ |
int rc; |
switch (IPC_GET_ARG1(call->data)) { |
case UDEBUG_M_BEGIN: |
rc = debug_begin(call, phone); |
return rc; |
case UDEBUG_M_GO: |
rc = debug_go(call, phone); |
return rc; |
case UDEBUG_M_ARGS_READ: |
rc = debug_args_read(call, phone); |
return rc; |
case UDEBUG_M_THREAD_READ: |
rc = debug_thread_read(call, phone); |
return rc; |
default: |
break; |
} |
return 0; |
} |
/** Called before the request is sent. |
* |
* @param call Call structure with the request. |
523,19 → 548,10 |
return rc; |
} |
break; |
case IPC_M_DEBUG_BEGIN: |
case IPC_M_DEBUG_ALL: |
/* actually need possibility of backsend with 0 result code */ |
rc = debug_begin(call, phone); |
rc = debug_request_preprocess(call, phone); |
return rc; |
case IPC_M_DEBUG_GO: |
rc = debug_go(call, phone); |
return rc; |
case IPC_M_DEBUG_ARGS_READ: |
rc = debug_args_read(call, phone); |
return rc; |
case IPC_M_DEBUG_THREAD_READ: |
rc = debug_thread_read(call, phone); |
return rc; |
default: |
break; |
} |
565,7 → 581,7 |
if (call->buffer) { |
/* This must be an affirmative answer to IPC_M_DATA_READ. */ |
/* or IPC_M_DEBUG_MEM_READ... */ |
/* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */ |
uintptr_t dst = IPC_GET_ARG1(call->data); |
size_t size = IPC_GET_ARG2(call->data); |
int rc = copy_to_uspace((void *) dst, call->buffer, size); |
598,11 → 614,7 |
IPC_SET_ARG5(call->data, phoneid); |
} |
switch (IPC_GET_METHOD(call->data)) { |
case IPC_M_DEBUG_BEGIN: |
case IPC_M_DEBUG_END: |
case IPC_M_DEBUG_GO: |
case IPC_M_DEBUG_STOP: |
case IPC_M_DEBUG_GUARD: |
case IPC_M_DEBUG_ALL: |
return -1; |
default: |
break; |
/branches/tracing/kernel/generic/src/ipc/ipc.c |
---|
609,9 → 609,11 |
#include <ipc/ipcrsc.h> |
#include <console/klog.h> |
#include <syscall/copy.h> |
#include <udebug.h> |
static void debug_mem_read(call_t *call) |
{ |
unative_t uspace_dst; |
void *uspace_ptr; |
unsigned size; |
void *buffer; |
618,8 → 620,9 |
int rc; |
klog_printf("debug_mem_read()"); |
uspace_ptr = (void *)IPC_GET_ARG2(call->data); |
size = IPC_GET_ARG3(call->data); |
uspace_dst = IPC_GET_ARG2(call->data); |
uspace_ptr = (void *)IPC_GET_ARG3(call->data); |
size = IPC_GET_ARG4(call->data); |
buffer = malloc(size, 0); // ??? |
klog_printf("debug_mem_read: src=%u, size=%u", uspace_ptr, size); |
638,6 → 641,7 |
/* Hack: ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that |
same code in process_answer() can be used |
(no way to distinguish method in answer) */ |
IPC_SET_ARG1(call->data, uspace_dst); |
IPC_SET_ARG2(call->data, size); |
call->buffer = buffer; |
648,6 → 652,7 |
{ |
call_t *call; |
int method; |
int dm; |
(void)arg; |
klog_printf("kbox_thread_proc()"); |
657,7 → 662,10 |
SYNCH_FLAGS_NONE); |
if (call != NULL) { |
method = IPC_GET_METHOD(call->data); |
if (method == IPC_M_DEBUG_MEM_READ) { |
dm = IPC_GET_ARG1(call->data); |
if (method == IPC_M_DEBUG_ALL && |
dm == UDEBUG_M_MEM_READ) { |
debug_mem_read(call); |
} |
} |
/branches/tracing/uspace/app/tester/debug/debug1.c |
---|
2,6 → 2,7 |
#include <unistd.h> |
#include <syscall.h> |
#include <ipc/ipc.h> |
#include <udebug.h> |
#include "../tester.h" |
const char *syscall_name[] = { |
63,12 → 64,12 |
phoneid = rc; |
printf("send IPC_M_DEBUG_BEGIN message\n"); |
rc = ipc_call_sync_0_0(phoneid, IPC_M_DEBUG_BEGIN); |
rc = ipc_call_sync_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN); |
printf("-> %d\n", rc); |
printf("send IPC_M_DEBUG_THREAD_READ message\n"); |
rc = ipc_call_sync_2_2(phoneid, IPC_M_DEBUG_THREAD_READ, |
&threadid_buf, TIDBUF_SIZE*sizeof(unsigned), |
rc = ipc_call_sync_3_2(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ, |
(sysarg_t)threadid_buf, TIDBUF_SIZE*sizeof(unsigned), |
&tb_copied, &tb_needed); |
printf("-> %d\n", rc); |
79,11 → 80,12 |
printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
while (1) { |
rc = ipc_call_sync_1_3(phoneid, IPC_M_DEBUG_GO, threadid_buf[0], |
&ev_type, &sc_id, &sc_rc); |
rc = ipc_call_sync_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO, |
threadid_buf[0], &ev_type, &sc_id, &sc_rc); |
if (rc >= 0) { |
rc = ipc_call_sync_3_1(phoneid, IPC_M_DEBUG_ARGS_READ, |
threadid_buf[0], sc_args, 6 * sizeof(unsigned), &copied); |
rc = ipc_call_sync_4_1(phoneid, IPC_M_DEBUG_ALL, |
UDEBUG_M_ARGS_READ, threadid_buf[0], sc_args, |
6 * sizeof(unsigned), &copied); |
} |
if (rc >= 0) { |
printf("%s[%d](%u, %u, %u, %u, %u, %u) -> %d\n", |
97,8 → 99,9 |
printf("read async call args..\n"); |
printf("dest=%u, ptr=%u, len=%u\n", |
(sysarg_t)ipc_args, sc_args[1], sizeof(ipc_args)); |
rc = ipc_call_sync_3_0(phoneid, IPC_M_DEBUG_MEM_READ, |
(sysarg_t)ipc_args, sc_args[1], sizeof(ipc_args)); |
rc = ipc_call_sync_4_0(phoneid, IPC_M_DEBUG_ALL, |
UDEBUG_M_MEM_READ, (sysarg_t)ipc_args, |
sc_args[1], sizeof(ipc_args)); |
printf("-> %d\n", rc); |
printf("args: (%u, %u, %u, %u, %u, %u)\n", |
ipc_args[0], ipc_args[1], ipc_args[2], |
/branches/tracing/uspace/lib/libc/include/udebug.h |
---|
0,0 → 1,15 |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_UDEBUG_H_ |
#define LIBC_UDEBUG_H_ |
#include <kernel/udebug.h> |
#endif |
/** @} |
*/ |