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#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
31315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
32315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
33c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com#include <stdint.h>
34c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com
35315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include <string>
36315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
37315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#include "common/mac/MachIPC.h"
38315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
39315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comnamespace google_breakpad {
40315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
41315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comclass ClientInfo;
42315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
43315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com// Messages the server can read via its mach port
44315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comenum {
45315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  kDumpRequestMessage     = 1,
46315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  kAcknowledgementMessage = 2,
47315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  kQuitMessage            = 3
48315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com};
49315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
5014889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com// Exception details sent by the client when requesting a dump.
5114889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.comstruct ExceptionInfo {
52c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  int32_t exception_type;
53c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  int32_t exception_code;
54c45b12b4225be716eba98f8305eebe36b2b19dbbted.mielczarek@gmail.com  int32_t exception_subcode;
5514889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com};
5614889c340ffe6edeb362232318a8723a96b43a22ted.mielczarek@gmail.com
57315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.comclass CrashGenerationServer {
58315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com public:
59315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // WARNING: callbacks may be invoked on a different thread
60315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // than that which creates the CrashGenerationServer.  They must
61315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // be thread safe.
62315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  typedef void (*OnClientDumpRequestCallback)(void *context,
63315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                                              const ClientInfo &client_info,
64315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                                              const std::string &file_path);
65315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
66315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  typedef void (*OnClientExitingCallback)(void *context,
67315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                                          const ClientInfo &client_info);
688426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  // If a FilterCallback returns false, the dump will not be written.
698426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  typedef bool (*FilterCallback)(void *context);
70315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
71315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Create an instance with the given parameters.
72315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  //
73315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // mach_port_name: Named server port to listen on.
748426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  // filter: Callback for a client to cancel writing a dump.
758426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  // filter_context: Context for the filter callback.
76315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // dump_callback: Callback for a client crash dump request.
77315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // dump_context: Context for client crash dump request callback.
78315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // exit_callback: Callback for client process exit.
79315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // exit_context: Context for client exit callback.
80315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // generate_dumps: Whether to automatically generate dumps.
81315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  //     Client code of this class might want to generate dumps explicitly
82315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  //     in the crash dump request callback. In that case, false can be
83315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  //     passed for this parameter.
84315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // dump_path: Path for generating dumps; required only if true is
85315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  //     passed for generateDumps parameter; NULL can be passed otherwise.
86315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer(const char *mach_port_name,
878426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                        FilterCallback filter,
888426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek                        void *filter_context,
89315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                        OnClientDumpRequestCallback dump_callback,
90315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                        void *dump_context,
91315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                        OnClientExitingCallback exit_callback,
92315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                        void *exit_context,
93315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                        bool generate_dumps,
94315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com                        const std::string &dump_path);
95315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
96315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ~CrashGenerationServer();
97315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
98315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Perform initialization steps needed to start listening to clients.
99315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  //
100315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Return true if initialization is successful; false otherwise.
101315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool Start();
102315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
103315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Stop the server.
104315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool Stop();
105315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
106315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com private:
107315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Return a unique filename at which a minidump can be written.
108315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool MakeMinidumpFilename(std::string &outFilename);
109315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
110315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Loop reading client messages and responding to them until
111315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // a quit message is received.
112315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  static void *WaitForMessages(void *server);
113315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
114315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Wait for a single client message and respond to it. Returns false
115315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // if a quit message was received or if an error occurred.
116315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool WaitForOneMessage();
117315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
1188426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  FilterCallback filter_;
1198426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek  void *filter_context_;
1208426a3587056399d74114e4fc7e6d9b658966ab9ted.mielczarek
121315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  OnClientDumpRequestCallback dump_callback_;
122315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  void *dump_context_;
123315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
124315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  OnClientExitingCallback exit_callback_;
125315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  void *exit_context_;
126315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
127315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool generate_dumps_;
128315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
129315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  std::string dump_dir_;
130315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
131315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  bool started_;
132315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
133315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // The mach port that receives requests to dump from child processes.
134315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  ReceivePort receive_port_;
135315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
136315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // The name of the mach port. Stored so the Stop method can message
137315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // the background thread to shut it down.
138315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  std::string mach_port_name_;
139315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
140315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // The thread that waits on the receive port.
141315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  pthread_t server_thread_;
142315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
143315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  // Disable copy constructor and operator=.
144315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer(const CrashGenerationServer&);
145315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com  CrashGenerationServer& operator=(const CrashGenerationServer&);
146315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com};
147315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
148315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com}  // namespace google_breakpad
149315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com
150315fd78199bc606ee02cb085dacadd58e0fc40c8ted.mielczarek@gmail.com#endif  // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
151