source: vendor/current/lib/util/fault.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 4.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Critical Fault handling
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Tim Prouty 2009
6
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.
11
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.
16
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/>.
19*/
20
21#include "replace.h"
22#include "system/filesys.h"
23#include "system/wait.h"
24#include "version.h"
25
26#ifdef HAVE_SYS_SYSCTL_H
27#include <sys/sysctl.h>
28#endif
29
30
31#ifdef HAVE_SYS_PRCTL_H
32#include <sys/prctl.h>
33#endif
34
35#include "debug.h"
36#include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
37#include "substitute.h"
38#include "fault.h"
39
40static struct {
41 bool disabled;
42 smb_panic_handler_t panic_handler;
43} fault_state;
44
45
46/*******************************************************************
47setup variables used for fault handling
48********************************************************************/
49void fault_configure(smb_panic_handler_t panic_handler)
50{
51 fault_state.panic_handler = panic_handler;
52}
53
54
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)
62{
63 fault_state.disabled = true;
64}
65
66
67/*******************************************************************
68report a fault
69********************************************************************/
70static void fault_report(int sig)
71{
72 static int counter;
73
74 if (counter) _exit(1);
75
76 counter++;
77
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);
82
83 smb_panic("internal error");
84
85 /* smb_panic() never returns, so this is really redundant */
86 exit(1);
87}
88
89/****************************************************************************
90catch serious errors
91****************************************************************************/
92static void sig_fault(int sig)
93{
94 fault_report(sig);
95}
96
97/*******************************************************************
98setup our fault handlers
99********************************************************************/
100void fault_setup(void)
101{
102 if (fault_state.disabled) {
103 return;
104 }
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
116}
117
118_PUBLIC_ const char *panic_action = NULL;
119
120/*
121 default smb_panic() implementation
122*/
123static void smb_panic_default(const char *why) _NORETURN_;
124static void smb_panic_default(const char *why)
125{
126#if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
127 /*
128 * Make sure all children can attach a debugger.
129 */
130 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
131#endif
132
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);
142
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)));
149 }
150 }
151 DEBUG(0,("PANIC: %s\n", why));
152
153#ifdef SIGABRT
154 CatchSignal(SIGABRT, SIG_DFL);
155#endif
156 abort();
157}
158
159
160/**
161 Something really nasty happened - panic !
162**/
163_PUBLIC_ void smb_panic(const char *why)
164{
165 if (fault_state.panic_handler) {
166 fault_state.panic_handler(why);
167 _exit(1);
168 }
169 smb_panic_default(why);
170}
Note: See TracBrowser for help on using the repository browser.