diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:21 -0400 |
---|---|---|
committer | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:21 -0400 |
commit | 67fc4e0cb931d6b4ccf21248e4199b154478ecea (patch) | |
tree | 4cf49d00bc9ac03c3c77d91fadd13fcabc75e0c9 /kernel/signal.c | |
parent | 5d5314d6795f3c1c0f415348ff8c51f7de042b77 (diff) |
kdb: core for kgdb back end (2 of 2)
This patch contains the hooks and instrumentation into kernel which
live outside the kernel/debug directory, which the kdb core
will call to run commands like lsmod, dmesg, bt etc...
CC: linux-arch@vger.kernel.org
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Martin Hicks <mort@sgi.com>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index dbd7fe073c55..825a3f24ad76 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -2735,3 +2735,43 @@ void __init signals_init(void) | |||
2735 | { | 2735 | { |
2736 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); | 2736 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); |
2737 | } | 2737 | } |
2738 | |||
2739 | #ifdef CONFIG_KGDB_KDB | ||
2740 | #include <linux/kdb.h> | ||
2741 | /* | ||
2742 | * kdb_send_sig_info - Allows kdb to send signals without exposing | ||
2743 | * signal internals. This function checks if the required locks are | ||
2744 | * available before calling the main signal code, to avoid kdb | ||
2745 | * deadlocks. | ||
2746 | */ | ||
2747 | void | ||
2748 | kdb_send_sig_info(struct task_struct *t, struct siginfo *info) | ||
2749 | { | ||
2750 | static struct task_struct *kdb_prev_t; | ||
2751 | int sig, new_t; | ||
2752 | if (!spin_trylock(&t->sighand->siglock)) { | ||
2753 | kdb_printf("Can't do kill command now.\n" | ||
2754 | "The sigmask lock is held somewhere else in " | ||
2755 | "kernel, try again later\n"); | ||
2756 | return; | ||
2757 | } | ||
2758 | spin_unlock(&t->sighand->siglock); | ||
2759 | new_t = kdb_prev_t != t; | ||
2760 | kdb_prev_t = t; | ||
2761 | if (t->state != TASK_RUNNING && new_t) { | ||
2762 | kdb_printf("Process is not RUNNING, sending a signal from " | ||
2763 | "kdb risks deadlock\n" | ||
2764 | "on the run queue locks. " | ||
2765 | "The signal has _not_ been sent.\n" | ||
2766 | "Reissue the kill command if you want to risk " | ||
2767 | "the deadlock.\n"); | ||
2768 | return; | ||
2769 | } | ||
2770 | sig = info->si_signo; | ||
2771 | if (send_sig_info(sig, info, t)) | ||
2772 | kdb_printf("Fail to deliver Signal %d to process %d.\n", | ||
2773 | sig, t->pid); | ||
2774 | else | ||
2775 | kdb_printf("Signal %d is sent to process %d.\n", sig, t->pid); | ||
2776 | } | ||
2777 | #endif /* CONFIG_KGDB_KDB */ | ||