1133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner/* 2133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * Copyright (C) 2010 The Android Open Source Project 3133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * All rights reserved. 4133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * 5133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * Redistribution and use in source and binary forms, with or without 6133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * modification, are permitted provided that the following conditions 7133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * are met: 8133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * * Redistributions of source code must retain the above copyright 9133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * notice, this list of conditions and the following disclaimer. 10133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * * Redistributions in binary form must reproduce the above copyright 11133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * notice, this list of conditions and the following disclaimer in 12133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * the documentation and/or other materials provided with the 13133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * distribution. 14133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * 15133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * SUCH DAMAGE. 27133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner */ 28133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner#include <stdio.h> 29133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner#include <unistd.h> 30133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner#include <errno.h> 31133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner#include <string.h> 32133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner#include <sys/wait.h> 33133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner#include <sys/resource.h> 34133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 35133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner/* A very simple program used to test constructor and destructor functions 36133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * in executables (instead of shared libraries). 37133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner */ 38133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 39133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnerint x = 0; 40133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 41133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner/* Initialize x to 1 when the program starts. This will be checked 42133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * later by the main() function. 43133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner */ 44133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnerstatic void __attribute__((constructor)) 45133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turneron_load(void) 46133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner{ 47133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner x = 1; 48133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner} 49133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 50133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner/* Crash intentionally if 'x' is set to 1 */ 51133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnerstatic void __attribute__((destructor)) 52133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turneron_exit(void) 53133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner{ 54133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (x == 1) 55133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner *(int*)(void*)0 = 10; /* force a crash */ 56133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner} 57133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 58133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnerint main(void) 59133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner{ 60133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner int status; 61133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner pid_t pid; 62133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 63133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* First, check that the constructor was properly called ! */ 64133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (x != 1) { 65133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Constructor function not called!!\n"); 66133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 1; 67133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner } 68133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 69133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* prevent our crashing child process from generating a core file */ 70133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner { 71133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner struct rlimit rlim; 72133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner rlim.rlim_cur = 0; 73133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner rlim.rlim_max = RLIM_INFINITY; 74133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner setrlimit(RLIMIT_CORE, &rlim); 75133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner } 76133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 77133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* Fork the current process, then wait for the child to exit 78133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner * and crash. 79133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner */ 80133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner pid = fork(); 81133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (pid < 0) { 82133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Could not fork process: %s\n", strerror(errno)); 83133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 2; 84133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner } 85133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* in the child, simply exit after 1 second. */ 86133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (pid == 0) { 87133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner sleep(1); 88133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 0; 89133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner } 90133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* in the parent, wait for the child to terminate */ 91133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (wait(&status) < 0) { 92133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Could not wait for child: %s\n", strerror(errno)); 93133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 3; 94133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner } 95133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (!WIFSIGNALED(status)) { 96133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Destructor not called!!\n"); 97133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 4; 98133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner } 99133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner 100133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* Prevent crashing */ 101133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner x = 2; 102133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner printf("ok\n"); 103133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 0; 104133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner} 105