Skip to content

Commit

Permalink
main/init: add exception signal handlers (baresip#765)
Browse files Browse the repository at this point in the history
* main/init: add SIGSEGV, SIGABRT and SIGILL handler

* add SIGNAL_BTRACE option and win32 exception handling

* replace SIGNAL_BTRACE with runtime libre_signal_btrace(enable)

* fix indentation

* rename s/signal_btrace/exception_btrace
  • Loading branch information
sreimers authored and Vladimir Orlov committed May 11, 2023
1 parent 8e16026 commit 53d76d0
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/re_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void fd_debug(void);

int libre_init(void);
void libre_close(void);
void libre_exception_btrace(bool enable);

int re_main(re_signal_h *signalh);
void re_cancel(void);
Expand Down
145 changes: 145 additions & 0 deletions src/main/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,139 @@
*
* Copyright (C) 2010 Creytiv.com
*/
#include <stdlib.h>
#ifdef HAVE_SIGNAL
#include <signal.h>
#endif
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif
#include <re_types.h>
#include <re_fmt.h>
#include <re_list.h>
#include <re_net.h>
#include <re_sys.h>
#include <re_main.h>
#include <re_btrace.h>
#include "main.h"


static bool exception_btrace = false;


#ifdef HAVE_SIGNAL
static void signal_handler(int sig)
{
struct btrace bt;

if (!exception_btrace)
return;

btrace(&bt);
re_fprintf(stderr, "Error: Signal (%d) %H\n", sig, btrace_println,
&bt);
fflush(stderr);

exit(128 + sig);
}
#endif


#ifdef WIN32
LONG WINAPI exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
{
struct btrace bt;

if (!exception_btrace)
return EXCEPTION_CONTINUE_SEARCH;

if (EXCEPTION_STACK_OVERFLOW !=
ExceptionInfo->ExceptionRecord->ExceptionCode) {
btrace(&bt);
re_fprintf(stderr, "%H\n", btrace_println, &bt);
}
else {
re_fprintf(stderr, "stack overflow: %p\n",
(void *)ExceptionInfo->ContextRecord->Rip);
}

switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION:
re_fprintf(stderr, "Error: EXCEPTION_ACCESS_VIOLATION\n");
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
re_fprintf(stderr, "Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n");
break;
case EXCEPTION_BREAKPOINT:
re_fprintf(stderr, "Error: EXCEPTION_BREAKPOINT\n");
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
re_fprintf(stderr, "Error: EXCEPTION_DATATYPE_MISALIGNMENT\n");
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
re_fprintf(stderr, "Error: EXCEPTION_FLT_DENORMAL_OPERAND\n");
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
re_fprintf(stderr, "Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n");
break;
case EXCEPTION_FLT_INEXACT_RESULT:
re_fprintf(stderr, "Error: EXCEPTION_FLT_INEXACT_RESULT\n");
break;
case EXCEPTION_FLT_INVALID_OPERATION:
re_fprintf(stderr, "Error: EXCEPTION_FLT_INVALID_OPERATION\n");
break;
case EXCEPTION_FLT_OVERFLOW:
re_fprintf(stderr, "Error: EXCEPTION_FLT_OVERFLOW\n");
break;
case EXCEPTION_FLT_STACK_CHECK:
re_fprintf(stderr, "Error: EXCEPTION_FLT_STACK_CHECK\n");
break;
case EXCEPTION_FLT_UNDERFLOW:
re_fprintf(stderr, "Error: EXCEPTION_FLT_UNDERFLOW\n");
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
re_fprintf(stderr, "Error: EXCEPTION_ILLEGAL_INSTRUCTION\n");
break;
case EXCEPTION_IN_PAGE_ERROR:
re_fprintf(stderr, "Error: EXCEPTION_IN_PAGE_ERROR\n");
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
re_fprintf(stderr, "Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n");
break;
case EXCEPTION_INT_OVERFLOW:
re_fprintf(stderr, "Error: EXCEPTION_INT_OVERFLOW\n");
break;
case EXCEPTION_INVALID_DISPOSITION:
re_fprintf(stderr, "Error: EXCEPTION_INVALID_DISPOSITION\n");
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
re_fprintf(stderr,
"Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n");
break;
case EXCEPTION_PRIV_INSTRUCTION:
re_fprintf(stderr, "Error: EXCEPTION_PRIV_INSTRUCTION\n");
break;
case EXCEPTION_SINGLE_STEP:
re_fprintf(stderr, "Error: EXCEPTION_SINGLE_STEP\n");
break;
case EXCEPTION_STACK_OVERFLOW:
re_fprintf(stderr, "Error: EXCEPTION_STACK_OVERFLOW\n");
break;
default:
re_fprintf(stderr, "Error: Unrecognized Exception\n");
break;
}

fflush(stderr);

return EXCEPTION_EXECUTE_HANDLER;
}
#endif


/**
* Initialise main library
*
Expand All @@ -21,6 +145,18 @@ int libre_init(void)
{
int err;

#if defined(HAVE_SIGNAL)
if (exception_btrace) {
(void)signal(SIGSEGV, signal_handler);
(void)signal(SIGABRT, signal_handler);
(void)signal(SIGILL, signal_handler);
}
#elif defined(WIN32)
if (exception_btrace) {
SetUnhandledExceptionFilter(exception_handler);
}
#endif

#ifdef USE_OPENSSL
err = openssl_init();
if (err)
Expand Down Expand Up @@ -48,3 +184,12 @@ void libre_close(void)
net_sock_close();
re_thread_close();
}


/**
* Enable/Disable exception signal handling (SIGSEGV, SIGABRT, SIGILL...)
*/
void libre_exception_btrace(bool enable)
{
exception_btrace = enable;
}
3 changes: 3 additions & 0 deletions test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,10 @@ int main(int argc, char *argv[])

dbg_init(DBG_INFO, flags);


/* Initialise library */
libre_exception_btrace(true);

err = libre_init();
if (err)
goto out;
Expand Down

0 comments on commit 53d76d0

Please sign in to comment.