If init dies, log a signal which killed it, if any.
PATCH v2 1/1 If init dies, log a signal which killed it, if any.
I just received another user's pleas for help when their init mysteriously died. I again explained that they need to check whether it died because of bad instruction, a segv, or something else. Which was an annoying detour into writing a trivial C program to spawn his init and print its exit code:
http://lists.busybox.net/pipermail/busybox/2012-January/077172.html
I hear you saying "just test it under /bin/sh". Well, the crashing init _was_ /bin/sh.
Which prompted me to make kernel do this first step automatically. We can print exit code, which makes it possible to see that death was from e.g. SIGILL without writing test programs.
The code is fairly self-explanatory. Compile-tested.
Changes in v.2: don't try to decode signal names, just print exit status in hex.
--- kernel/exit.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
kernel/exit.c +5 -2
@@ -710,8 +710,11 @@ static struct task_struct *find_new_reaper(struct task_struct *father)if (unlikely (pid_ns->child_reaper == father)) {write_unlock_irq (&tasklist_lock); -if (unlikely (pid_ns == &init_pid_ns)) -panic ("Attempted to kill init!" ); +if (unlikely (pid_ns == &init_pid_ns)) { +panic ("Attempted to kill init! exitcode=%08x\n" , + father->signal->group_exit_code ?: + father->exit_code); + }zap_pid_ns_processes (pid_ns);write_lock_irq (&tasklist_lock);
Signature · 1 line
1.7.7.5
Quoted 12 lines · Denys Vlasenko
I just received another user's pleas for help when their init mysteriously died. I again explained that they need to check whether it died because of bad instruction, a segv, or something else. Which was an annoying detour into writing a trivial C program to spawn his init and print its exit code:
http://lists.busybox.net/pipermail/busybox/2012-January/077172.html
I hear you saying "just test it under
/bin/sh". Well, the crashing init _was_/bin/sh.
Quoted 8 lines
Which prompted me to make kernel do this first step automatically. We can print exit code, which makes it possible to see that death was from e.g. SIGILL without writing test programs.
The code is fairly self-explanatory. Compile-tested.
Changes in v.2: don't try to decode signal names, just print exit status in hex.
Looks reasonable to me.
Probably you should re-send the patch to Andrew, I do not know who else can pick it.
Quoted 26 lines
Signed-off-by Denys Vlasenko <[email protected]>--- kernel/exit.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)kernel/exit.c +5
-3@@ -710,8 +710,11 @@ static struct task_struct *find_new_reaper(struct task_struct *father)if (unlikely (pid_ns->child_reaper == father)) {write_unlock_irq (&tasklist_lock); -if (unlikely (pid_ns == &init_pid_ns)) -panic ("Attempted to kill init!" ); +if (unlikely (pid_ns == &init_pid_ns)) { +panic ("Attempted to kill init! exitcode=%08x\n" , + father->signal->group_exit_code ?: + father->exit_code); + }zap_pid_ns_processes (pid_ns);write_lock_irq (&tasklist_lock); --1.7.7.5
Quoted 26 lines · On Fri, 20 Jan 2012 23:17:16 +0100 Denys Vlasenko <[email protected]>…
I just received another user's pleas for help when their init mysteriously died. I again explained that they need to check whether it died because of bad instruction, a segv, or something else. Which was an annoying detour into writing a trivial C program to spawn his init and print its exit code:
http://lists.busybox.net/pipermail/busybox/2012-January/077172.html
I hear you saying "just test it under
/bin/sh". Well, the crashing init _was_/bin/sh.Which prompted me to make kernel do this first step automatically. We can print exit code, which makes it possible to see that death was from e.g. SIGILL without writing test programs.
The code is fairly self-explanatory. Compile-tested.
Changes in v.2: don't try to decode signal names, just print exit status in hex.
...
kernel/exit.c static struct task_struct *find_new_reaper(struct task_struct *father) · line 717
Quoted 10 lines
kernel/exit.c +5
-2@@ -710,8 +710,11 @@ static struct task_struct *find_new_reaper(struct task_struct *father)if (unlikely (pid_ns->child_reaper == father)) {write_unlock_irq (&tasklist_lock); -if (unlikely (pid_ns == &init_pid_ns)) -panic ("Attempted to kill init!" ); +if (unlikely (pid_ns == &init_pid_ns)) { +panic ("Attempted to kill init! exitcode=%08x\n" , + father->signal->group_exit_code ?: + father->exit_code); + }
It's a bit user-hostile to print a hex number in such a context without the leading 0x. The %08 does provide a hint - users are unlikely to interpret 00000011 as 11. But still, I think...
kernel/exit.c renamed from kernel/exit.c~kernel-exitc-if-init-dies-log-a-signal-which-killed-it-if-any-fix +1 -1
@@ -711,7 +711,7 @@ static struct task_struct *find_new_reapif (unlikely (pid_ns->child_reaper == father)) {write_unlock_irq (&tasklist_lock);if (unlikely (pid_ns == &init_pid_ns)) { -panic ("Attempted to kill init! exitcode=%08x\n" , +panic ("Attempted to kill init! exitcode=0x%08x\n" , father->signal->group_exit_code ?: father->exit_code); }
_
Or maybe we should use %d. Does anyone use hex for exit codes?
Quoted 15 lines · Andrew Morton
It's a bit user-hostile to print a hex number in such a context without the leading 0x. The %08 does provide a hint - users are unlikely to interpret 00000011 as 11. But still, I think...
kernel/exit.c renamed from kernel/exit.c~kernel-exitc-if-init-dies-log-a-signal-which-killed-it-if-any-fix +1
-1@@ -711,7 +711,7 @@ static struct task_struct *find_new_reapif (unlikely (pid_ns->child_reaper == father)) {write_unlock_irq (&tasklist_lock);if (unlikely (pid_ns == &init_pid_ns)) { -panic ("Attempted to kill init! exitcode=%08x\n" , +panic ("Attempted to kill init! exitcode=0x%08x\n" , father->signal->group_exit_code ?: father->exit_code); }
Quoted 1 line
_
Looks good to me.
Quoted 1 line
Or maybe we should use %d. Does anyone use hex for exit codes?
I guess hex is better, considering that normal (non-signal) exit code is stored in bits 8-15. It's more readable to see exit code 3 as 0x300 then as 768.
Signature · 1 line
vda