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