From 3ab19002fe425d57579842815c6ac6b4a6b08210 Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Sun, 29 Jul 2007 01:06:36 +0000 Subject: [PATCH] Added "suspend", "resume" and "drop" commands to kernel debugger. It's now possible to debug amok-running user threads by suspending or resuming them, as well as dropping them into the userland-debugger from inside kdl. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21734 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/thread.c | 76 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index c9388ff6bc..47834786fe 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -535,12 +535,15 @@ make_thread_suspended(int argc, char **argv) struct hash_iterator i; int32 id; - if (argc != 2) { + if (argc > 2) { kprintf("usage: suspend [thread-id]\n"); return 0; } - id = strtoul(argv[1], NULL, 0); + if (argc == 1) + id = thread_get_current_thread()->id; + else + id = strtoul(argv[1], NULL, 0); hash_open(sThreadHash, &i); @@ -549,17 +552,80 @@ make_thread_suspended(int argc, char **argv) continue; thread->state = thread->next_state = B_THREAD_SUSPENDED; - kprintf("thread 0x%lx suspended\n", thread->id); + kprintf("thread 0x%lx suspended\n", id); break; } if (!thread) - kprintf("thread 0x%lx not found\n", thread->id); + kprintf("thread 0x%lx not found\n", id); hash_close(sThreadHash, &i, false); return 0; } +static int +make_thread_resumed(int argc, char **argv) +{ + struct thread *thread; + struct hash_iterator i; + int32 id; + + if (argc != 2) { + kprintf("usage: resume \n"); + return 0; + } + + // force user to enter a thread id, as using + // the current thread is usually not intended + id = strtoul(argv[1], NULL, 0); + + hash_open(sThreadHash, &i); + + while ((thread = hash_next(sThreadHash, &i)) != NULL) { + if (thread->id != id) + continue; + + if (thread->state == B_THREAD_SUSPENDED) { + thread->state = thread->next_state = B_THREAD_READY; + scheduler_enqueue_in_run_queue(thread); + kprintf("thread 0x%lx resumed\n", thread->id); + } + break; + } + if (!thread) + kprintf("thread 0x%lx not found\n", id); + + hash_close(sThreadHash, &i, false); + return 0; +} + + +static int +drop_into_debugger(int argc, char **argv) +{ + status_t err; + int32 id; + + if (argc > 2) { + kprintf("usage: drop [thread-id]\n"); + return 0; + } + + if (argc == 1) + id = thread_get_current_thread()->id; + else + id = strtoul(argv[1], NULL, 0); + + err = _user_debug_thread(id); + if (err) + kprintf("drop failed\n"); + else + kprintf("thread 0x%lx dropped into user debugger\n", id); + + return 0; +} + + static const char * state_to_text(struct thread *thread, int32 state) { @@ -1570,6 +1636,8 @@ thread_init(kernel_args *args) add_debugger_command("next_team", &dump_next_thread_in_team, "dump the next thread in the team of the last thread viewed"); add_debugger_command("unreal", &make_thread_unreal, "set realtime priority threads to normal priority"); add_debugger_command("suspend", &make_thread_suspended, "suspend a thread"); + add_debugger_command("resume", &make_thread_resumed, "resume a thread"); + add_debugger_command("drop", &drop_into_debugger, "drop a thread into the user-debugger"); return B_OK; }