Path: blob/devel/elmergrid/src/metis-5.1.0/GKlib/error.c
3206 views
/*!1\file error.c2\brief Various error-handling functions34This file contains functions dealing with error reporting and termination56\author George7\date 1/1/20078\version\verbatim $Id: error.c 10711 2011-08-31 22:23:04Z karypis $ \endverbatim9*/101112#define _GK_ERROR_C_ /* this is needed to properly declare the gk_jub* variables13as an extern function in GKlib.h */1415#include <GKlib.h>161718/* These are the jmp_buf for the graceful exit in case of severe errors.19Multiple buffers are defined to allow for recursive invokation. */20#define MAX_JBUFS 12821__thread int gk_cur_jbufs=-1;22__thread jmp_buf gk_jbufs[MAX_JBUFS];23__thread jmp_buf gk_jbuf;2425typedef void (*gksighandler_t)(int);2627/* These are the holders of the old singal handlers for the trapped signals */28static __thread gksighandler_t old_SIGMEM_handler; /* Custom signal */29static __thread gksighandler_t old_SIGERR_handler; /* Custom signal */30static __thread gksighandler_t old_SIGMEM_handlers[MAX_JBUFS]; /* Custom signal */31static __thread gksighandler_t old_SIGERR_handlers[MAX_JBUFS]; /* Custom signal */3233/* The following is used to control if the gk_errexit() will actually abort or not.34There is always a single copy of this variable */35static int gk_exit_on_error = 1;363738/*************************************************************************/39/*! This function sets the gk_exit_on_error variable40*/41/*************************************************************************/42void gk_set_exit_on_error(int value)43{44gk_exit_on_error = value;45}46474849/*************************************************************************/50/*! This function prints an error message and exits51*/52/*************************************************************************/53void errexit(char *f_str,...)54{55va_list argp;5657va_start(argp, f_str);58vfprintf(stderr, f_str, argp);59va_end(argp);6061if (strlen(f_str) == 0 || f_str[strlen(f_str)-1] != '\n')62fprintf(stderr,"\n");63fflush(stderr);6465if (gk_exit_on_error)66exit(-2);6768/* abort(); */69}707172/*************************************************************************/73/*! This function prints an error message and raises a signum signal74*/75/*************************************************************************/76void gk_errexit(int signum, char *f_str,...)77{78va_list argp;7980va_start(argp, f_str);81vfprintf(stderr, f_str, argp);82va_end(argp);8384fprintf(stderr,"\n");85fflush(stderr);8687if (gk_exit_on_error)88raise(signum);89}909192/***************************************************************************/93/*! This function sets a number of signal handlers and sets the return point94of a longjmp95*/96/***************************************************************************/97int gk_sigtrap()98{99if (gk_cur_jbufs+1 >= MAX_JBUFS)100return 0;101102gk_cur_jbufs++;103104old_SIGMEM_handlers[gk_cur_jbufs] = signal(SIGMEM, gk_sigthrow);105old_SIGERR_handlers[gk_cur_jbufs] = signal(SIGERR, gk_sigthrow);106107return 1;108}109110111/***************************************************************************/112/*! This function sets the handlers for the signals to their default handlers113*/114/***************************************************************************/115int gk_siguntrap()116{117if (gk_cur_jbufs == -1)118return 0;119120signal(SIGMEM, old_SIGMEM_handlers[gk_cur_jbufs]);121signal(SIGERR, old_SIGERR_handlers[gk_cur_jbufs]);122123gk_cur_jbufs--;124125return 1;126}127128129/*************************************************************************/130/*! This function is the custome signal handler, which all it does is to131perform a longjump to the most recent saved environment132*/133/*************************************************************************/134void gk_sigthrow(int signum)135{136longjmp(gk_jbufs[gk_cur_jbufs], signum);137}138139140/***************************************************************************141* This function sets a number of signal handlers and sets the return point142* of a longjmp143****************************************************************************/144void gk_SetSignalHandlers()145{146old_SIGMEM_handler = signal(SIGMEM, gk_NonLocalExit_Handler);147old_SIGERR_handler = signal(SIGERR, gk_NonLocalExit_Handler);148}149150151/***************************************************************************152* This function sets the handlers for the signals to their default handlers153****************************************************************************/154void gk_UnsetSignalHandlers()155{156signal(SIGMEM, old_SIGMEM_handler);157signal(SIGERR, old_SIGERR_handler);158}159160161/*************************************************************************162* This function is the handler for SIGUSR1 that implements the cleaning up163* process prior to a non-local exit.164**************************************************************************/165void gk_NonLocalExit_Handler(int signum)166{167longjmp(gk_jbuf, signum);168}169170171/*************************************************************************/172/*! \brief Thread-safe implementation of strerror() */173/**************************************************************************/174char *gk_strerror(int errnum)175{176#if defined(WIN32) || defined(__MINGW32__)177return strerror(errnum);178#else179#ifndef SUNOS180static __thread char buf[1024];181182strerror_r(errnum, buf, 1024);183184buf[1023] = '\0';185return buf;186#else187return strerror(errnum);188#endif189#endif190}191192193194/*************************************************************************195* This function prints a backtrace of calling functions196**************************************************************************/197void PrintBackTrace()198{199#ifdef HAVE_EXECINFO_H200void *array[10];201int i, size;202char **strings;203204size = backtrace(array, 10);205strings = backtrace_symbols(array, size);206207printf("Obtained %d stack frames.\n", size);208for (i=0; i<size; i++) {209printf("%s\n", strings[i]);210}211free(strings);212#endif213}214215216