00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include <signal.h>
00025 #include <sys/ucontext.h>
00026 #include "hosthooks.h"
00027 #include "hosthooks-def.h"
00028 #include "toplev.h"
00029 #include "diagnostic.h"
00030 #include "config/host-darwin.h"
00031
00032 static void segv_crash_handler (int);
00033 static void segv_handler (int, siginfo_t *, void *);
00034 static void darwin_rs6000_extra_signals (void);
00035
00036 #ifndef HAVE_DECL_SIGALTSTACK
00037
00038
00039 extern int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
00040 #endif
00041
00042
00043
00044 #ifdef HAS_MCONTEXT_T_UNDERSCORES
00045 #define MC_FLD(x) __ ## x
00046 #else
00047 #define MC_FLD(x) x
00048 #endif
00049
00050 #undef HOST_HOOKS_EXTRA_SIGNALS
00051 #define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals
00052
00053
00054
00055
00056
00057
00058
00059 static void
00060 segv_crash_handler (int sig ATTRIBUTE_UNUSED)
00061 {
00062 internal_error ("Segmentation Fault (code)");
00063 }
00064
00065 static void
00066 segv_handler (int sig ATTRIBUTE_UNUSED,
00067 siginfo_t *sip ATTRIBUTE_UNUSED,
00068 void *scp)
00069 {
00070 ucontext_t *uc = (ucontext_t *)scp;
00071 sigset_t sigset;
00072 unsigned faulting_insn;
00073
00074
00075
00076 signal (SIGSEGV, segv_crash_handler);
00077 sigemptyset (&sigset);
00078 sigaddset (&sigset, SIGSEGV);
00079 sigprocmask (SIG_UNBLOCK, &sigset, NULL);
00080
00081 faulting_insn = *(unsigned *)uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0);
00082
00083
00084
00085
00086
00087
00088
00089 if ((faulting_insn & 0xFFFF8000) == 0x94218000
00090 || (faulting_insn & 0xFC1F03FF) == 0x7C01016E
00091 || (faulting_insn & 0xFC1F8000) == 0x90018000
00092 || (faulting_insn & 0xFC1F8000) == 0xD8018000
00093 || (faulting_insn & 0xFC1F8000) == 0xBC018000 )
00094 {
00095 char *shell_name;
00096
00097 fnotice (stderr, "Out of stack space.\n");
00098 shell_name = getenv ("SHELL");
00099 if (shell_name != NULL)
00100 shell_name = strrchr (shell_name, '/');
00101 if (shell_name != NULL)
00102 {
00103 static const char * shell_commands[][2] = {
00104 { "sh", "ulimit -S -s unlimited" },
00105 { "bash", "ulimit -S -s unlimited" },
00106 { "tcsh", "limit stacksize unlimited" },
00107 { "csh", "limit stacksize unlimited" },
00108
00109
00110 { "zsh", "limit stacksize 32m" }
00111 };
00112 size_t i;
00113
00114 for (i = 0; i < ARRAY_SIZE (shell_commands); i++)
00115 if (strcmp (shell_commands[i][0], shell_name + 1) == 0)
00116 {
00117 fnotice (stderr,
00118 "Try running '%s' in the shell to raise its limit.\n",
00119 shell_commands[i][1]);
00120 }
00121 }
00122
00123 if (global_dc->abort_on_error)
00124 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
00125
00126 exit (FATAL_EXIT_CODE);
00127 }
00128
00129 fprintf (stderr, "[address=%08lx pc=%08x]\n",
00130 uc->uc_mcontext->MC_FLD(es).MC_FLD(dar),
00131 uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0));
00132 internal_error ("Segmentation Fault");
00133 exit (FATAL_EXIT_CODE);
00134 }
00135
00136 static void
00137 darwin_rs6000_extra_signals (void)
00138 {
00139 struct sigaction sact;
00140 stack_t sigstk;
00141
00142 sigstk.ss_sp = xmalloc (SIGSTKSZ);
00143 sigstk.ss_size = SIGSTKSZ;
00144 sigstk.ss_flags = 0;
00145 if (sigaltstack (&sigstk, NULL) < 0)
00146 fatal_error ("While setting up signal stack: %m");
00147
00148 sigemptyset(&sact.sa_mask);
00149 sact.sa_flags = SA_ONSTACK | SA_SIGINFO;
00150 sact.sa_sigaction = segv_handler;
00151 if (sigaction (SIGSEGV, &sact, 0) < 0)
00152 fatal_error ("While setting up signal handler: %m");
00153 }
00154
00155
00156 const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;