netatalk  4.6.1
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
fault.c File Reference
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <atalk/logger.h>
#include <atalk/util.h>

Macros

#define SIGNAL_CAST   (void (*)(int))
 
#define SAFE_FREE(x)   do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
 
#define BACKTRACE_STACK_SIZE   64
 
#define FAULT_ALTSTACK_SIZE   (64 * 1024)
 

Functions

static void log_backtrace (void *uctx)
 
static void panic_report (const char *why, void *uctx)
 
void netatalk_panic (const char *why)
 
static void fault_report (int sig, siginfo_t *info, void *uctx)
 
static void sig_fault (int sig, siginfo_t *info, void *ctx)
 
static void catch_fault_signal (int signum)
 
void fault_setup_thread (void)
 
void fault_setup (void(*fn)(void *))
 

Variables

static void(* cont_fn )(void *)
 
static void(*)(int) CatchSignal (int signum, void(*handler)(int))
 

Macro Definition Documentation

◆ BACKTRACE_STACK_SIZE

#define BACKTRACE_STACK_SIZE   64

◆ FAULT_ALTSTACK_SIZE

#define FAULT_ALTSTACK_SIZE   (64 * 1024)

◆ SAFE_FREE

#define SAFE_FREE (   x)    do { if ((x) != NULL) {free(x); x=NULL;} } while(0)

◆ SIGNAL_CAST

#define SIGNAL_CAST   (void (*)(int))

Function Documentation

◆ catch_fault_signal()

static void catch_fault_signal ( int  signum)
static

Install sig_fault for a fault signal, on the alternate stack

SA_ONSTACK is required to report stack exhaustion: the guard page leaves no room for a signal frame, so without it the kernel cannot run the handler and kills the process with no diagnostic.

◆ fault_report()

static void fault_report ( int  sig,
siginfo_t *  info,
void *  uctx 
)
static

report a fault

◆ fault_setup()

void fault_setup ( void(*)(void *)  fn)

setup our fault handlers

◆ fault_setup_thread()

void fault_setup_thread ( void  )

Give the calling thread its own alternate signal stack

sigaltstack() is per-thread and survives fork() but not pthread_create(), so a thread that exhausts its stack dies unreported unless it installs one.

◆ log_backtrace()

static void log_backtrace ( void *  uctx)
static

Log a backtrace of the calling thread

libunwind names frames on musl, which ships no execinfo; the execinfo path stays for platforms that do. Deep runs of one frame are the signature of runaway recursion, so log enough of them to see it.

◆ netatalk_panic()

void netatalk_panic ( const char *  why)

◆ panic_report()

static void panic_report ( const char *  why,
void *  uctx 
)
static

Something really nasty happened - panic !

◆ sig_fault()

static void sig_fault ( int  sig,
siginfo_t *  info,
void *  ctx 
)
static

catch serious errors

Variable Documentation

◆ CatchSignal

void(*)(int) CatchSignal(int signum, void(*handler)(int)) ( int  signum,
void(*)(int)  handler 
)
static

Catch a signal. This should implement the following semantics:

  1. The handler remains installed after being called.
  2. The signal should be blocked during handler execution.

◆ cont_fn

void(* cont_fn) (void *) ( void *  )
static