SIGSEGV signal handler

SIGSEGV signal handler

Post by Arash Baratl » Wed, 29 Nov 1995 04:00:00

Hi people,

Could some kind soul tell me how can a SIGSEGV signal handler
determine the memory location that caused the violation?

Here is my problem.  I am working on a system that provides
among many things, a virtual distributed shared memory (VDSM)
across a network.  I have an implementation on SunOS and Solaris.
Now I am interested in a Linux port.  However, Linux signal handers,
as defined, do not allow me to do this.

Let me expand my point.  Linux signal handlers have the
following prototype:
        void handler(int signo).
Both SVR4 and 4.3+BSD have augmented this to allow more
flexibility.  That is, some context information also gets
passed to the hander.  For example the following is a valid
signal handler on SunOS:
        void handler(int signo, int code, struct sigcontext *scp).
Similarly, 'struct siginfo' is used in SVR4.

What I exactly need is this:  When a SIGSVEC is raised, I need my
handler to know exactly which memory address was accessed and I
don't know how to do it.

I appreciate any advice, and please reply vi email.



SIGSEGV signal handler

Post by Leonard N. Zubkof » Wed, 29 Nov 1995 04:00:00

  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.


#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.__gsh);
  fprintf(stderr, "fs = %X, __fsh = %X\n",
          SignalContext.fs, SignalContext.__fsh);
  fprintf(stderr, "es = %X, __esh = %X\n",
, 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.__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);


int main(int ArgCount, char *ArgVector[], char *Environment[])
  signal(SIGINT, (void (*)(int)) FatalSignalHandler);
  signal(SIGTERM, (void (*)(int)) FatalSignalHandler);
  return 0;