1315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Copyright (c) 2010, Google Inc.
2315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// All rights reserved.
3315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//
4315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Redistribution and use in source and binary forms, with or without
5315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// modification, are permitted provided that the following conditions are
6315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// met:
7315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//
8315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//     * Redistributions of source code must retain the above copyright
9315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// notice, this list of conditions and the following disclaimer.
10315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//     * Redistributions in binary form must reproduce the above
11315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// copyright notice, this list of conditions and the following disclaimer
12315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// in the documentation and/or other materials provided with the
13315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// distribution.
14315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//     * Neither the name of Google Inc. nor the names of its
15315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// contributors may be used to endorse or promote products derived from
16315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// this software without specific prior written permission.
17315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//
18315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com//
30315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// crash_generation_server_test.cc
31315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Unit tests for CrashGenerationServer
32315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
33315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <dirent.h>
34315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <glob.h>
35315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <stdint.h>
36315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <sys/wait.h>
37315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <unistd.h>
38315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
39315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <string>
40315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
41315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "breakpad_googletest_includes.h"
42315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "client/mac/crash_generation/client_info.h"
43315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "client/mac/crash_generation/crash_generation_client.h"
44315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "client/mac/crash_generation/crash_generation_server.h"
45315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "client/mac/handler/exception_handler.h"
46c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#include "client/mac/tests/spawn_child_process.h"
47b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org#include "common/tests/auto_tempdir.h"
48c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#include "google_breakpad/processor/minidump.h"
49c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
50c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comnamespace google_breakpad {
51c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com// This acts as the log sink for INFO logging from the processor
52c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com// logging code. The logging output confuses XCode and makes it think
53c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com// there are unit test failures. testlogging.h handles the overriding.
54c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comstd::ostringstream info_log;
55c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com}
56315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
57315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comnamespace {
58315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing std::string;
59315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::AutoTempDir;
60315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::ClientInfo;
61315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::CrashGenerationClient;
62315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::CrashGenerationServer;
63315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::ExceptionHandler;
64c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::Minidump;
65c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpContext;
66c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpException;
67c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpModule;
68c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpModuleList;
69c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpSystemInfo;
70c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpThread;
71c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing google_breakpad::MinidumpThreadList;
72315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing testing::Test;
73c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comusing namespace google_breakpad_test;
74315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
75315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comclass CrashGenerationServerTest : public Test {
76315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.compublic:
77315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // The port name to receive messages on
78315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  char mach_port_name[128];
79315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Filename of the last dump that was generated
80315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  string last_dump_name;
8114889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  // PID of the child process
8214889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  pid_t child_pid;
83315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // A temp dir
84315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  AutoTempDir temp_dir;
85315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Counter just to ensure that we don't hit the same port again
86315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  static int i;
878426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  bool filter_callback_called;
88315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
89315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  void SetUp() {
90315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    sprintf(mach_port_name,
918426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek            "com.google.breakpad.ServerTest.%d.%d", getpid(),
928426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek            CrashGenerationServerTest::i++);
9314889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com    child_pid = (pid_t)-1;
948426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    filter_callback_called = false;
95315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
96315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com};
97315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comint CrashGenerationServerTest::i = 0;
98315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
99315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that starting and stopping a server works
100315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testStartStopServer) {
101315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
1028426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter callback
1038426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter context
1048426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // dump callback
1058426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // dump context
1068426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // exit callback
1078426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // exit context
1088426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               false, // generate dumps
1098426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               ""); // dump path
110315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
111315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Stop());
112315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
113315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
114315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that requesting a dump via CrashGenerationClient works
115315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test without actually dumping
116315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testRequestDumpNoDump) {
117315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
1188426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter callback
1198426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter context
120b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // dump callback
121b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // dump context
122b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit callback
123b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit context
124b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               false, // don't generate dumps
125b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               temp_dir.path()); // dump path
126315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
127315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
128315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pid_t pid = fork();
129315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
130315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (pid == 0) {
131315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    CrashGenerationClient client(mach_port_name);
132315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    bool result = client.RequestDump();
133315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    exit(result ? 0 : 1);
134315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
135315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
136315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int ret;
137315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
138315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(WIFEXITED(ret));
139315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, WEXITSTATUS(ret));
140315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
141315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // check that no minidump was written
142b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org  string pattern = temp_dir.path() + "/*";
143315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  glob_t dirContents;
144315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ret = glob(pattern.c_str(), GLOB_NOSORT, NULL, &dirContents);
145315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(GLOB_NOMATCH, ret);
146315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (ret != GLOB_NOMATCH)
147315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    globfree(&dirContents);
148315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
149315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
150315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comvoid dumpCallback(void *context, const ClientInfo &client_info,
1518426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                  const std::string &file_path) {
152315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (context) {
153315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    CrashGenerationServerTest* self =
154315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com        reinterpret_cast<CrashGenerationServerTest*>(context);
155315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    if (!file_path.empty())
156315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com      self->last_dump_name = file_path;
15714889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com    self->child_pid = client_info.pid();
158315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
159315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
160315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
161315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comvoid *RequestDump(void *context) {
162315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationClient client((const char*)context);
163315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool result = client.RequestDump();
164315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  return (void*)(result ? 0 : 1);
165315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
166315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
167315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that actually writing a minidump works
168315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testRequestDump) {
169315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
1708426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter callback
1718426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter context
172b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               dumpCallback,  // dump callback
173b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               this,  // dump context
174b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit callback
175b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit context
176b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               true, //  generate dumps
177b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               temp_dir.path()); // dump path
178315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
179315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
180315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pid_t pid = fork();
181315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
182315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (pid == 0) {
183315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // Have to spawn off a separate thread to request the dump,
184315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // because MinidumpGenerator assumes the handler thread is not
185315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // the only thread
186315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    pthread_t thread;
187315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    if (pthread_create(&thread, NULL, RequestDump, (void*)mach_port_name) != 0)
188315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com      exit(1);
189315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    void* result;
190315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    pthread_join(thread, &result);
191315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    exit(reinterpret_cast<intptr_t>(result));
192315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
193315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
194315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int ret;
195315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
196315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(WIFEXITED(ret));
197315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, WEXITSTATUS(ret));
198315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
199315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // check that minidump was written
200315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_FALSE(last_dump_name.empty());
201315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  struct stat st;
202315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
20314889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  EXPECT_LT(0, st.st_size);
20414889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  // check client's PID
20514889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  ASSERT_EQ(pid, child_pid);
206315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
207315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
208315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comstatic void Crasher() {
209315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int *a = (int*)0x42;
210315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
211315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  fprintf(stdout, "Going to crash...\n");
212315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  fprintf(stdout, "A = %d", *a);
213315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
214315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
215315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that crashing a child process with an OOP ExceptionHandler installed
216315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// results in a minidump being written by the CrashGenerationServer in
217315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// the parent.
218315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testChildProcessCrash) {
219315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
2208426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter callback
2218426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter context
222b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               dumpCallback,  // dump callback
223b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               this,  // dump context
224b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit callback
225b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit context
226b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               true, //  generate dumps
227b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               temp_dir.path()); // dump path
228315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
229315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
230315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pid_t pid = fork();
231315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
232315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (pid == 0) {
233315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // Instantiate an OOP exception handler.
234315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name);
235315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    Crasher();
236315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // not reached
237315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    exit(0);
238315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
239315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
240315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int ret;
241315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
242315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_FALSE(WIFEXITED(ret));
243315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
244315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // check that minidump was written
245315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_FALSE(last_dump_name.empty());
246315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  struct stat st;
247315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
248c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_LT(0, st.st_size);
249c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
250c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  // Read the minidump, sanity check some data.
251c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  Minidump minidump(last_dump_name.c_str());
252c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(minidump.Read());
253c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
254c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpSystemInfo* system_info = minidump.GetSystemInfo();
255c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(system_info);
256c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  const MDRawSystemInfo* raw_info = system_info->system_info();
257c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(raw_info);
258c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(kNativeArchitecture, raw_info->processor_architecture);
259c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
260c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpThreadList* thread_list = minidump.GetThreadList();
261c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(thread_list);
262c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_EQ((unsigned int)1, thread_list->thread_count());
263c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
264c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0);
265c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(main_thread);
266c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpContext* context = main_thread->GetContext();
267c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(context);
268c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(kNativeContext, context->GetContextCPU());
269c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
270c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpModuleList* module_list = minidump.GetModuleList();
271c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(module_list);
272c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  const MinidumpModule* main_module = module_list->GetMainModule();
273c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(main_module);
274c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(GetExecutablePath(), main_module->code_file());
275c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com}
276c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
277c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) && \
278c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  (defined(__x86_64__) || defined(__i386__))
279c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com// Test that crashing a child process of a different architecture
280c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com// produces a valid minidump.
281c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testChildProcessCrashCrossArchitecture) {
282c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
2838426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter callback
2848426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // filter context
285b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               dumpCallback,  // dump callback
286b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               this,  // dump context
287b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit callback
288b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               NULL,  // exit context
289b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               true, //  generate dumps
290b12089f06d061d1ae393f208d37dc17e003d21c4qsr@chromium.org                               temp_dir.path()); // dump path
291c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
292c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
293c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  // Spawn a child process
294c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  string helper_path = GetHelperPath();
295c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  const char* argv[] = {
296c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com    helper_path.c_str(),
297c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com    "crash",
298c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com    mach_port_name,
299c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com    NULL
300c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  };
301c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  pid_t pid = spawn_child_process(argv);
302c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
303c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
304c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  int ret;
305c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
306c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_FALSE(WIFEXITED(ret));
307c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
308c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  // check that minidump was written
309c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_FALSE(last_dump_name.empty());
310c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  struct stat st;
311c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
312c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_LT(0, st.st_size);
313c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
314c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.comconst MDCPUArchitecture kExpectedArchitecture =
315c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#if defined(__x86_64__)
316c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MD_CPU_ARCHITECTURE_X86
317c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#elif defined(__i386__)
318c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MD_CPU_ARCHITECTURE_AMD64
319c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#endif
320c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ;
3216162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint32_t kExpectedContext =
322c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#if defined(__i386__)
323c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MD_CONTEXT_AMD64
324c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#elif defined(__x86_64__)
325c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MD_CONTEXT_X86
326c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#endif
327c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ;
328c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
329c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  // Read the minidump, sanity check some data.
330c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  Minidump minidump(last_dump_name.c_str());
331c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(minidump.Read());
332c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
333c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpSystemInfo* system_info = minidump.GetSystemInfo();
334c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(system_info);
335c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  const MDRawSystemInfo* raw_info = system_info->system_info();
336c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(raw_info);
337c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(kExpectedArchitecture, raw_info->processor_architecture);
338c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
339c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpThreadList* thread_list = minidump.GetThreadList();
340c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(thread_list);
341c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_EQ((unsigned int)1, thread_list->thread_count());
342c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
343c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0);
344c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(main_thread);
345c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpContext* context = main_thread->GetContext();
346c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(context);
347c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(kExpectedContext, context->GetContextCPU());
348c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
349c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  MinidumpModuleList* module_list = minidump.GetModuleList();
350c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(module_list);
351c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  const MinidumpModule* main_module = module_list->GetMainModule();
352c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  ASSERT_TRUE(main_module);
353c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  EXPECT_EQ(helper_path, main_module->code_file());
354315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
355c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#endif
356315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
3578426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarekbool filter_callback(void* context) {
3588426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  CrashGenerationServerTest* self =
3598426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    reinterpret_cast<CrashGenerationServerTest*>(context);
3608426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  self->filter_callback_called = true;
3618426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  // veto dump generation
3628426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  return false;
3638426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek}
3648426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek
3658426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek// Test that a filter callback can veto minidump writing.
3668426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarekTEST_F(CrashGenerationServerTest, testFilter) {
3678426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  CrashGenerationServer server(mach_port_name,
3688426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               filter_callback,  // filter callback
3698426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               this,            // filter context
3708426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               dumpCallback,  // dump callback
3718426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               this,  // dump context
3728426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // exit callback
3738426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               NULL,  // exit context
3748426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               true, //  generate dumps
3758426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                               temp_dir.path()); // dump path
3768426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  ASSERT_TRUE(server.Start());
3778426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek
3788426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  pid_t pid = fork();
3798426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  ASSERT_NE(-1, pid);
3808426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  if (pid == 0) {
3818426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    // Instantiate an OOP exception handler.
3828426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name);
3838426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    Crasher();
3848426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    // not reached
3858426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek    exit(0);
3868426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  }
3878426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek
3888426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  int ret;
3898426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
3908426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  EXPECT_FALSE(WIFEXITED(ret));
3918426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  EXPECT_TRUE(server.Stop());
3928426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek
3938426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  // check that no minidump was written
3948426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  EXPECT_TRUE(last_dump_name.empty());
3958426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  EXPECT_TRUE(filter_callback_called);
3968426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek}
3978426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek
398315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}  // namespace
399