Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/lib/util/fault.c

    r740 r988  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   Critical Fault handling
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    
     5   Copyright (C) Tim Prouty 2009
     6
    67   This program is free software; you can redistribute it and/or modify
    78   it under the terms of the GNU General Public License as published by
    89   the Free Software Foundation; either version 3 of the License, or
    910   (at your option) any later version.
    10    
     11
    1112   This program is distributed in the hope that it will be useful,
    1213   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1314   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1415   GNU General Public License for more details.
    15    
     16
    1617   You should have received a copy of the GNU General Public License
    1718   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    1819*/
    1920
    20 #include "includes.h"
     21#include "replace.h"
     22#include "system/filesys.h"
     23#include "system/wait.h"
    2124#include "version.h"
    22 #include "system/wait.h"
    23 #include "system/filesys.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
    2454
    2555/**
    26  * @file
    27  * @brief Fault handling
    28  */
    29 
    30 /* the registered fault handler */
    31 static struct {
    32         const char *name;
    33         void (*fault_handler)(int sig);
    34 } fault_handlers;
    35 
    36 static const char *progname;
    37 
    38 #ifdef HAVE_BACKTRACE
    39 #include <execinfo.h>
    40 #elif HAVE_LIBEXC_H
    41 #include <libexc.h>
    42 #endif
    43 
    44 /**
    45  * Write backtrace to debug log
    46  */
    47 _PUBLIC_ void call_backtrace(void)
     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)
    4862{
    49 #ifdef HAVE_BACKTRACE
    50 #ifndef BACKTRACE_STACK_SIZE
    51 #define BACKTRACE_STACK_SIZE 64
    52 #endif
    53         void *backtrace_stack[BACKTRACE_STACK_SIZE];
    54         int backtrace_size;
    55         char **backtrace_strings;
    56 
    57         /* get the backtrace (stack frames) */
    58         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
    59         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
    60 
    61         DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
    62                   (unsigned long)backtrace_size));
    63        
    64         if (backtrace_strings) {
    65                 int i;
    66 
    67                 for (i = 0; i < backtrace_size; i++)
    68                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
    69 
    70                 /* Leak the backtrace_strings, rather than risk what free() might do */
    71         }
    72 
    73 #elif HAVE_LIBEXC
    74 
    75 #define NAMESIZE 32 /* Arbitrary */
    76 #ifndef BACKTRACE_STACK_SIZE
    77 #define BACKTRACE_STACK_SIZE 64
    78 #endif
    79 
    80         /* The IRIX libexc library provides an API for unwinding the stack. See
    81          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
    82          * since we are about to abort anyway, it hardly matters.
    83          *
    84          * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this
    85          * will fail with a nasty message upon failing to open the /proc entry.
    86          */
    87         {
    88                 uint64_t        addrs[BACKTRACE_STACK_SIZE];
    89                 char *          names[BACKTRACE_STACK_SIZE];
    90                 char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
    91 
    92                 int             i;
    93                 int             levels;
    94 
    95                 ZERO_ARRAY(addrs);
    96                 ZERO_ARRAY(names);
    97                 ZERO_ARRAY(namebuf);
    98 
    99                 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
    100                         names[i] = namebuf + (i * NAMESIZE);
    101                 }
    102 
    103                 levels = trace_back_stack(0, addrs, names,
    104                                 BACKTRACE_STACK_SIZE, NAMESIZE);
    105 
    106                 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
    107                 for (i = 0; i < levels; i++) {
    108                         DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
    109                 }
    110      }
    111 #undef NAMESIZE
    112 #endif
     63        fault_state.disabled = true;
    11364}
    11465
    115 _PUBLIC_ const char *panic_action = NULL;
    11666
    117 /**
    118  Something really nasty happened - panic !
    119 **/
    120 _PUBLIC_ _NORETURN_ void smb_panic(const char *why)
    121 {
    122         int result;
    123 
    124         if (panic_action && *panic_action) {
    125                 char pidstr[20];
    126                 char cmdstring[200];
    127                 safe_strcpy(cmdstring, panic_action, sizeof(cmdstring));
    128                 snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
    129                 all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring));
    130                 if (progname) {
    131                         all_string_sub(cmdstring, "%PROG%", progname, sizeof(cmdstring));
    132                 }
    133                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring));
    134                 result = system(cmdstring);
    135 
    136                 if (result == -1)
    137                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
    138                                   strerror(errno)));
    139                 else
    140                         DEBUG(0, ("smb_panic(): action returned status %d\n",
    141                                   WEXITSTATUS(result)));
    142         }
    143         DEBUG(0,("PANIC: %s\n", why));
    144 
    145         call_backtrace();
    146 
    147 #ifdef SIGABRT
    148         CatchSignal(SIGABRT, SIG_DFL);
    149 #endif
    150         abort();
    151 }
    152 
    153 /**
     67/*******************************************************************
    15468report a fault
    155 **/
    156 _NORETURN_ static void fault_report(int sig)
     69********************************************************************/
     70static void fault_report(int sig)
    15771{
    15872        static int counter;
    159        
     73
    16074        if (counter) _exit(1);
    16175
    162         DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"));
     76        counter++;
     77
     78        DEBUGSEP(0);
    16379        DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),SAMBA_VERSION_STRING));
    164         DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
    165         DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"));
     80        DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba HOWTO\n"));
     81        DEBUGSEP(0);
    16682
    16783        smb_panic("internal error");
    16884
     85        /* smb_panic() never returns, so this is really redundant */
    16986        exit(1);
    17087}
    17188
    172 /**
     89/****************************************************************************
    17390catch serious errors
    174 **/
    175 _NORETURN_ static void sig_fault(int sig)
     91****************************************************************************/
     92static void sig_fault(int sig)
    17693{
    177         if (fault_handlers.fault_handler) {
    178                 /* we have a fault handler, call it. It may not return. */
    179                 fault_handlers.fault_handler(sig);
    180         }
    181         /* If it returns or doesn't exist, use regular reporter */
    18294        fault_report(sig);
    18395}
    18496
    185 /**
     97/*******************************************************************
    18698setup our fault handlers
    187 **/
    188 _PUBLIC_ void fault_setup(const char *pname)
     99********************************************************************/
     100void fault_setup(void)
    189101{
    190         if (progname != NULL) {
     102        if (fault_state.disabled) {
    191103                return;
    192104        }
    193         progname = pname;
     105#if !defined(HAVE_DISABLE_FAULT_HANDLING)
    194106#ifdef SIGSEGV
    195107        CatchSignal(SIGSEGV, sig_fault);
     
    201113        CatchSignal(SIGABRT, sig_fault);
    202114#endif
    203 #ifdef SIGFPE
    204         CatchSignal(SIGFPE, sig_fault);
    205115#endif
    206116}
    207117
    208 /**
    209    disable setting up fault handlers
    210 **/
    211 _PUBLIC_ void fault_setup_disable(void)
     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)
    212125{
    213         progname = "fault disabled";
     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();
    214157}
    215158
    216159
    217160/**
    218   register a fault handler.
    219   Should only be called once in the execution of smbd.
    220 */
    221 _PUBLIC_ bool register_fault_handler(const char *name,
    222                                      void (*fault_handler)(int sig))
     161   Something really nasty happened - panic !
     162**/
     163_PUBLIC_ void smb_panic(const char *why)
    223164{
    224         if (fault_handlers.name != NULL) {
    225                 /* it's already registered! */
    226                 DEBUG(2,("fault handler '%s' already registered - failed '%s'\n",
    227                          fault_handlers.name, name));
    228                 return false;
     165        if (fault_state.panic_handler) {
     166                fault_state.panic_handler(why);
     167                _exit(1);
    229168        }
    230 
    231         fault_handlers.name = name;
    232         fault_handlers.fault_handler = fault_handler;
    233 
    234         DEBUG(2,("fault handler '%s' registered\n", name));
    235         return true;
     169        smb_panic_default(why);
    236170}
Note: See TracChangeset for help on using the changeset viewer.