Home
Developer Resources
QNX RTOS v4
QNX RTOS v4 Knowledge Base

QNX RTOS v4 Knowledge Base

Foundry27
Foundry27
QNX RTOS v4 project
Resources

QNX RTOS v4 Knowledge Base

Title Capturing SIGSEGV's in code in QNX4
Ref. No. QNX.000010013
Category(ies) Development
Issue When an application crashes it generates a SIGSEGV, is there a way to capture this signal so the application doesn't crash?

Solution Yes, the following code example shows how this can be done.

#include <signal.h>
#include <sys/sigcontext.h>  /* follows if you don't have it in your system */

void catch(int signo, SIGCONTEXT *scp)
{
        printf("death by signal %u at 0x%lxn", signo, scp->sc_ip);
        exit(1);
}


//The fields:
        ulong_t  sc_info;      /* fault specific info */
        ushort_t  sc_errc;      /* error code pushed by processor */
        uchar_t  sc_fault;      /* actual fault # */
        uchar_t  sc_flags;      /* signal handler flags: */
//are only available in QNX 4.24 and above, as is the sigaltstack() et al...


#ifndef sigcont_h
#define sigcont_h 1


#ifndef __TYPES_H_INCLUDED
#include <sys/types.h>
#endif

typedef struct _sigcontext SIGCONTEXT;
struct _sigcontext {
        ulong_t  sc_mask;
        ulong_t  sc_gs:16,:16; /* register set at fault time */
        ulong_t  sc_fs:16,:16;
        ulong_t  sc_es:16,:16;
        ulong_t  sc_ds:16,:16;
        ulong_t  sc_di;
        ulong_t  sc_si;
        ulong_t  sc_bp;
        ulong_t  :32;          /* hole from pushad */
        ulong_t  sc_bx;
        ulong_t  sc_dx;
        ulong_t  sc_cx;
        ulong_t  sc_ax;
        ulong_t  sc_ip;
        ulong_t  sc_cs:16, :16;
        ulong_t  sc_fl;
        ulong_t  sc_sp;
        ulong_t  sc_ss:16, :16;
        ulong_t  sc_info;      /* fault specific info */
        ushort_t  sc_errc;      /* error code pushed by processor */
        uchar_t  sc_fault;      /* actual fault # */
        uchar_t  sc_flags;      /* signal handler flags: */
#define SC_ONSTACK 1
};

enum {
        TRAP_ZDIV    = 0,    /* SIGFPE:  divide by zero */
        TRAP_DEBUG  = 1,    /* SIGTRAP: debug fault    */
        TRAP_NMI    = 2,    /* SGIBUS:  nmi fault      */
        TRAP_BRKPT  = 3,    /* SIGTRAP: cpu breakpoint */
        TRAP_OFLOW  = 4,    /* SIGFPE:  integer overflow*/
        TRAP_BOUNDS  = 5,    /* SIGFPE:  bound instn failed*/
        TRAP_BADOP  = 6,    /* SIGILL:  invalid opcode */
        TRAP_NONDP  = 7,    /* SIGFPE:  NDP not present or available */
        TRAP_DFAULT  = 8,    /* never:  double fault (system error) */
        TRAP_NDPSEGV = 9,    /* SIGSEGV: NDP invalid address */
        TRAP_BADTSS  = 10,  /* never:  invalid tss  (system error) */
        TRAP_NOTPRESENT=11,  /* SIGSEGV: referenced segment not preset */
        TRAP_NOSTACK = 12,  /* SIGSEGV: esp|ebp bad address */
        TRAP_GPF    = 13,  /* SIGSEGV: other */
        TRAP_PAGE    = 14,  /* SIGSEGV: page fault */
        TRAP_FPERROR = 16,  /* SIGFPE:  floating point error */
};


#define __ERRC_VALID (1<<TRAP_DFAULT | 1<<TRAP_BADTSS |
        1<<TRAP_NOTPRESENT | 1<<TRAP_NOSTACK | 1<<TRAP_GPF | 1<<TRAP_PAGE )

#define __INFO_VALID (1<<TRAP_PAGE)


#endif