1 /* $OpenBSD: atexit_test.c,v 1.9 2017/07/27 15:08:37 bluhm Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Daniel Hartmeier 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Effort sponsored in part by the Defense Advanced Research Projects 32 * Agency (DARPA) and Air Force Research Laboratory, Air Force 33 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 34 * 35 */ 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <signal.h> 41 #include <unistd.h> 42 43 #include "include/namespace.h" 44 #include "hidden/stdlib.h" 45 #include "stdlib/atexit.h" 46 47 void handle_first(void); 48 void handle_middle(void); 49 void handle_last(void); 50 void handle_invalid(void *); 51 void handle_cleanup(void); 52 void handle_signal(int); 53 54 static int counter; 55 56 int 57 main(int argc, char *argv[]) 58 { 59 int i; 60 61 if (argc != 2 || (strcmp(argv[1], "-valid") && 62 strcmp(argv[1], "-invalid-atexit") && 63 strcmp(argv[1], "-invalid-cleanup"))) { 64 fprintf(stderr, "%s -valid/-invalid-atexit/-invalid-cleanup\n", 65 argv[0]); 66 return (1); 67 } 68 fprintf(stderr, "main()\n"); 69 if (atexit(handle_last)) { 70 perror("atexit(handle_last) failed"); 71 return (1); 72 } 73 for (i = 0; i < 65535; ++i) { 74 if (atexit(handle_middle)) { 75 perror("atexit(handle_middle) failed"); 76 return (1); 77 } 78 } 79 if (atexit(handle_first)) { 80 perror("atexit(handle_first) failed"); 81 return (1); 82 } 83 /* this is supposed to segfault */ 84 if (!strcmp(argv[1], "-invalid-atexit")) { 85 signal(SIGSEGV, handle_signal); 86 __atexit->fns[0].fn_ptr = handle_invalid; 87 } else if (!strcmp(argv[1], "-invalid-cleanup")) { 88 struct atexit *p = __atexit; 89 90 signal(SIGSEGV, handle_signal); 91 while (p != NULL && p->next != NULL) 92 p = p->next; 93 if (p == NULL) 94 fprintf(stderr, "p == NULL, no page found\n"); 95 p->fns[0].fn_ptr = handle_invalid; 96 } 97 __atexit_register_cleanup(handle_cleanup); 98 counter = 0; 99 fprintf(stderr, "main() returns\n"); 100 return (0); 101 } 102 103 void 104 handle_first(void) 105 { 106 fprintf(stderr, "handle_first() counter == %i\n", counter); 107 } 108 109 void 110 handle_middle(void) 111 { 112 counter++; 113 } 114 115 void 116 handle_last(void) 117 { 118 fprintf(stderr, "handle_last() counter == %i\n", counter); 119 } 120 121 void 122 handle_cleanup(void) 123 { 124 fprintf(stderr, "handle_cleanup()\n"); 125 } 126 127 void 128 handle_invalid(void *arg) 129 { 130 fprintf(stderr, "handle_invalid() THIS SHOULD HAVE SEGFAULTED INSTEAD!\n"); 131 } 132 133 void 134 handle_signal(int sigraised) 135 { 136 switch (sigraised) { 137 case SIGSEGV: 138 dprintf(STDERR_FILENO, "SIGSEGV\n"); 139 exit(0); 140 default: 141 dprintf(STDERR_FILENO, "unexpected signal caught\n"); 142 exit(1); 143 } 144 } 145