Fix NULL pointer access classification on AIX 4.
[libsigsegv/ericb.git] / tests / sigsegv2.c
blob39961a6ad450ce788b381db16bc11d09199a99a5
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)
7 any later version.
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. */
18 #ifndef _MSC_VER
19 # include <config.h>
20 #endif
22 #include "sigsegv.h"
23 #include <stdio.h>
25 #if HAVE_SIGSEGV_RECOVERY
27 #include "mmaputil.h"
28 #include <stdlib.h>
30 static sigsegv_dispatcher dispatcher;
32 static volatile unsigned int logcount = 0;
33 static volatile unsigned long logdata[10];
35 static int
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]))
41 abort ();
42 if (!((unsigned long)fault_address >= area
43 && (unsigned long)fault_address - area < 0x4000))
44 abort ();
45 if (mprotect ((void *) area, 0x4000, PROT_READ_WRITE) == 0)
46 return 1;
47 return 0;
50 static int
51 handler (void *fault_address, int serious)
53 return sigsegv_dispatch (&dispatcher, fault_address);
56 static void
57 barrier ()
61 int
62 main ()
64 void *p;
65 unsigned long area1;
66 unsigned long area2;
67 unsigned long area3;
69 /* Preparations. */
70 #if !HAVE_MMAP_ANON && !HAVE_MMAP_ANONYMOUS && HAVE_MMAP_DEVZERO
71 zero_fd = open ("/dev/zero", O_RDONLY, 0644);
72 #endif
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");
82 exit (2);
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");
89 exit (2);
92 p = mmap_zeromap ((void *) 0x0BEE0000, 0x4000);
93 if (p == (void *)(-1))
95 fprintf (stderr, "mmap_zeromap failed.\n");
96 exit (2);
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");
103 exit (2);
105 if (mprotect ((void *) area2, 0x4000, PROT_READ_WRITE) < 0
106 || mprotect ((void *) area2, 0x4000, PROT_READ) < 0)
108 fprintf (stderr, "mprotect failed.\n");
109 exit (2);
112 p = mmap_zeromap ((void *) 0x06990000, 0x4000);
113 if (p == (void *)(-1))
115 fprintf (stderr, "mmap_zeromap failed.\n");
116 exit (2);
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;
131 barrier();
133 /* Check that the handler was called three times. */
134 if (logcount != 3)
135 exit (1);
136 if (!(logdata[0] == area2 && logdata[1] == area3 && logdata[2] == area1))
137 exit (1);
138 printf ("Test passed.\n");
139 return 0;
142 #else
145 main ()
147 return 77;
150 #endif