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 |
