| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 1 |  | 
|  | 2 | //#include <cutils/misc.h> | 
|  | 3 |  | 
|  | 4 | #include <unistd.h> | 
|  | 5 | #include <stdio.h> | 
|  | 6 | #include <stdlib.h> | 
|  | 7 | #include <string.h> | 
|  | 8 | #include <sched.h> | 
|  | 9 | #include <errno.h> | 
|  | 10 |  | 
|  | 11 | #include <signal.h> | 
|  | 12 | #include <sys/ptrace.h> | 
|  | 13 | #include <sys/wait.h> | 
|  | 14 | #include <sys/socket.h> | 
|  | 15 |  | 
|  | 16 | #include <pthread.h> | 
|  | 17 |  | 
|  | 18 | #include <cutils/sockets.h> | 
|  | 19 |  | 
|  | 20 | void crash1(void); | 
|  | 21 | void crashnostack(void); | 
| Bruce Beare | 8492490 | 2010-10-13 14:21:30 -0700 | [diff] [blame] | 22 | void maybeabort(void); | 
| Elliott Hughes | aa42130 | 2012-12-10 14:15:42 -0800 | [diff] [blame] | 23 | int do_action(const char* arg); | 
| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 24 |  | 
|  | 25 | static void debuggerd_connect() | 
|  | 26 | { | 
|  | 27 | char tmp[1]; | 
|  | 28 | int s; | 
|  | 29 | sprintf(tmp, "%d", gettid()); | 
|  | 30 | s = socket_local_client("android:debuggerd", | 
|  | 31 | ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); | 
|  | 32 | if(s >= 0) { | 
|  | 33 | read(s, tmp, 1); | 
|  | 34 | close(s); | 
|  | 35 | } | 
|  | 36 | } | 
|  | 37 |  | 
|  | 38 | void test_call1() | 
|  | 39 | { | 
|  | 40 | *((int*) 32) = 1; | 
|  | 41 | } | 
|  | 42 |  | 
|  | 43 | void *test_thread(void *x) | 
|  | 44 | { | 
|  | 45 | printf("crasher: thread pid=%d tid=%d\n", getpid(), gettid()); | 
|  | 46 |  | 
|  | 47 | sleep(1); | 
|  | 48 | test_call1(); | 
|  | 49 | printf("goodbye\n"); | 
|  | 50 |  | 
|  | 51 | return 0; | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | void *noisy(void *x) | 
|  | 55 | { | 
|  | 56 | char c = (unsigned) x; | 
|  | 57 | for(;;) { | 
|  | 58 | usleep(250*1000); | 
|  | 59 | write(2, &c, 1); | 
|  | 60 | if(c == 'C') *((unsigned*) 0) = 42; | 
|  | 61 | } | 
|  | 62 | return 0; | 
|  | 63 | } | 
|  | 64 |  | 
|  | 65 | int ctest() | 
|  | 66 | { | 
|  | 67 | pthread_t thr; | 
|  | 68 | pthread_attr_t attr; | 
|  | 69 | pthread_attr_init(&attr); | 
|  | 70 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 
|  | 71 | pthread_create(&thr, &attr, noisy, (void*) 'A'); | 
|  | 72 | pthread_create(&thr, &attr, noisy, (void*) 'B'); | 
|  | 73 | pthread_create(&thr, &attr, noisy, (void*) 'C'); | 
|  | 74 | for(;;) ; | 
|  | 75 | return 0; | 
|  | 76 | } | 
|  | 77 |  | 
| Elliott Hughes | aa42130 | 2012-12-10 14:15:42 -0800 | [diff] [blame] | 78 | static void* thread_callback(void* raw_arg) | 
| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 79 | { | 
| Elliott Hughes | aa42130 | 2012-12-10 14:15:42 -0800 | [diff] [blame] | 80 | return (void*) do_action((const char*) raw_arg); | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | int do_action_on_thread(const char* arg) | 
|  | 84 | { | 
|  | 85 | pthread_t t; | 
|  | 86 | pthread_create(&t, NULL, thread_callback, (void*) arg); | 
|  | 87 | void* result = NULL; | 
|  | 88 | pthread_join(t, &result); | 
|  | 89 | return (int) result; | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | int do_action(const char* arg) | 
|  | 93 | { | 
|  | 94 | if(!strncmp(arg, "thread-", strlen("thread-"))) { | 
|  | 95 | return do_action_on_thread(arg + strlen("thread-")); | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | if(!strcmp(arg,"nostack")) crashnostack(); | 
|  | 99 | if(!strcmp(arg,"ctest")) return ctest(); | 
|  | 100 | if(!strcmp(arg,"exit")) exit(1); | 
|  | 101 | if(!strcmp(arg,"abort")) maybeabort(); | 
|  | 102 |  | 
| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 103 | pthread_t thr; | 
|  | 104 | pthread_attr_t attr; | 
| Elliott Hughes | aa42130 | 2012-12-10 14:15:42 -0800 | [diff] [blame] | 105 | pthread_attr_init(&attr); | 
|  | 106 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 
|  | 107 | pthread_create(&thr, &attr, test_thread, 0); | 
|  | 108 | while(1) sleep(1); | 
|  | 109 | } | 
| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 110 |  | 
| Elliott Hughes | aa42130 | 2012-12-10 14:15:42 -0800 | [diff] [blame] | 111 | int main(int argc, char **argv) | 
|  | 112 | { | 
|  | 113 | fprintf(stderr,"crasher: built at " __TIME__ "!@\n"); | 
| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 114 | fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid()); | 
|  | 115 |  | 
|  | 116 | if(argc > 1) { | 
| Elliott Hughes | aa42130 | 2012-12-10 14:15:42 -0800 | [diff] [blame] | 117 | return do_action(argv[1]); | 
| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 118 | } else { | 
|  | 119 | crash1(); | 
|  | 120 | //        *((int*) 0) = 42; | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | return 0; | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | void maybeabort() | 
|  | 127 | { | 
|  | 128 | if(time(0) != 42) abort(); | 
|  | 129 | } |