diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2012-01-30 12:15:22 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-01-30 12:15:22 +0100 |
commit | da2b2da6a708edffcc3b405ab5fd7f3f11af5d33 (patch) | |
tree | aad306641009c4faccf419327d3b9ed724d52df5 /init | |
parent | 1c7724bf2acb6ebe28b24bd6da3b740e716b46cf (diff) | |
download | busybox-w32-da2b2da6a708edffcc3b405ab5fd7f3f11af5d33.tar.gz busybox-w32-da2b2da6a708edffcc3b405ab5fd7f3f11af5d33.tar.bz2 busybox-w32-da2b2da6a708edffcc3b405ab5fd7f3f11af5d33.zip |
init: add a segv debugging aid, disabled by default
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'init')
-rw-r--r-- | init/init.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/init/init.c b/init/init.c index c540faa70..724894698 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -108,6 +108,8 @@ | |||
108 | //config: Note that on Linux, init attempts to detect serial terminal and | 108 | //config: Note that on Linux, init attempts to detect serial terminal and |
109 | //config: sets TERM to "vt102" if one is found. | 109 | //config: sets TERM to "vt102" if one is found. |
110 | 110 | ||
111 | #define DEBUG_SEGV_HANDLER 0 | ||
112 | |||
111 | #include "libbb.h" | 113 | #include "libbb.h" |
112 | #include <syslog.h> | 114 | #include <syslog.h> |
113 | #include <paths.h> | 115 | #include <paths.h> |
@@ -118,6 +120,15 @@ | |||
118 | #endif | 120 | #endif |
119 | #include "reboot.h" /* reboot() constants */ | 121 | #include "reboot.h" /* reboot() constants */ |
120 | 122 | ||
123 | #if DEBUG_SEGV_HANDLER | ||
124 | # undef _GNU_SOURCE | ||
125 | # define _GNU_SOURCE 1 | ||
126 | # undef __USE_GNU | ||
127 | # define __USE_GNU 1 | ||
128 | # include <execinfo.h> | ||
129 | # include <sys/ucontext.h> | ||
130 | #endif | ||
131 | |||
121 | /* Used only for sanitizing purposes in set_sane_term() below. On systems where | 132 | /* Used only for sanitizing purposes in set_sane_term() below. On systems where |
122 | * the baud rate is stored in a separate field, we can safely disable them. */ | 133 | * the baud rate is stored in a separate field, we can safely disable them. */ |
123 | #ifndef CBAUD | 134 | #ifndef CBAUD |
@@ -957,6 +968,33 @@ static int check_delayed_sigs(void) | |||
957 | } | 968 | } |
958 | } | 969 | } |
959 | 970 | ||
971 | #if DEBUG_SEGV_HANDLER | ||
972 | static | ||
973 | void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) | ||
974 | { | ||
975 | long ip; | ||
976 | ucontext_t *uc; | ||
977 | |||
978 | uc = ucontext; | ||
979 | ip = uc->uc_mcontext.gregs[REG_EIP]; | ||
980 | fdprintf(2, "signal:%d address:0x%lx ip:0x%lx\n", | ||
981 | sig, | ||
982 | /* this is void*, but using %p would print "(null)" | ||
983 | * even for ptrs which are not exactly 0, but, say, 0x123: | ||
984 | */ | ||
985 | (long)info->si_addr, | ||
986 | ip); | ||
987 | { | ||
988 | /* glibc extension */ | ||
989 | void *array[50]; | ||
990 | int size; | ||
991 | size = backtrace(array, 50); | ||
992 | backtrace_symbols_fd(array, size, 2); | ||
993 | } | ||
994 | for (;;) sleep(9999); | ||
995 | } | ||
996 | #endif | ||
997 | |||
960 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 998 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
961 | int init_main(int argc UNUSED_PARAM, char **argv) | 999 | int init_main(int argc UNUSED_PARAM, char **argv) |
962 | { | 1000 | { |
@@ -964,6 +1002,19 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
964 | return kill(1, SIGHUP); | 1002 | return kill(1, SIGHUP); |
965 | } | 1003 | } |
966 | 1004 | ||
1005 | #if DEBUG_SEGV_HANDLER | ||
1006 | { | ||
1007 | struct sigaction sa; | ||
1008 | memset(&sa, 0, sizeof(sa)); | ||
1009 | sa.sa_sigaction = handle_sigsegv; | ||
1010 | sa.sa_flags = SA_SIGINFO; | ||
1011 | sigaction(SIGSEGV, &sa, NULL); | ||
1012 | sigaction(SIGILL, &sa, NULL); | ||
1013 | sigaction(SIGFPE, &sa, NULL); | ||
1014 | sigaction(SIGBUS, &sa, NULL); | ||
1015 | } | ||
1016 | #endif | ||
1017 | |||
967 | if (!DEBUG_INIT) { | 1018 | if (!DEBUG_INIT) { |
968 | /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ | 1019 | /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ |
969 | if (getpid() != 1 | 1020 | if (getpid() != 1 |