Could some kind soul tell me how can a SIGSEGV signal handler
determine the memory location that caused the violation?
The following program should demonstrate this (on Linux 1.2.13). I wrote
this a while back when I was tracking down a memory fault triggered by cpp,
and wanted to know the exact memory location of the fault, the code
sequence, and a stack trace.
Leonard
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#define __KERNEL__
#include <signal.h>
#undef __KERNEL__
static void FatalSignalHandler(int SignalNumber,
struct sigcontext_struct SignalContext)
{
unsigned char *CodePointer;
unsigned long *StackPointer;
int i;
fprintf(stderr, "\n*** Signal %d Received ***\n", SignalNumber);
fprintf(stderr, "gs = %X, __gsh = %X\n",
SignalContext.gs, SignalContext.__gsh);
fprintf(stderr, "fs = %X, __fsh = %X\n",
SignalContext.fs, SignalContext.__fsh);
fprintf(stderr, "es = %X, __esh = %X\n",
SignalContext.es, SignalContext.__esh);
fprintf(stderr, "ds = %X, __dsh = %X\n",
SignalContext.ds, SignalContext.__dsh);
fprintf(stderr, "edi = %X\n", SignalContext.edi);
fprintf(stderr, "esi = %X\n", SignalContext.esi);
fprintf(stderr, "ebp = %X\n", SignalContext.ebp);
fprintf(stderr, "esp = %X\n", SignalContext.esp);
fprintf(stderr, "ebx = %X\n", SignalContext.ebx);
fprintf(stderr, "edx = %X\n", SignalContext.edx);
fprintf(stderr, "ecx = %X\n", SignalContext.ecx);
fprintf(stderr, "eax = %X\n", SignalContext.eax);
fprintf(stderr, "trapno = %X\n", SignalContext.trapno);
fprintf(stderr, "err = %X\n", SignalContext.err);
fprintf(stderr, "eip = %X\n", SignalContext.eip);
fprintf(stderr, "cs = %X, __csh = %X\n",
SignalContext.cs, SignalContext.__csh);
fprintf(stderr, "eflags = %X\n", SignalContext.eflags);
fprintf(stderr, "esp_at_signal = %X\n", SignalContext.esp_at_signal);
fprintf(stderr, "ss = %X, __ssh = %X\n",
SignalContext.ss, SignalContext.__ssh);
fprintf(stderr, "i387 = %X\n", SignalContext.i387);
fprintf(stderr, "oldmask = %X\n", SignalContext.oldmask);
fprintf(stderr, "cr2 = %X\n", SignalContext.cr2);
CodePointer = (unsigned char *) SignalContext.eip;
fprintf(stderr, "%X/", CodePointer);
for (i = 0; i < 20; i++)
fprintf(stderr, " %02X", *CodePointer++);
fprintf(stderr, "\n");
StackPointer = (unsigned long *) 0xC0000000;
while (--StackPointer >= (unsigned long *) SignalContext.esp_at_signal)
fprintf(stderr, "%08X/ %08X\n", StackPointer, *StackPointer);
Quote:}
int main(int ArgCount, char *ArgVector[], char *Environment[])
{
signal(SIGINT, (void (*)(int)) FatalSignalHandler);
signal(SIGTERM, (void (*)(int)) FatalSignalHandler);
sigpause(0);
return 0;
Quote:}