1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #include <stdio.h> 29 #include <unistd.h> 30 #include <errno.h> 31 #include <string.h> 32 #include <sys/wait.h> 33 #include <sys/resource.h> 34 35 /* A very simple program used to test constructor and destructor functions 36 * in executables (instead of shared libraries). 37 */ 38 39 int x = 0; 40 41 /* Initialize x to 1 when the program starts. This will be checked 42 * later by the main() function. 43 */ 44 static void __attribute__((constructor)) 45 on_load(void) 46 { 47 x = 1; 48 } 49 50 /* Crash intentionally if 'x' is set to 1 */ 51 static void __attribute__((destructor)) 52 on_exit(void) 53 { 54 if (x == 1) 55 *(int*)(void*)0 = 10; /* force a crash */ 56 } 57 58 int main(void) 59 { 60 int status; 61 pid_t pid; 62 63 /* First, check that the constructor was properly called ! */ 64 if (x != 1) { 65 fprintf(stderr, "Constructor function not called!!\n"); 66 return 1; 67 } 68 69 /* prevent our crashing child process from generating a core file */ 70 { 71 struct rlimit rlim; 72 rlim.rlim_cur = 0; 73 rlim.rlim_max = RLIM_INFINITY; 74 setrlimit(RLIMIT_CORE, &rlim); 75 } 76 77 /* Fork the current process, then wait for the child to exit 78 * and crash. 79 */ 80 pid = fork(); 81 if (pid < 0) { 82 fprintf(stderr, "Could not fork process: %s\n", strerror(errno)); 83 return 2; 84 } 85 /* in the child, simply exit after 1 second. */ 86 if (pid == 0) { 87 sleep(1); 88 return 0; 89 } 90 /* in the parent, wait for the child to terminate */ 91 if (wait(&status) < 0) { 92 fprintf(stderr, "Could not wait for child: %s\n", strerror(errno)); 93 return 3; 94 } 95 if (!WIFSIGNALED(status)) { 96 fprintf(stderr, "Destructor not called!!\n"); 97 return 4; 98 } 99 100 /* Prevent crashing */ 101 x = 2; 102 printf("ok\n"); 103 return 0; 104 } 105