user972276
user972276

Reputation: 3053

problems with sig handling of SIGSEGV

I have created a signal handler to get called when SIGSEGV is sent. I am using C to write my programs and also using Linux and intel x86 processor. In the sig handler it looks like the si_addr that is passed in through the siginfo_t struct is given the value 0 instead of the value of the address of the instruction causing the problem. I set the SIG_INFO flag in sigaction so idk why this is happening.

Here is some example code:

int main(){
    mprotect(..., PROC_READ | PROC_WRITE /* | PROC_EXEC */);  //cannot execute page

    someMethodOnRestrictedPage();
    //do some stuff
}

void init_sighandler(void) {

    //initialize the sigaction so that sig handler is called when a SIGSEGV is thrown
    struct sigaction * action;

    action = (struct sigaction *) malloc(sizeof(struct sigaction));

    action->sa_sigaction = sighandler;
    sigemptyset (&action->sa_mask);

    action->sa_flags = 0;

    sigaddset(&action->sa_mask, SA_SIGINFO);
    sigaddset(&action->sa_mask, SA_RESTART);

    sigaction(SIGSEGV, action, NULL);
}

void sighandler(int sig, siginfo_t *siginfo, void *ucp){
    printf("%x\n", siginfo->si_addr);   // prints out 0
}

Upvotes: 0

Views: 2090

Answers (1)

moshbear
moshbear

Reputation: 3322

Your .sa_flags has the SA_SIGINFO bit cleared.

Quoting http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigaction.html,

SA_SIGINFO

If cleared and the signal is caught, the signal-catching function will be entered as:

void func(int signo);

where signo is the only argument to the signal catching function. In this case the sa_handler member must be used to describe the signal catching function and the application must not modify the sa_sigaction member.

If SA_SIGINFO is set and the signal is caught, the signal-catching function will be entered as:

void func(int signo, siginfo_t *info, void *context);

where two additional arguments are passed to the signal catching function. The second argument will point to an object of type siginfo_t explaining the reason why the signal was generated; the third argument can be cast to a pointer to an object of type ucontext_t to refer to the receiving process' context that was interrupted when the signal was delivered. In this case the sa_sigaction member must be used to describe the signal catching function and the application must not modify the sa_handler member.

The si_signo member contains the system-generated signal number.

The si_errno member may contain implementation-dependent additional error information; if non-zero, it contains an error number identifying the condition that caused the signal to be generated.

The si_code member contains a code identifying the cause of the signal. If the value of si_code is less than or equal to 0, then the signal was generated by a process and si_pid and si_uid respectively indicate the process ID and the real user ID of the sender. The <signal.h> header description contains information about the signal specific contents of the elements of the siginfo_t type.

--End quote

So sigaction uses .sa_handler if the bit is clear, and .sa_sigaction if the bit is set.

So you have undefined behaviour, since you're reading unwritten arguments.

Set .sa_flags = SA_SIGINFO | ... to rectify the issue.

Upvotes: 1

Related Questions