Address of instruction causing SIGSEGV
From: Jeroen N. Witmond (jnw_at_xs4all.nl)
Date: 08/24/04
- Next message: dnewbold: "driver receives wrong inode from kernal"
- Previous message: TenThumbs: "Re: Why is the stack pointer always the same?"
- Next in thread: Tuukka Toivonen: "Re: Address of instruction causing SIGSEGV"
- Reply: Tuukka Toivonen: "Re: Address of instruction causing SIGSEGV"
- Reply: John Reiser: "Re: Address of instruction causing SIGSEGV"
- Reply: Ulrich Weigand: "Re: Address of instruction causing SIGSEGV"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 24 Aug 2004 07:11:56 -0700
This has been asked some times before, but I haven't found a single
answer that says it all. In my signal handler for SIGSEGV, I need to
determine the address of the instruction that caused the SIGSEGV. This
address is not the one found in siginfo.si_addr, as the latter is the
address of the memory that could not be accessed, and not of the
instruction referencing that address in memory.
>From a number of posts in a number of newsgroups, I gathered that the
address of the instruction causing the SIGSEGV could be found in
sigcontext.cr2. I also found references to field eip in the same
structure. A small program (see below) showed that cr2 equals zero and
eip contains something that could well be the address of the
instruction causing the SIGSEGV.
Questions:
- Is sigcontext.eip the correct field to look for the address of the
instruction causing the SIGSEGV?
- Is using an undeclared and undocumented parameter of the handler
(and a cast of the handler's address to sighandler_t to kill gcc's
warnings) the only way to access struct sigcontext?
- I am currently working with kernels 2.4.19 and 2.4.20. Does kernel
2.6 behave differently in this area? Does this behaviour depend on
other components, for instance libc?
- Is there a better newsgroup to ask these questions?
Thanks in advance,
Jeroen.
<cut here>
/* sigsegvhandler.c : Try to get address of instruction causing
SIGSEGV. */
#define _GNU_SOURCE
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <string.h>
static int sigCaught;
static struct sigcontext sigContext;
static jmp_buf afterError;
static void sigcontextAction(int sig, struct sigcontext ctx)
{
sigCaught = sig;
sigContext = ctx;
longjmp(afterError, 1);
}
int main()
{
struct sigaction sigAction;
memset(&sigAction, 0, sizeof(sigAction));
sigAction.sa_handler = (sighandler_t)sigcontextAction;
sigaction(SIGSEGV, &sigAction, 0);
if (setjmp(afterError) == 0) {
/* Cause a SIGSEGV. */
int* invalid = 0;
*invalid = 0;
return 4; /* We should NOT get here. */
}
else {
/* Show information about the signal caught. */
printf("%s:%d: Cought signal %d, eip=0x%lx, cr2=0x%lx.\n",
__FILE__, __LINE__, sigCaught, sigContext.eip, sigContext.cr2);
return 0;
}
}
- Next message: dnewbold: "driver receives wrong inode from kernal"
- Previous message: TenThumbs: "Re: Why is the stack pointer always the same?"
- Next in thread: Tuukka Toivonen: "Re: Address of instruction causing SIGSEGV"
- Reply: Tuukka Toivonen: "Re: Address of instruction causing SIGSEGV"
- Reply: John Reiser: "Re: Address of instruction causing SIGSEGV"
- Reply: Ulrich Weigand: "Re: Address of instruction causing SIGSEGV"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|