crash_generation_server_test.cc revision 14889c340ffe6edeb362232318a8723a96b43a22
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"
46315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "client/mac/tests/auto_tempdir.h"
47315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
48315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comnamespace {
49315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing std::string;
50315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::AutoTempDir;
51315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::ClientInfo;
52315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::CrashGenerationClient;
53315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::CrashGenerationServer;
54315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing google_breakpad::ExceptionHandler;
55315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comusing testing::Test;
56315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
57315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comclass CrashGenerationServerTest : public Test {
58315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.compublic:
59315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // The port name to receive messages on
60315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  char mach_port_name[128];
61315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Filename of the last dump that was generated
62315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  string last_dump_name;
6314889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  // PID of the child process
6414889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  pid_t child_pid;
65315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // A temp dir
66315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  AutoTempDir temp_dir;
67315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Counter just to ensure that we don't hit the same port again
68315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  static int i;
69315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
70315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  void SetUp() {
71315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    sprintf(mach_port_name,
72315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com	    "com.google.breakpad.ServerTest.%d.%d", getpid(),
73315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com	    CrashGenerationServerTest::i++);
7414889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com    child_pid = (pid_t)-1;
75315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
76315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com};
77315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comint CrashGenerationServerTest::i = 0;
78315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
79315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that starting and stopping a server works
80315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testStartStopServer) {
81315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
82315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // dump callback
83315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // dump context
84315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit callback
85315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit context
86315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       false, // generate dumps
87315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       ""); // dump path
88315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
89315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Stop());
90315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
91315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
92315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that requesting a dump via CrashGenerationClient works
93315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test without actually dumping
94315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testRequestDumpNoDump) {
95315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
96315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // dump callback
97315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // dump context
98315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit callback
99315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit context
100315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       false, // don't generate dumps
101315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       temp_dir.path); // dump path
102315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
103315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
104315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pid_t pid = fork();
105315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
106315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (pid == 0) {
107315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    CrashGenerationClient client(mach_port_name);
108315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    bool result = client.RequestDump();
109315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    exit(result ? 0 : 1);
110315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
111315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
112315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int ret;
113315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
114315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(WIFEXITED(ret));
115315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, WEXITSTATUS(ret));
116315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
117315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // check that no minidump was written
118315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  string pattern = temp_dir.path + "/*";
119315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  glob_t dirContents;
120315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ret = glob(pattern.c_str(), GLOB_NOSORT, NULL, &dirContents);
121315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(GLOB_NOMATCH, ret);
122315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (ret != GLOB_NOMATCH)
123315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    globfree(&dirContents);
124315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
125315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
126315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comvoid dumpCallback(void *context, const ClientInfo &client_info,
127315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com		  const std::string &file_path) {
128315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (context) {
129315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    CrashGenerationServerTest* self =
130315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com        reinterpret_cast<CrashGenerationServerTest*>(context);
131315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    if (!file_path.empty())
132315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com      self->last_dump_name = file_path;
13314889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com    self->child_pid = client_info.pid();
134315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
135315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
136315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
137315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comvoid *RequestDump(void *context) {
138315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationClient client((const char*)context);
139315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool result = client.RequestDump();
140315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  return (void*)(result ? 0 : 1);
141315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
142315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
143315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that actually writing a minidump works
144315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testRequestDump) {
145315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
146315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       dumpCallback,  // dump callback
147315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       this,  // dump context
148315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit callback
149315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit context
150315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       true, //  generate dumps
151315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       temp_dir.path); // dump path
152315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
153315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
154315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pid_t pid = fork();
155315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
156315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (pid == 0) {
157315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // Have to spawn off a separate thread to request the dump,
158315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // because MinidumpGenerator assumes the handler thread is not
159315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // the only thread
160315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    pthread_t thread;
161315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    if (pthread_create(&thread, NULL, RequestDump, (void*)mach_port_name) != 0)
162315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com      exit(1);
163315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    void* result;
164315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    pthread_join(thread, &result);
165315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    exit(reinterpret_cast<intptr_t>(result));
166315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
167315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
168315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int ret;
169315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
170315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(WIFEXITED(ret));
171315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, WEXITSTATUS(ret));
172315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
173315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // check that minidump was written
174315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_FALSE(last_dump_name.empty());
175315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  struct stat st;
176315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
17714889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  EXPECT_LT(0, st.st_size);
17814889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  // check client's PID
17914889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com  ASSERT_EQ(pid, child_pid);
180315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
181315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
182315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comstatic void Crasher() {
183315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int *a = (int*)0x42;
184315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
185315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  fprintf(stdout, "Going to crash...\n");
186315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  fprintf(stdout, "A = %d", *a);
187315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
188315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
189315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Test that crashing a child process with an OOP ExceptionHandler installed
190315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// results in a minidump being written by the CrashGenerationServer in
191315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// the parent.
192315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comTEST_F(CrashGenerationServerTest, testChildProcessCrash) {
193315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer server(mach_port_name,
194315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       dumpCallback,  // dump callback
195315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       this,  // dump context
196315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit callback
197315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       NULL,  // exit context
198315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       true, //  generate dumps
199315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com			       temp_dir.path); // dump path
200315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_TRUE(server.Start());
201315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
202315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pid_t pid = fork();
203315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_NE(-1, pid);
204315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  if (pid == 0) {
205315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // Instantiate an OOP exception handler.
206315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name);
207315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    Crasher();
208315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    // not reached
209315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com    exit(0);
210315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  }
211315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
212315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  int ret;
213315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_EQ(pid, waitpid(pid, &ret, 0));
214315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_FALSE(WIFEXITED(ret));
215315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_TRUE(server.Stop());
216315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // check that minidump was written
217315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ASSERT_FALSE(last_dump_name.empty());
218315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  struct stat st;
219315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
220315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  EXPECT_LT(0, st.st_size);
221315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}
222315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
223315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}  // namespace
224