crasher.c revision af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//#include <cutils/misc.h> 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sched.h> 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <signal.h> 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ptrace.h> 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/wait.h> 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pthread.h> 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/sockets.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid crash1(void); 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid crashnostack(void); 22849249064cae9c1bb23b0204b5d35b832567801eBruce Bearevoid maybeabort(void); 23aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughesint do_action(const char* arg); 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void debuggerd_connect() 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[1]; 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s; 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(tmp, "%d", gettid()); 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = socket_local_client("android:debuggerd", 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s >= 0) { 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project read(s, tmp, 1); 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(s); 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughesint smash_stack(int i) { 39df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes printf("crasher: deliberately corrupting stack...\n"); 40df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes // Unless there's a "big enough" buffer on the stack, gcc 41df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes // doesn't bother inserting checks. 42df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes char buf[8]; 43df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes // If we don't write something relatively unpredicatable 44df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes // into the buffer and then do something with it, gcc 45df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes // optimizes everything away and just returns a constant. 46df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes *(int*)(&buf[7]) = (uintptr_t) &buf[0]; 47df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes return *(int*)(&buf[0]); 48df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes} 49df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid test_call1() 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *((int*) 32) = 1; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *test_thread(void *x) 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("crasher: thread pid=%d tid=%d\n", getpid(), gettid()); 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sleep(1); 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project test_call1(); 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("goodbye\n"); 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *noisy(void *x) 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char c = (unsigned) x; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usleep(250*1000); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project write(2, &c, 1); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(c == 'C') *((unsigned*) 0) = 42; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ctest() 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_t thr; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_attr_t attr; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_attr_init(&attr); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_create(&thr, &attr, noisy, (void*) 'A'); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_create(&thr, &attr, noisy, (void*) 'B'); 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_create(&thr, &attr, noisy, (void*) 'C'); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) ; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughesstatic void* thread_callback(void* raw_arg) 91aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes{ 92aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes return (void*) do_action((const char*) raw_arg); 93aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes} 94aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes 95aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughesint do_action_on_thread(const char* arg) 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 97aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes pthread_t t; 98aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes pthread_create(&t, NULL, thread_callback, (void*) arg); 99aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes void* result = NULL; 100aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes pthread_join(t, &result); 101aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes return (int) result; 102aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes} 103aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes 104af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin__attribute__((noinline)) int crash3(int a) { 105af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin *((int*) 0xdead) = a; 106af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin return a*4; 107af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin} 108af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin 109af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin__attribute__((noinline)) int crash2(int a) { 110af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin a = crash3(a) + 2; 111af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin return a*3; 112af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin} 113af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin 114af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin__attribute__((noinline)) int crash(int a) { 115af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin a = crash2(a) + 1; 116af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin return a*2; 117af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin} 118af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin 119aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughesint do_action(const char* arg) 120aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes{ 121aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes if(!strncmp(arg, "thread-", strlen("thread-"))) { 122aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes return do_action_on_thread(arg + strlen("thread-")); 123aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes } 124aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes 125df4200e8c255fca1d03855b971b57036b9ccaa94Elliott Hughes if(!strcmp(arg,"smash-stack")) return smash_stack(42); 126aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes if(!strcmp(arg,"nostack")) crashnostack(); 127aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes if(!strcmp(arg,"ctest")) return ctest(); 128aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes if(!strcmp(arg,"exit")) exit(1); 129af2cb3667ba24d1ef3037aa5a7b3bc0a238cf040Pavel Chupin if(!strcmp(arg,"crash")) return crash(42); 130aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes if(!strcmp(arg,"abort")) maybeabort(); 131aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_t thr; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_attr_t attr; 134aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes pthread_attr_init(&attr); 135aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 136aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes pthread_create(&thr, &attr, test_thread, 0); 137aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes while(1) sleep(1); 138aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes} 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 140aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughesint main(int argc, char **argv) 141aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes{ 142aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes fprintf(stderr,"crasher: built at " __TIME__ "!@\n"); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid()); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc > 1) { 146aa4213057ba1723e4f164e54f80bb7621c3cb6b3Elliott Hughes return do_action(argv[1]); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project crash1(); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// *((int*) 0) = 42; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid maybeabort() 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(time(0) != 42) abort(); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 159