Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2800 → Rev 2801

/branches/tracing/kernel/generic/include/proc/task.h
93,6 → 93,12
* certain extent.
*/
atomic_t active_calls;
 
/** Debugging stuff */
bool being_debugged;
bool stop_request;
call_t *debug_begin_call;
call_t *debug_go_call;
/** Architecture specific task data. */
task_arch_t arch;
/branches/tracing/kernel/generic/include/proc/thread.h
203,6 → 203,9
 
/** Thread's kernel stack. */
uint8_t *kstack;
 
/** Debugging stuff */
waitq_t go_wq;
} thread_t;
 
/** Thread list lock.
/branches/tracing/kernel/generic/include/udebug.h
0,0 → 1,16
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef KERN_UDEBUG_H_
#define KERN_UDEBUG_H_
 
void udebug_syscall_event(void);
void udebug_stopping_point(void);
 
#endif
 
/** @}
*/
/branches/tracing/kernel/generic/include/syscall/syscall.h
66,6 → 66,7
SYS_SYSINFO_VALID,
SYS_SYSINFO_VALUE,
SYS_DEBUG_ENABLE_CONSOLE,
SYS_IPC_CONNECT_TASK,
SYSCALL_END
} syscall_t;
 
/branches/tracing/kernel/generic/include/ipc/sysipc.h
57,6 → 57,7
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
irq_code_t *ucode);
unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno);
unative_t sys_ipc_connect_task(sysarg64_t *task_id);
 
#endif
 
/branches/tracing/kernel/generic/include/ipc/ipc.h
195,6 → 195,35
*/
#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.
*/
#define IPC_M_DEBUG_BEGIN 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.
*/
#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
 
/* Well-known methods */
#define IPC_M_LAST_SYSTEM 511
#define IPC_M_PING 512
299,6 → 328,7
extern int ipc_phone_hangup(phone_t *phone);
extern void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err);
extern void ipc_print_task(task_id_t taskid);
extern int ipc_connect_task(task_id_t taskid);
 
extern answerbox_t *ipc_phone_0;
 
/branches/tracing/kernel/generic/src/proc/thread.c
341,6 → 341,8
 
avltree_node_initialize(&t->threads_tree_node);
t->threads_tree_node.key = (uintptr_t) t;
waitq_initialize(&t->go_wq);
 
/* might depend on previous initialization */
thread_create_arch(t);
/branches/tracing/kernel/generic/src/syscall/syscall.c
52,6 → 52,7
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <console/klog.h>
#include <udebug.h>
 
/** Print using kernel facility
*
108,6 → 109,9
if (THREAD->interrupted)
thread_exit();
 
udebug_syscall_event();
udebug_stopping_point();
return rc;
}
158,7 → 162,9
(syshandler_t) sys_sysinfo_value,
/* Debug calls */
(syshandler_t) sys_debug_enable_console
(syshandler_t) sys_debug_enable_console,
 
(syshandler_t) sys_ipc_connect_task
};
 
/** @}
/branches/tracing/kernel/generic/src/ipc/sysipc.c
290,13 → 290,76
return 0;
}
 
static task_t *get_lock_callee_task(phone_t *phone)
{
answerbox_t *answerbox;
task_t *ta;
 
// FIXME: locking!!!
 
answerbox = phone->callee;
ta = answerbox->task;
 
spinlock_lock(&ta->lock);
 
return ta;
}
 
#include <console/klog.h>
 
static void debug_begin(call_t *call, phone_t *phone)
{
task_t *ta;
 
klog_printf("debug_begin()");
ta = get_lock_callee_task(phone);
klog_printf("debugging task %llu\n", ta->taskid);
 
if (ta->being_debugged != false) {
IPC_SET_RETVAL(call->data, EBUSY);
ipc_answer(&ta->answerbox, call);
 
spinlock_unlock(&ta->lock);
return;
}
 
ta->being_debugged = true;
ta->stop_request = true;
ta->debug_begin_call = call;
spinlock_unlock(&ta->lock);
 
klog_printf("debug_begin() done");
}
 
static void debug_go(call_t *call, phone_t *phone)
{
thread_t *t;
link_t *l;
task_t *ta;
 
klog_printf("debug_go()");
ta = get_lock_callee_task(phone);
 
l = ta->th_head.next;
if (l != &TASK->th_head) {
t = list_get_instance(l, thread_t, th_link);
waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
}
 
ta->debug_go_call = call;
spinlock_unlock(&ta->lock);
}
 
 
/** Called before the request is sent.
*
* @param call Call structure with the request.
* @param phone Phone that the call will be sent through.
*
* @return Return 0 on success, ELIMIT or EPERM on error.
*/
static int request_preprocess(call_t *call)
static int request_preprocess(call_t *call, phone_t *phone)
{
int newphid;
size_t size;
338,6 → 401,12
return rc;
}
break;
case IPC_M_DEBUG_BEGIN:
debug_begin(call, phone);
break;
case IPC_M_DEBUG_GO:
debug_go(call, phone);
break;
default:
break;
}
397,7 → 466,17
return -1;
}
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:
return -1;
default:
break;
}
return 0;
}
 
439,7 → 518,7
IPC_SET_ARG4(call.data, 0);
IPC_SET_ARG5(call.data, 0);
 
if (!(res = request_preprocess(&call))) {
if (!(res = request_preprocess(&call, phone))) {
ipc_call_sync(phone, &call);
process_answer(&call);
} else {
477,7 → 556,7
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res = request_preprocess(&call))) {
if (!(res = request_preprocess(&call, phone))) {
ipc_call_sync(phone, &call);
process_answer(&call);
} else
544,7 → 623,7
*/
IPC_SET_ARG5(call->data, 0);
 
if (!(res = request_preprocess(call)))
if (!(res = request_preprocess(call, phone)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
578,7 → 657,7
ipc_call_free(call);
return (unative_t) rc;
}
if (!(res = request_preprocess(call)))
if (!(res = request_preprocess(call, phone)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
862,5 → 941,26
return 0;
}
 
#include <console/klog.h>
 
/**
* Syscall connect to a task by id.
*
* @return Phone id on success, or negative error code.
*/
unative_t sys_ipc_connect_task(sysarg64_t *uspace_taskid_arg)
{
sysarg64_t taskid_arg;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
 
klog_printf("sys_ipc_connect_kbox(%lld, %d)", taskid_arg.value);
 
return ipc_connect_task(taskid_arg.value);
}
 
/** @}
*/
/branches/tracing/kernel/generic/src/ipc/ipc.c
606,5 → 606,38
spinlock_unlock(&task->lock);
}
 
#include <ipc/ipcrsc.h>
#include <console/klog.h>
 
/**
* Connect phone to a task specified by id.
*
* @return Phone id on success, or negative error code.
*/
int ipc_connect_task(task_id_t taskid)
{
int newphid;
task_t *ta;
 
newphid = phone_alloc();
if (newphid < 0)
return ELIMIT;
 
spinlock_lock(&tasks_lock);
ta = task_find_by_id(taskid);
if (ta == NULL) {
spinlock_unlock(&tasks_lock);
return ENOENT;
}
spinlock_lock(&ta->lock);
spinlock_unlock(&tasks_lock);
 
ipc_phone_connect(&TASK->phones[newphid], &ta->answerbox);
spinlock_unlock(&ta->lock);
 
return newphid;
}
 
/** @}
*/
/branches/tracing/kernel/generic/src/udebug/udebug.c
0,0 → 1,39
/** @addtogroup generic
* @{
*/
 
/**
* @file
* @brief Tdebug.
*/
#include <synch/waitq.h>
#include <console/klog.h>
#include <udebug.h>
#include <arch.h>
 
void udebug_stopping_point(void)
{
if (TASK->stop_request) { /* locking! */
klog_printf("udebug_stopping_point");
IPC_SET_RETVAL(TASK->debug_begin_call->data, 0);
ipc_answer(&TASK->answerbox, TASK->debug_begin_call);
TASK->stop_request = false;
TASK->debug_begin_call = NULL;
waitq_sleep(&THREAD->go_wq);
}
}
 
void udebug_syscall_event(void)
{
/* being debugged + have go */
if (TASK->being_debugged && !TASK->stop_request) { /* locking! */
klog_printf("udebug_syscall_event");
IPC_SET_RETVAL(TASK->debug_go_call->data, 0);
ipc_answer(&TASK->answerbox, TASK->debug_go_call);
waitq_sleep(&THREAD->go_wq);
}
}
 
/** @}
*/
/branches/tracing/kernel/Makefile
275,6 → 275,7
generic/src/ipc/sysipc.c \
generic/src/ipc/ipcrsc.c \
generic/src/ipc/irq.c \
generic/src/udebug/udebug.c \
generic/src/security/cap.c \
generic/src/sysinfo/sysinfo.c
 
/branches/tracing/uspace/app/tester/debug/debug1.def
0,0 → 1,6
{
"debug1",
"Userspace debugging test",
&test_debug1,
true
},
/branches/tracing/uspace/app/tester/debug/debug1.c
0,0 → 1,33
#include <stdio.h>
#include <unistd.h>
#include <ipc/ipc.h>
#include "../tester.h"
 
 
char * test_debug1(bool quiet)
{
int taskid;
int rc;
int phoneid;
int i;
 
printf("running debug1 test\n");
taskid = 12;
printf("ipc_connect_task(%d)...\n", taskid);
rc = ipc_connect_task(taskid);
printf("-> %d\n", rc);
phoneid = rc;
 
printf("send IPC_M_DEBUG_BEGIN message\n");
rc = ipc_call_sync_0_0(phoneid, IPC_M_DEBUG_BEGIN);
printf("-> %d\n", rc);
 
while (1) {
printf("send IPC_M_DEBUG_GO message\n");
rc = ipc_call_sync_0_0(phoneid, IPC_M_DEBUG_GO);
printf("-> %d\n", rc);
}
 
printf("done\n");
return NULL;
}
/branches/tracing/uspace/app/tester/tester.c
57,6 → 57,7
#include "ipc/hangup.def"
#include "devmap/devmap1.def"
#include "vfs/vfs1.def"
#include "debug/debug1.def"
{NULL, NULL, NULL}
};
 
/branches/tracing/uspace/app/tester/tester.h
70,6 → 70,7
extern char * test_hangup(bool quiet);
extern char * test_devmap1(bool quiet);
extern char * test_vfs1(bool quiet);
extern char * test_debug1(bool quiet);
 
extern test_t tests[];
 
/branches/tracing/uspace/app/tester/Makefile
53,7 → 53,8
ipc/answer.c \
ipc/hangup.c \
devmap/devmap1.c \
vfs/vfs1.c
vfs/vfs1.c \
debug/debug1.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
/branches/tracing/uspace/lib/libc/include/ipc/ipc.h
288,6 → 288,10
extern int ipc_data_write_receive(ipc_callid_t *callid, size_t *size);
extern int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size);
 
#include <task.h>
 
extern int ipc_connect_task(task_id_t id);
 
#endif
 
/** @}
/branches/tracing/uspace/lib/libc/generic/ipc.c
909,6 → 909,18
{
return ipc_answer_2(callid, EOK, (ipcarg_t) dst, (ipcarg_t) size);
}
 
#include <kernel/syscall/sysarg64.h>
/** Connect to a task specified by id.
*/
int ipc_connect_task(task_id_t id)
{
sysarg64_t arg;
 
arg.value = (unsigned long long) id;
 
return __SYSCALL1(SYS_IPC_CONNECT_TASK, (sysarg_t) &arg);
}
/** @}
*/