1 /* Test the dispatcher.
2 Copyright (C) 2002-2006, 2008 Bruno Haible <bruno@clisp.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
25 #if HAVE_SIGSEGV_RECOVERY
30 static sigsegv_dispatcher dispatcher
;
32 static volatile unsigned int logcount
= 0;
33 static volatile unsigned long logdata
[10];
36 area_handler (void *fault_address
, void *user_arg
)
38 unsigned long area
= *(unsigned long *)user_arg
;
39 logdata
[logcount
++] = area
;
40 if (logcount
>= sizeof (logdata
) / sizeof (logdata
[0]))
42 if (!((unsigned long)fault_address
>= area
43 && (unsigned long)fault_address
- area
< 0x4000))
45 if (mprotect ((void *) area
, 0x4000, PROT_READ_WRITE
) == 0)
51 handler (void *fault_address
, int serious
)
53 return sigsegv_dispatch (&dispatcher
, fault_address
);
70 #if !HAVE_MMAP_ANON && !HAVE_MMAP_ANONYMOUS && HAVE_MMAP_DEVZERO
71 zero_fd
= open ("/dev/zero", O_RDONLY
, 0644);
73 sigsegv_init (&dispatcher
);
74 sigsegv_install_handler (&handler
);
76 /* Setup some mmaped memory. */
78 p
= mmap_zeromap ((void *) 0x12340000, 0x4000);
79 if (p
== (void *)(-1))
81 fprintf (stderr
, "mmap_zeromap failed.\n");
84 area1
= (unsigned long) p
;
85 sigsegv_register (&dispatcher
, (void *) area1
, 0x4000, &area_handler
, &area1
);
86 if (mprotect ((void *) area1
, 0x4000, PROT_NONE
) < 0)
88 fprintf (stderr
, "mprotect failed.\n");
92 p
= mmap_zeromap ((void *) 0x0BEE0000, 0x4000);
93 if (p
== (void *)(-1))
95 fprintf (stderr
, "mmap_zeromap failed.\n");
98 area2
= (unsigned long) p
;
99 sigsegv_register (&dispatcher
, (void *) area2
, 0x4000, &area_handler
, &area2
);
100 if (mprotect ((void *) area2
, 0x4000, PROT_READ
) < 0)
102 fprintf (stderr
, "mprotect failed.\n");
105 if (mprotect ((void *) area2
, 0x4000, PROT_READ_WRITE
) < 0
106 || mprotect ((void *) area2
, 0x4000, PROT_READ
) < 0)
108 fprintf (stderr
, "mprotect failed.\n");
112 p
= mmap_zeromap ((void *) 0x06990000, 0x4000);
113 if (p
== (void *)(-1))
115 fprintf (stderr
, "mmap_zeromap failed.\n");
118 area3
= (unsigned long) p
;
119 sigsegv_register (&dispatcher
, (void *) area3
, 0x4000, &area_handler
, &area3
);
120 mprotect ((void *) area3
, 0x4000, PROT_READ
);
122 /* This access should call the handler. */
123 ((volatile int *)area2
)[230] = 22;
124 /* This access should call the handler. */
125 ((volatile int *)area3
)[412] = 33;
126 /* This access should not give a signal. */
127 ((volatile int *)area2
)[135] = 22;
128 /* This access should call the handler. */
129 ((volatile int *)area1
)[612] = 11;
133 /* Check that the handler was called three times. */
136 if (!(logdata
[0] == area2
&& logdata
[1] == area3
&& logdata
[2] == area1
))
138 printf ("Test passed.\n");