SIGSEGV

Hi,

Is there any way to replace the function that puts out the SIGSEGV message?

I would like to print a little bit more info with the error, like the state
of a few major variables or info on which section of code is executing.

How do you use the current info from SIGSEGV?

TIA

Augie

Catch the signal then syslog or whatever.

Augie Henriques wrote:

Hi,

Is there any way to replace the function that puts out the SIGSEGV message?

I would like to print a little bit more info with the error, like the state
of a few major variables or info on which section of code is executing.

How do you use the current info from SIGSEGV?

TIA

Augie

#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)



static void signal_handler(int sig, SIGCONTEXT *scp ) {

dprintf( -1, “terminating from signal 0x%04X”, sig );

if ( sig == SIGSEGV ) {

dprintf( -1, " terminating SIGSEGV", sig );

dprintf( -1, “ip %04x:%08x fault:%04x”, scp->sc_cs, scp->sc_ip ,
scp->sc_fault );

dprintf( -1, “Overlength %d dropped %d %d”, err_len, rxdropped, rxdrop );

}



#if defined(STACK_SIZE)

stack_check(’*’);

#endif


exit(EXIT_FAILURE);

}

“Dean Douthat” <ddouthat@faac.com> wrote in message
news:3B33B69A.E55E5CE6@faac.com

Catch the signal then syslog or whatever.

Augie Henriques wrote:

Hi,

Is there any way to replace the function that puts out the SIGSEGV
message?

I would like to print a little bit more info with the error, like the
state
of a few major variables or info on which section of code is executing.

How do you use the current info from SIGSEGV?

TIA

Augie

Hi Mario,

Thanks for the reply. A few questions.

“Mario Charest” <mcharest@deletezinformatic.com> wrote in message
news:9h0er0$drf$1@inn.qnx.com

#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 */

I’m not familiar with this statement. What is this?

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)

How do you set the signal_handler to get called? I checked the docs for
signal() and sigaction(), but they both mention signal handlers with one
parameter (int sig). How did you get the signal context to get passed to
the signal handler?

static void signal_handler(int sig, SIGCONTEXT *scp ) {

dprintf( -1, “terminating from signal 0x%04X”, sig );

Where does the dprintf come from? This is not documented in the Watcom
docs, is it?

if ( sig == SIGSEGV ) {

dprintf( -1, " terminating SIGSEGV", sig );

dprintf( -1, “ip %04x:%08x fault:%04x”, scp->sc_cs, scp->sc_ip ,
scp->sc_fault );

dprintf( -1, “Overlength %d dropped %d %d”, err_len, rxdropped, rxdrop );

}



#if defined(STACK_SIZE)

stack_check(’*’);

What does this function do? Where does STACK_SIZE get set/passed from?

#endif


exit(EXIT_FAILURE);

}

“Dean Douthat” <> ddouthat@faac.com> > wrote in message
news:> 3B33B69A.E55E5CE6@faac.com> …
Catch the signal then syslog or whatever.

Augie Henriques wrote:

Hi,

Is there any way to replace the function that puts out the SIGSEGV
message?

I would like to print a little bit more info with the error, like the
state
of a few major variables or info on which section of code is
executing.

How do you use the current info from SIGSEGV?

TIA

Augie
\

TIA

Augie

“Augie Henriques” <augiehenriques@hotmail.com> wrote in message
news:9h7f17$h9h$1@inn.qnx.com

Hi Mario,

Thanks for the reply. A few questions.


ulong_t sc_gs:16,:16; /* register set at fault time */

I’m not familiar with this statement. What is this?

A bit field. sc_gs:16 means the variable is only take up 16 bits and
the ;16 is a nameless space, for padding I guess.

I think the idea here was to be kind of indepedant of packing

ulong sc_gs:16,16:

Will use 4 bytes regardless of packing while

short sc_gs
short sc_gs_pad;

Is risky.



How do you set the signal_handler to get called? I checked the docs for
signal() and sigaction(), but they both mention signal handlers with one
parameter (int sig). How did you get the signal context to get passed to
the signal handler?

As strange as it may sound signal handlers always gets the extra argument
passed.
You will have to cast to prevent warning:

signal ( signal_nb, (void(*)(int)) handler );

I don’t know if this behavior is specific to QNX.

static void signal_handler(int sig, SIGCONTEXT *scp ) {

dprintf( -1, “terminating from signal 0x%04X”, sig );

Sorry quit cut & paste, this is a cover function for printf. Just use
printf and remove the first argument

#if defined(STACK_SIZE)

stack_check(’*’);

What does this function do? Where does STACK_SIZE get set/passed from?


#endif

Again you can forget about this. It’s a function that checks for stack
usage.
I think I got this function from and old post on QUICS. If you are
insterested
I can post them :wink: I find it usefull during development because everytime
the
program terminates it tell me how much of the stack as been used.

Hi Mario.

There still something I don’t understand.

Where does the signal context (_sigcontext) come from? Is this a standard
structure that gets data from the signal?

Where does this data come from? How does it get to the signal context?

Does each app need to define a signal context and somehow pass it to the
signal handler?

Also, is this safe to do in a Photon App?

TIA

Augie

“Augie Henriques” <augiehenriques@hotmail.com> wrote in message
news:9h7lv2$l18$1@inn.qnx.com

Hi Mario.

There still something I don’t understand.

Where does the signal context (_sigcontext) come from?

From the kernel

Is this a standard structure that gets data from the signal?


Where does this data come from? How does it get to the signal context?

Does each app need to define a signal context and somehow pass it to the
signal handler?

No the kernel does it, just like it passes the signal number to the signal
hander.

Signal handler prototypes is:

void signal( int signum);

The signum value is passed by the kernel,libc. However in reality the TRUE
prototypes is

void signal (int signum, SIGCONTEXT *)

The sigcontext has always been there !!! It’s already taken care of and
filled
in. By using the standard prototypes you just didn’t get access to the
pointer.
That’s all.

You don’t have anything to do expect change the prototypes


Also, is this safe to do in a Photon App?

Standard signal rules apply :wink:

Augie