spoolss: fix jobid in level 1 GetJob and EnumJobs responses
[Samba.git] / lib / util / fault.c
blob54d847117423df8279a68f4335bd972c513d4571
1 /*
2 Unix SMB/CIFS implementation.
3 Critical Fault handling
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Tim Prouty 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "replace.h"
22 #include "system/filesys.h"
23 #include "system/wait.h"
24 #include "version.h"
26 #ifdef HAVE_SYS_SYSCTL_H
27 #include <sys/sysctl.h>
28 #endif
31 #ifdef HAVE_SYS_PRCTL_H
32 #include <sys/prctl.h>
33 #endif
35 #include "debug.h"
36 #include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
37 #include "substitute.h"
38 #include "fault.h"
40 static struct {
41 bool disabled;
42 smb_panic_handler_t panic_handler;
43 } fault_state;
46 /*******************************************************************
47 setup variables used for fault handling
48 ********************************************************************/
49 void fault_configure(smb_panic_handler_t panic_handler)
51 fault_state.panic_handler = panic_handler;
55 /**
56 disable setting up fault handlers
57 This is used for the bind9 dlz module, as we
58 don't want a Samba module in bind9 to override the bind
59 fault handling
60 **/
61 _PUBLIC_ void fault_setup_disable(void)
63 fault_state.disabled = true;
67 /*******************************************************************
68 report a fault
69 ********************************************************************/
70 static void fault_report(int sig)
72 static int counter;
74 if (counter) _exit(1);
76 counter++;
78 DEBUGSEP(0);
79 DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),SAMBA_VERSION_STRING));
80 DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba HOWTO\n"));
81 DEBUGSEP(0);
83 smb_panic("internal error");
85 /* smb_panic() never returns, so this is really redundant */
86 exit(1);
89 /****************************************************************************
90 catch serious errors
91 ****************************************************************************/
92 static void sig_fault(int sig)
94 fault_report(sig);
97 /*******************************************************************
98 setup our fault handlers
99 ********************************************************************/
100 void fault_setup(void)
102 if (fault_state.disabled) {
103 return;
105 #if !defined(HAVE_DISABLE_FAULT_HANDLING)
106 #ifdef SIGSEGV
107 CatchSignal(SIGSEGV, sig_fault);
108 #endif
109 #ifdef SIGBUS
110 CatchSignal(SIGBUS, sig_fault);
111 #endif
112 #ifdef SIGABRT
113 CatchSignal(SIGABRT, sig_fault);
114 #endif
115 #endif
118 _PUBLIC_ const char *panic_action = NULL;
121 default smb_panic() implementation
123 static void smb_panic_default(const char *why) _NORETURN_;
124 static void smb_panic_default(const char *why)
126 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
128 * Make sure all children can attach a debugger.
130 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
131 #endif
133 if (panic_action && *panic_action) {
134 char cmdstring[200];
135 if (strlcpy(cmdstring, panic_action, sizeof(cmdstring)) < sizeof(cmdstring)) {
136 int result;
137 char pidstr[20];
138 snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
139 all_string_sub(cmdstring, "%d", pidstr, sizeof(cmdstring));
140 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring));
141 result = system(cmdstring);
143 if (result == -1)
144 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
145 strerror(errno)));
146 else
147 DEBUG(0, ("smb_panic(): action returned status %d\n",
148 WEXITSTATUS(result)));
151 DEBUG(0,("PANIC: %s\n", why));
153 #ifdef SIGABRT
154 CatchSignal(SIGABRT, SIG_DFL);
155 #endif
156 abort();
161 Something really nasty happened - panic !
163 _PUBLIC_ void smb_panic(const char *why)
165 if (fault_state.panic_handler) {
166 fault_state.panic_handler(why);
167 _exit(1);
169 smb_panic_default(why);