1*57718be8SEnji Cooper /* $NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /* 4*57718be8SEnji Cooper * Copyright (c) 2008 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 9*57718be8SEnji Cooper * are met: 10*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 15*57718be8SEnji Cooper * 16*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 27*57718be8SEnji Cooper */ 28*57718be8SEnji Cooper 29*57718be8SEnji Cooper /* 30*57718be8SEnji Cooper * Program to test atexit(3) and __cxa_atexit()/__cxa_finalize(). 31*57718be8SEnji Cooper * 32*57718be8SEnji Cooper * Written by Jason R. Thorpe, February 2003. 33*57718be8SEnji Cooper * Public domain. 34*57718be8SEnji Cooper */ 35*57718be8SEnji Cooper 36*57718be8SEnji Cooper #include <sys/cdefs.h> 37*57718be8SEnji Cooper __COPYRIGHT("@(#) Copyright (c) 2008\ 38*57718be8SEnji Cooper The NetBSD Foundation, inc. All rights reserved."); 39*57718be8SEnji Cooper __RCSID("$NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); 40*57718be8SEnji Cooper 41*57718be8SEnji Cooper #include <stdio.h> 42*57718be8SEnji Cooper #include <stdlib.h> 43*57718be8SEnji Cooper #include <signal.h> 44*57718be8SEnji Cooper #include <string.h> 45*57718be8SEnji Cooper #include <unistd.h> 46*57718be8SEnji Cooper 47*57718be8SEnji Cooper extern int __cxa_atexit(void (*func)(void *), void *, void *); 48*57718be8SEnji Cooper extern void __cxa_finalize(void *); 49*57718be8SEnji Cooper 50*57718be8SEnji Cooper static int dso_handle_1; 51*57718be8SEnji Cooper static int dso_handle_2; 52*57718be8SEnji Cooper static int dso_handle_3; 53*57718be8SEnji Cooper 54*57718be8SEnji Cooper static int arg_1; 55*57718be8SEnji Cooper static int arg_2; 56*57718be8SEnji Cooper static int arg_3; 57*57718be8SEnji Cooper 58*57718be8SEnji Cooper static int exiting_state; 59*57718be8SEnji Cooper 60*57718be8SEnji Cooper #define ASSERT(expr) \ 61*57718be8SEnji Cooper do { \ 62*57718be8SEnji Cooper if ((expr) == 0) { \ 63*57718be8SEnji Cooper write(STDERR_FILENO, __func__, strlen(__func__)); \ 64*57718be8SEnji Cooper write(STDERR_FILENO, ": ", 2); \ 65*57718be8SEnji Cooper write(STDERR_FILENO, __STRING(expr), \ 66*57718be8SEnji Cooper strlen(__STRING(expr))); \ 67*57718be8SEnji Cooper write(STDERR_FILENO, "\n", 1); \ 68*57718be8SEnji Cooper my_abort(); \ 69*57718be8SEnji Cooper } \ 70*57718be8SEnji Cooper } while (/*CONSTCOND*/0) 71*57718be8SEnji Cooper 72*57718be8SEnji Cooper #define SUCCESS() \ 73*57718be8SEnji Cooper do { \ 74*57718be8SEnji Cooper write(STDOUT_FILENO, __func__, strlen(__func__)); \ 75*57718be8SEnji Cooper write(STDOUT_FILENO, "\n", 1); \ 76*57718be8SEnji Cooper } while (/*CONSTCOND*/0) 77*57718be8SEnji Cooper 78*57718be8SEnji Cooper static void 79*57718be8SEnji Cooper my_abort(void) 80*57718be8SEnji Cooper { 81*57718be8SEnji Cooper 82*57718be8SEnji Cooper kill(getpid(), SIGABRT); 83*57718be8SEnji Cooper /* NOTREACHED */ 84*57718be8SEnji Cooper } 85*57718be8SEnji Cooper 86*57718be8SEnji Cooper static void 87*57718be8SEnji Cooper cxa_handler_5(void *arg) 88*57718be8SEnji Cooper { 89*57718be8SEnji Cooper static int cxa_handler_5_called; 90*57718be8SEnji Cooper 91*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_1); 92*57718be8SEnji Cooper ASSERT(cxa_handler_5_called == 0); 93*57718be8SEnji Cooper ASSERT(exiting_state == 5); 94*57718be8SEnji Cooper 95*57718be8SEnji Cooper exiting_state--; 96*57718be8SEnji Cooper cxa_handler_5_called = 1; 97*57718be8SEnji Cooper SUCCESS(); 98*57718be8SEnji Cooper } 99*57718be8SEnji Cooper 100*57718be8SEnji Cooper static void 101*57718be8SEnji Cooper cxa_handler_4(void *arg) 102*57718be8SEnji Cooper { 103*57718be8SEnji Cooper static int cxa_handler_4_called; 104*57718be8SEnji Cooper 105*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_1); 106*57718be8SEnji Cooper ASSERT(cxa_handler_4_called == 0); 107*57718be8SEnji Cooper ASSERT(exiting_state == 4); 108*57718be8SEnji Cooper 109*57718be8SEnji Cooper exiting_state--; 110*57718be8SEnji Cooper cxa_handler_4_called = 1; 111*57718be8SEnji Cooper SUCCESS(); 112*57718be8SEnji Cooper } 113*57718be8SEnji Cooper 114*57718be8SEnji Cooper static void 115*57718be8SEnji Cooper cxa_handler_3(void *arg) 116*57718be8SEnji Cooper { 117*57718be8SEnji Cooper static int cxa_handler_3_called; 118*57718be8SEnji Cooper 119*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_2); 120*57718be8SEnji Cooper ASSERT(cxa_handler_3_called == 0); 121*57718be8SEnji Cooper ASSERT(exiting_state == 3); 122*57718be8SEnji Cooper 123*57718be8SEnji Cooper exiting_state--; 124*57718be8SEnji Cooper cxa_handler_3_called = 1; 125*57718be8SEnji Cooper SUCCESS(); 126*57718be8SEnji Cooper } 127*57718be8SEnji Cooper 128*57718be8SEnji Cooper static void 129*57718be8SEnji Cooper cxa_handler_2(void *arg) 130*57718be8SEnji Cooper { 131*57718be8SEnji Cooper static int cxa_handler_2_called; 132*57718be8SEnji Cooper 133*57718be8SEnji Cooper ASSERT(arg == (void *)&arg_3); 134*57718be8SEnji Cooper ASSERT(cxa_handler_2_called == 0); 135*57718be8SEnji Cooper ASSERT(exiting_state == 2); 136*57718be8SEnji Cooper 137*57718be8SEnji Cooper exiting_state--; 138*57718be8SEnji Cooper cxa_handler_2_called = 1; 139*57718be8SEnji Cooper SUCCESS(); 140*57718be8SEnji Cooper } 141*57718be8SEnji Cooper 142*57718be8SEnji Cooper static void 143*57718be8SEnji Cooper normal_handler_1(void) 144*57718be8SEnji Cooper { 145*57718be8SEnji Cooper static int normal_handler_1_called; 146*57718be8SEnji Cooper 147*57718be8SEnji Cooper ASSERT(normal_handler_1_called == 0); 148*57718be8SEnji Cooper ASSERT(exiting_state == 1); 149*57718be8SEnji Cooper 150*57718be8SEnji Cooper exiting_state--; 151*57718be8SEnji Cooper normal_handler_1_called = 1; 152*57718be8SEnji Cooper SUCCESS(); 153*57718be8SEnji Cooper } 154*57718be8SEnji Cooper 155*57718be8SEnji Cooper static void 156*57718be8SEnji Cooper normal_handler_0(void) 157*57718be8SEnji Cooper { 158*57718be8SEnji Cooper static int normal_handler_0_called; 159*57718be8SEnji Cooper 160*57718be8SEnji Cooper ASSERT(normal_handler_0_called == 0); 161*57718be8SEnji Cooper ASSERT(exiting_state == 0); 162*57718be8SEnji Cooper 163*57718be8SEnji Cooper normal_handler_0_called = 1; 164*57718be8SEnji Cooper SUCCESS(); 165*57718be8SEnji Cooper } 166*57718be8SEnji Cooper 167*57718be8SEnji Cooper int 168*57718be8SEnji Cooper main(int argc, char *argv[]) 169*57718be8SEnji Cooper { 170*57718be8SEnji Cooper 171*57718be8SEnji Cooper exiting_state = 5; 172*57718be8SEnji Cooper 173*57718be8SEnji Cooper ASSERT(0 == atexit(normal_handler_0)); 174*57718be8SEnji Cooper ASSERT(0 == atexit(normal_handler_1)); 175*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); 176*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); 177*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); 178*57718be8SEnji Cooper ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); 179*57718be8SEnji Cooper 180*57718be8SEnji Cooper __cxa_finalize(&dso_handle_1); 181*57718be8SEnji Cooper __cxa_finalize(&dso_handle_2); 182*57718be8SEnji Cooper exit(0); 183*57718be8SEnji Cooper } 184