/ src / client / solaris / handler / exception_handler_test.cc
exception_handler_test.cc
  1  // Copyright 2007 Google LLC
  2  //
  3  // Redistribution and use in source and binary forms, with or without
  4  // modification, are permitted provided that the following conditions are
  5  // met:
  6  //
  7  //     * Redistributions of source code must retain the above copyright
  8  // notice, this list of conditions and the following disclaimer.
  9  //     * Redistributions in binary form must reproduce the above
 10  // copyright notice, this list of conditions and the following disclaimer
 11  // in the documentation and/or other materials provided with the
 12  // distribution.
 13  //     * Neither the name of Google LLC nor the names of its
 14  // contributors may be used to endorse or promote products derived from
 15  // this software without specific prior written permission.
 16  //
 17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28  
 29  // Author: Alfred Peng
 30  
 31  #ifdef HAVE_CONFIG_H
 32  #include <config.h>  // Must come first
 33  #endif
 34  
 35  #include <pthread.h>
 36  #include <unistd.h>
 37  
 38  #include <cassert>
 39  #include <cstdio>
 40  #include <cstdlib>
 41  #include <cstring>
 42  
 43  #include "client/solaris/handler/exception_handler.h"
 44  #include "client/solaris/handler/solaris_lwp.h"
 45  
 46  using namespace google_breakpad;
 47  
 48  // Thread use this to see if it should stop working.
 49  static bool should_exit = false;
 50  
 51  static int foo2(int arg) {
 52    // Stack variable, used for debugging stack dumps.
 53    int c = 0xcccccccc;
 54    fprintf(stderr, "Thread trying to crash: %x\n", getpid());
 55    c = *reinterpret_cast<int*>(0x5);
 56    return c;
 57  }
 58  
 59  static int foo(int arg) {
 60    // Stack variable, used for debugging stack dumps.
 61    int b = 0xbbbbbbbb;
 62    b = foo2(b);
 63    return b;
 64  }
 65  
 66  static void* thread_crash(void*) {
 67    // Stack variable, used for debugging stack dumps.
 68    int a = 0xaaaaaaaa;
 69    sleep(3);
 70    a = foo(a);
 71    printf("%x\n", a);
 72    return NULL;
 73  }
 74  
 75  static void* thread_main(void*) {
 76    while (!should_exit)
 77      sleep(1);
 78    return NULL;
 79  }
 80  
 81  static void CreateCrashThread() {
 82    pthread_t h;
 83    pthread_create(&h, NULL, thread_crash, NULL);
 84    pthread_detach(h);
 85  }
 86  
 87  // Create working threads.
 88  static void CreateThread(int num) {
 89    pthread_t h;
 90    for (int i = 0; i < num; ++i) {
 91      pthread_create(&h, NULL, thread_main, NULL);
 92      pthread_detach(h);
 93    }
 94  }
 95  
 96  // Callback when minidump written.
 97  static bool MinidumpCallback(const char* dump_path,
 98                               const char* minidump_id,
 99                               void* context,
100                               bool succeeded) {
101    int index = reinterpret_cast<int>(context);
102    if (index == 0) {
103      should_exit = true;
104      return true;
105    }
106    // Don't process it.
107    return false;
108  }
109  
110  int main(int argc, char* argv[]) {
111    int handler_index = 1;
112    ExceptionHandler handler_ignore(".", NULL, MinidumpCallback,
113                                    (void*)handler_index, true);
114    CreateCrashThread();
115    CreateThread(10);
116  
117    while (true)
118      sleep(20);
119    should_exit = true;
120  
121    return 0;
122  }