summaryrefslogtreecommitdiff
path: root/tests/testsig.c
blob: 27ea78c6a9a32e41e24373c81db9d8e4775b6ecb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/ucontext.h>

jmp_buf jmp_env;

void alarm_handler(int sig)
{
    printf("alarm signal=%d\n", sig);
    alarm(1);
}

#ifndef REG_EAX
#define REG_EAX EAX
#define REG_EBX EBX
#define REG_ECX ECX
#define REG_EDX EDX
#define REG_ESI ESI
#define REG_EDI EDI
#define REG_EBP EBP
#define REG_ESP ESP
#define REG_EIP EIP
#define REG_EFL EFL
#endif

void dump_regs(struct ucontext *uc)
{
    printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
           "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
           "EFL=%08x EIP=%08x\n",
           uc->uc_mcontext.gregs[REG_EAX],
           uc->uc_mcontext.gregs[REG_EBX],
           uc->uc_mcontext.gregs[REG_ECX],
           uc->uc_mcontext.gregs[REG_EDX],
           uc->uc_mcontext.gregs[REG_ESI],
           uc->uc_mcontext.gregs[REG_EDI],
           uc->uc_mcontext.gregs[REG_EBP],
           uc->uc_mcontext.gregs[REG_ESP],
           uc->uc_mcontext.gregs[REG_EFL],
           uc->uc_mcontext.gregs[REG_EIP]);
}

void sig_handler(int sig, siginfo_t *info, void *puc)
{
    struct ucontext *uc = puc;

    printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n",
           strsignal(info->si_signo),
           info->si_signo, info->si_errno, info->si_code, 
           (unsigned long)info->si_addr);
    dump_regs(uc);
    longjmp(jmp_env, 1);
}

int v1;

int main(int argc, char **argv)
{
    struct sigaction act;
    int i;
    
    /* test division by zero reporting */
    if (setjmp(jmp_env) == 0) {
        act.sa_sigaction = sig_handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_SIGINFO | SA_ONESHOT;
        sigaction(SIGFPE, &act, NULL);
        
        /* now divide by zero */
        v1 = 0;
        v1 = 2 / v1;
    }

    /* test illegal instruction reporting */
    if (setjmp(jmp_env) == 0) {
        act.sa_sigaction = sig_handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_SIGINFO | SA_ONESHOT;
        sigaction(SIGILL, &act, NULL);
        
        /* now execute an invalid instruction */
        asm volatile("ud2");
    }
    
    /* test SEGV reporting */
    if (setjmp(jmp_env) == 0) {
        act.sa_sigaction = sig_handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_SIGINFO | SA_ONESHOT;
        sigaction(SIGSEGV, &act, NULL);
        
        /* now store in an invalid address */
        *(char *)0x1234 = 1;
    }
    
    act.sa_handler = alarm_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGALRM, &act, NULL);
    alarm(1);
    for(i = 0;i < 2; i++) {
        sleep(1);
    }
    return 0;
}