summaryrefslogtreecommitdiffstats
blob: 2ce14dd2b4decbd380fcac5fd39195c4922814b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
#define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_

#include <windows.h>
#include <dbghelp.h>
#include <string>
#include <utility>
#include "client/windows/common/ipc_protocol.h"
#include "processor/scoped_ptr.h"

namespace google_breakpad {

struct CustomClientInfo;

// Abstraction of client-side implementation of out of process
// crash generation.
//
// The process that desires to have out-of-process crash dump
// generation service can use this class in the following way:
//
// * Create an instance.
// * Call Register method so that the client tries to register
//   with the server process and check the return value. If
//   registration is not successful, out-of-process crash dump
//   generation will not be available
// * Request dump generation by calling either of the two
//   overloaded RequestDump methods - one in case of exceptions
//   and the other in case of assertion failures
//
// Note that it is the responsibility of the client code of
// this class to set the unhandled exception filter with the
// system by calling the SetUnhandledExceptionFilter function
// and the client code should explicitly request dump generation.
class CrashGenerationClient {
 public:
  CrashGenerationClient(const wchar_t* pipe_name,
                        MINIDUMP_TYPE dump_type,
                        const CustomClientInfo* custom_info);

  CrashGenerationClient(HANDLE pipe_handle,
                        MINIDUMP_TYPE dump_type,
                        const CustomClientInfo* custom_info);

  ~CrashGenerationClient();

  // Registers the client process with the crash server.
  //
  // Returns true if the registration is successful; false otherwise.
  bool Register();

  // Requests the crash server to upload a previous dump with the
  // given crash id.
  bool RequestUpload(DWORD crash_id);

  bool RequestDump(EXCEPTION_POINTERS* ex_info,
                   MDRawAssertionInfo* assert_info);

  // Requests the crash server to generate a dump with the given
  // exception information.
  //
  // Returns true if the dump was successful; false otherwise. Note that
  // if the registration step was not performed or it was not successful,
  // false will be returned.
  bool RequestDump(EXCEPTION_POINTERS* ex_info);

  // Requests the crash server to generate a dump with the given
  // assertion information.
  //
  // Returns true if the dump was successful; false otherwise. Note that
  // if the registration step was not performed or it was not successful,
  // false will be returned.
  bool RequestDump(MDRawAssertionInfo* assert_info);

  // If the crash generation client is running in a sandbox that prevents it
  // from opening the named pipe directly, the server process may open the
  // handle and duplicate it into the client process with this helper method.
  // Returns INVALID_HANDLE_VALUE on failure. The process must have been opened
  // with the PROCESS_DUP_HANDLE access right.
  static HANDLE DuplicatePipeToClientProcess(const wchar_t* pipe_name,
                                             HANDLE hProcess);

 private:
  // Connects to the appropriate pipe and sets the pipe handle state.
  //
  // Returns the pipe handle if everything goes well; otherwise Returns NULL.
  HANDLE ConnectToServer();

  // Performs a handshake with the server over the given pipe which should be
  // already connected to the server.
  //
  // Returns true if handshake with the server was successful; false otherwise.
  bool RegisterClient(HANDLE pipe);

  // Validates the given server response.
  bool ValidateResponse(const ProtocolMessage& msg) const;

  // Returns true if the registration step succeeded; false otherwise.
  bool IsRegistered() const;

  // Connects to the given named pipe with given parameters.
  //
  // Returns true if the connection is successful; false otherwise.
  HANDLE ConnectToPipe(const wchar_t* pipe_name,
                       DWORD pipe_access,
                       DWORD flags_attrs);

  // Signals the crash event and wait for the server to generate crash.
  bool SignalCrashEventAndWait();

  // Pipe name to use to talk to server.
  std::wstring pipe_name_;

  // Pipe handle duplicated from server process. Only valid before
  // Register is called.
  HANDLE pipe_handle_;

  // Custom client information
  CustomClientInfo custom_info_;

  // Type of dump to generate.
  MINIDUMP_TYPE dump_type_;

  // Event to signal in case of a crash.
  HANDLE crash_event_;

  // Handle to wait on after signaling a crash for the server
  // to finish generating crash dump.
  HANDLE crash_generated_;

  // Handle to a mutex that will become signaled with WAIT_ABANDONED
  // if the server process goes down.
  HANDLE server_alive_;

  // Server process id.
  DWORD server_process_id_;

  // Id of the thread that caused the crash.
  DWORD thread_id_;

  // Exception pointers for an exception crash.
  EXCEPTION_POINTERS* exception_pointers_;

  // Assertion info for an invalid parameter or pure call crash.
  MDRawAssertionInfo assert_info_;

  // Disable copy ctor and operator=.
  CrashGenerationClient(const CrashGenerationClient& crash_client);
  CrashGenerationClient& operator=(const CrashGenerationClient& crash_client);
};

}  // namespace google_breakpad

#endif  // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_