也许有点过长,但这里有一些示例代码可以使用:
SIGILL
在没有编译器抱怨的情况下找到一种方法时遇到了一些问题;但至少在 gcc 下工作 - 但又一次......
gcc -Wall -Wextra -pedantic -ggdb -std=c89 -o eigabrt eigabrt.c
#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <signal.h> /* signal() */
#include <unistd.h> /* sleep() */
void explain_sig(int sig)
{
switch (sig) {
case SIGABRT:
printf("SIGABRT (abnormal termination)");
break;
case SIGFPE:
printf("SIGFPE (arithmetic error)");
break;
case SIGILL:
printf("SIGILL (invalid execution)");
break;
case SIGINT:
printf("SIGINT ((asynchronous) interactive attention)");
break;
case SIGSEGV:
printf("SIGSEGV (illegal storage access)");
break;
case SIGTERM:
printf("SIGTERM ((asynchronous) termination request)");
break;
}
}
void my_sigtrap(int sig)
{
printf("\nReceived signal %d, ", sig);
explain_sig(sig);
putchar('\n');
switch (sig) {
case SIGABRT:
break;
case SIGFPE:
printf("Problem with your math\n");
break;
case SIGILL:
exit(sig);
break;
case SIGINT:
printf("Try once more. I dare you.\n");
/* exit(sig); */
break;
case SIGSEGV:
/* Everything is udefined, do not free here */
exit(sig);
break;
case SIGTERM:
break;
}
printf("Restoring to default\n");
signal(sig, SIG_DFL);
}
/*void set_trap(void (*new_fun)(int), void (*signal)(int))*/
void set_trap(int set_sig, void (*new_fun)(int))
{
void (*orig_sig_fun)(int);
orig_sig_fun = signal(set_sig, new_fun);
printf("Setting my own fun for ");
explain_sig(set_sig);
printf("\n -- ");
if (orig_sig_fun == SIG_IGN) {
printf("Was previously ignored.\n");
signal(set_sig, SIG_IGN);
} else if (orig_sig_fun == SIG_DFL) {
printf("Was handled by default.\n");
} else if (orig_sig_fun == SIG_ERR) {
perror("Failed to set signal.\nNo trap\n -- ");
}
}
void my_exit(void)
{
printf("my exit called\n");
}
static const unsigned char insn[4] = { 0xff, 0xff, 0xff, 0xff };
/* ref. switch satement below for how to trigger various signals
* I.e.: $ ./my_prog s , causes SIGSEGV */
int main(int argc, char *argv[])
{
int i = 0;
unsigned char action = 'x'; /* default action, ref switch below */
int loops_b4_act = 1; /* loops before signal is trigged */
int j = 0; /* Used to cause SIGFPE */
void (*sigill)(void) = (char*)insn; /* Used to cause SIGILL */
int *segv; /* Used to cause SIGSEGV */
if (argc > 1)
action = argv[1][0];
printf("Action to trigger: %c\n", action);
atexit(my_exit);
set_trap(SIGABRT, &my_sigtrap);
set_trap(SIGFPE, &my_sigtrap);
set_trap(SIGILL, &my_sigtrap);
set_trap(SIGINT, &my_sigtrap);
set_trap(SIGSEGV, &my_sigtrap);
set_trap(SIGTERM, &my_sigtrap);
setbuf(stdout, NULL); /* Turning off buffering */
putchar('.');
while (1) {
if (i++ == loops_b4_act) {
switch (action) {
case 'a': abort(); break; /* cause SIGABRT */
case 'f': i /= j; break; /* casue SIGFPE */
case 'l': sigill(); break; /* casue SIGILL */
case 'i': raise(SIGINT); break; /* cause SIGINT, or,
* ie: Ctrl+C */
case 's': *segv = i; break; /* casue SIGSEGV */
case 't': raise(SIGTERM); break;/* cause SIGTERM, or,
* ie: kill -15 pid */
case 'x': exit(0); break; /* exit by exit() */
}
}
sleep(1);
putchar('.');
}
return 0;
}