1// Copyright (c) 2011, 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// crash_generator.h: Define the google_breakpad::CrashGenerator class,
31// which is used to generate a crash (and a core dump file) for testing.
32
33#ifndef COMMON_LINUX_TESTS_CRASH_GENERATOR_H_
34#define COMMON_LINUX_TESTS_CRASH_GENERATOR_H_
35
36#include <sys/resource.h>
37
38#include <string>
39
40#include "common/tests/auto_tempdir.h"
41#include "common/using_std_string.h"
42
43namespace google_breakpad {
44
45// A utility class for generating a crash (and a core dump file) for
46// testing. It creates a child process with the specified number of
47// threads, which is then termainated by the specified signal. A core
48// dump file is expected to be created upon the termination of the child
49// process, which can then be used for testing code that processes core
50// dump files.
51class CrashGenerator {
52 public:
53  CrashGenerator();
54
55  ~CrashGenerator();
56
57  // Returns true if a core dump file named 'core' will be generated in
58  // the current directory for a test that produces a crash by checking
59  // if /proc/sys/kernel/core_pattern has the default value 'core'.
60  bool HasDefaultCorePattern() const;
61
62  // Returns the expected path of the core dump file.
63  string GetCoreFilePath() const;
64
65  // Returns the directory of a copy of proc files of the child process.
66  string GetDirectoryOfProcFilesCopy() const;
67
68  // Creates a crash (and a core dump file) by creating a child process with
69  // |num_threads| threads, and the terminating the child process by sending
70  // a signal with number |crash_signal| to the |crash_thread|-th thread.
71  // Returns true on success.
72  bool CreateChildCrash(unsigned num_threads, unsigned crash_thread,
73                        int crash_signal, pid_t* child_pid);
74
75  // Returns the thread ID of the |index|-th thread in the child process.
76  // This method does not validate |index|.
77  pid_t GetThreadId(unsigned index) const;
78
79 private:
80  // Copies the following proc files of the process with |pid| to the directory
81  // at |path|: auxv, cmdline, environ, maps, status
82  // The directory must have been created. Returns true on success.
83  bool CopyProcFiles(pid_t pid, const char* path) const;
84
85  // Creates |num_threads| threads in the child process.
86  void CreateThreadsInChildProcess(unsigned num_threads);
87
88  // Sets the maximum size of core dump file (both the soft and hard limit)
89  // to |limit| bytes. Returns true on success.
90  bool SetCoreFileSizeLimit(rlim_t limit) const;
91
92  // Creates a shared memory of |memory_size| bytes for communicating thread
93  // IDs between the parent and child process. Returns true on success.
94  bool MapSharedMemory(size_t memory_size);
95
96  // Releases any shared memory created by MapSharedMemory(). Returns true on
97  // success.
98  bool UnmapSharedMemory();
99
100  // Returns the pointer to the thread ID of the |index|-th thread in the child
101  // process. This method does not validate |index|.
102  pid_t* GetThreadIdPointer(unsigned index);
103
104  // Temporary directory in which a core file is generated.
105  AutoTempDir temp_dir_;
106
107  // Shared memory for communicating thread IDs between the parent and
108  // child process.
109  void* shared_memory_;
110
111  // Number of bytes mapped for |shared_memory_|.
112  size_t shared_memory_size_;
113};
114
115}  // namespace google_breakpad
116
117#endif  // COMMON_LINUX_TESTS_CRASH_GENERATOR_H_
118