00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 #ifdef HAVE_SYS_PRCTL_H
00024 #include <sys/prctl.h>
00025 #endif
00026
00027 static void (*cont_fn)(void *);
00028 static pstring corepath;
00029
00030
00031
00032
00033 static void fault_report(int sig)
00034 {
00035 static int counter;
00036
00037 if (counter) _exit(1);
00038
00039 counter++;
00040
00041 DEBUGSEP(0);
00042 DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),SAMBA_VERSION_STRING));
00043 DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba3-HOWTO\n"));
00044 DEBUG(0,("\nFrom: http://www.samba.org/samba/docs/Samba3-HOWTO.pdf\n"));
00045 DEBUGSEP(0);
00046
00047 smb_panic("internal error");
00048
00049 if (cont_fn) {
00050 cont_fn(NULL);
00051 #ifdef SIGSEGV
00052 CatchSignal(SIGSEGV,SIGNAL_CAST SIG_DFL);
00053 #endif
00054 #ifdef SIGBUS
00055 CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL);
00056 #endif
00057 #ifdef SIGABRT
00058 CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL);
00059 #endif
00060 return;
00061 }
00062 exit(1);
00063 }
00064
00065
00066
00067
00068 static void sig_fault(int sig)
00069 {
00070 fault_report(sig);
00071 }
00072
00073
00074
00075
00076 void fault_setup(void (*fn)(void *))
00077 {
00078 cont_fn = fn;
00079
00080 #ifdef SIGSEGV
00081 CatchSignal(SIGSEGV,SIGNAL_CAST sig_fault);
00082 #endif
00083 #ifdef SIGBUS
00084 CatchSignal(SIGBUS,SIGNAL_CAST sig_fault);
00085 #endif
00086 #ifdef SIGABRT
00087 CatchSignal(SIGABRT,SIGNAL_CAST sig_fault);
00088 #endif
00089 }
00090
00091
00092
00093
00094
00095 void dump_core_setup(const char *progname)
00096 {
00097 pstring logbase;
00098 char * end;
00099
00100 if (lp_logfile() && *lp_logfile()) {
00101 snprintf(logbase, sizeof(logbase), "%s", lp_logfile());
00102 if ((end = strrchr_m(logbase, '/'))) {
00103 *end = '\0';
00104 }
00105 } else {
00106
00107
00108
00109
00110 snprintf(logbase, sizeof(logbase), "%s", dyn_LOGFILEBASE);
00111 }
00112
00113 SMB_ASSERT(progname != NULL);
00114
00115 snprintf(corepath, sizeof(corepath), "%s/cores", logbase);
00116 mkdir(corepath,0700);
00117
00118 snprintf(corepath, sizeof(corepath), "%s/cores/%s",
00119 logbase, progname);
00120 mkdir(corepath,0700);
00121
00122 sys_chown(corepath,getuid(),getgid());
00123 chmod(corepath,0700);
00124
00125 #ifdef HAVE_GETRLIMIT
00126 #ifdef RLIMIT_CORE
00127 {
00128 struct rlimit rlp;
00129 getrlimit(RLIMIT_CORE, &rlp);
00130 rlp.rlim_cur = MAX(16*1024*1024,rlp.rlim_cur);
00131 setrlimit(RLIMIT_CORE, &rlp);
00132 getrlimit(RLIMIT_CORE, &rlp);
00133 DEBUG(3,("Maximum core file size limits now %d(soft) %d(hard)\n",
00134 (int)rlp.rlim_cur,(int)rlp.rlim_max));
00135 }
00136 #endif
00137 #endif
00138
00139 #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
00140
00141
00142
00143
00144 prctl(PR_SET_DUMPABLE, 1);
00145 #endif
00146
00147
00148
00149
00150 }
00151
00152 void dump_core(void)
00153 {
00154
00155
00156
00157
00158 if (!lp_enable_core_files()) {
00159 DEBUG(0, ("Exiting on internal error (core file administratively disabled)\n"));
00160 exit(1);
00161 }
00162
00163 #if DUMP_CORE
00164
00165
00166
00167 if (geteuid() != 0) {
00168 become_root();
00169 }
00170
00171 if (*corepath != '\0') {
00172
00173
00174
00175 if (chdir(corepath) != 0) {
00176 DEBUG(0, ("unable to change to %s\n", corepath));
00177 DEBUGADD(0, ("refusing to dump core\n"));
00178 exit(1);
00179 }
00180
00181 DEBUG(0,("dumping core in %s\n", corepath));
00182 }
00183
00184 umask(~(0700));
00185 dbgflush();
00186
00187
00188 #ifdef SIGABRT
00189 CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL);
00190 #endif
00191
00192 abort();
00193
00194 #else
00195 exit(1);
00196 #endif
00197 }
00198