Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sigaction and ignoring a signal with c in linux environment

Tags:

c

linux

sigaction

I am new to this type of programming, so sorry if my question is trivial. What I am trying to do is to cause a segmentation fault in my program and instead of exiting the program, I want to handle the signal and continue execution after segmentation fault. I wrote a code that seem to be working, I just want to make sure that this is the way to do this. So here is my code.

void myhandle(int mysignal, siginfo_t *si, void* arg)
{
  printf("Signal is %d\n",mysignal);

  ucontext_t *context = (ucontext_t *)arg;
  context->uc_mcontext.gregs[REG_RIP]++;
}


int main(int argc, char *argv[])
{
   struct sigaction action;

  action.sa_handler=myhandle;
  sigaction(11,&action,NULL);

  printf("Before segfault\n");

  int *a=NULL;
  int b=*a;

  printf("I am still alive\n");

  return 0;
}

Can someone explain to me why the printf inside myhandle runs twice ? Also is this code ok ?

Thank you.

like image 936
Saik Avatar asked Mar 13 '23 12:03

Saik


1 Answers

By this example i have modified your code at below way and now it works as you wanted.

#include<stdio.h>
#define __USE_GNU
#include<signal.h>
#include<ucontext.h>

void myhandle(int mysignal, siginfo_t *si, void* arg)
{
  printf("Signal is %d\n",mysignal);

  ucontext_t *context = (ucontext_t *)arg;
  context->uc_mcontext.gregs[REG_RIP] = context->uc_mcontext.gregs[REG_RIP] + 0x04 ;
}


int main(int argc, char *argv[])
{

  struct sigaction action;
  action.sa_sigaction = &myhandle;
  action.sa_flags = SA_SIGINFO;

  sigaction(11,&action,NULL);


  printf("Before segfault\n");

  int *a=NULL;
  int b;
  b =*a;

  printf("I am still alive\n");

  return 0;
}

Output:

jeegar@jeegar:~/stackoverflow$ gcc test1.c
jeegar@jeegar:~/stackoverflow$ ./a.out 
Before segfault
Signal is 11
I am still alive

On further question form OP in commentes. To runtime remove this handler for this signel

void myhandle(int mysignal, siginfo_t *si, void* arg)
{
  printf("Signal is %d\n",mysignal);

if(flag == 0) {
  // Disable the handler
  action.sa_sigaction = SIG_DFL;
  sigaction(11,&action,NULL);
}

if(flag) {
  ucontext_t *context = (ucontext_t *)arg;
  context->uc_mcontext.gregs[REG_RIP] = context-      >uc_mcontext.gregs[REG_RIP] + 0x04 ;
}

}
like image 53
Jeegar Patel Avatar answered Mar 24 '23 05:03

Jeegar Patel