OLD | NEW |
| (Empty) |
1 // Copyright (c) 2008, 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 #ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ | |
31 #define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ | |
32 | |
33 #include <list> | |
34 #include <string> | |
35 #include "client/windows/common/ipc_protocol.h" | |
36 #include "client/windows/crash_generation/minidump_generator.h" | |
37 #include "processor/scoped_ptr.h" | |
38 | |
39 namespace google_breakpad { | |
40 class ClientInfo; | |
41 | |
42 // Abstraction for server side implementation of out-of-process crash | |
43 // generation protocol for Windows platform only. It generates Windows | |
44 // minidump files for client processes that request dump generation. When | |
45 // the server is requested to start listening for clients (by calling the | |
46 // Start method), it creates a named pipe and waits for the clients to | |
47 // register. In response, it hands them event handles that the client can | |
48 // signal to request dump generation. When the clients request dump | |
49 // generation in this way, the server generates Windows minidump files. | |
50 class CrashGenerationServer { | |
51 public: | |
52 typedef void (*OnClientConnectedCallback)(void* context, | |
53 const ClientInfo* client_info); | |
54 | |
55 typedef void (*OnClientDumpRequestCallback)(void* context, | |
56 const ClientInfo* client_info, | |
57 const std::wstring* file_path); | |
58 | |
59 typedef void (*OnClientExitedCallback)(void* context, | |
60 const ClientInfo* client_info); | |
61 | |
62 // Creates an instance with the given parameters. | |
63 // | |
64 // Parameter pipe_name: Name of the Windows named pipe | |
65 // Parameter pipe_sec_attrs Security attributes to set on the pipe. Pass | |
66 // NULL to use default security on the pipe. By default, the pipe created | |
67 // allows Local System, Administrators and the Creator full control and | |
68 // the Everyone group read access on the pipe. | |
69 // Parameter connect_callback: Callback for a new client connection. | |
70 // Parameter connect_context: Context for client connection callback. | |
71 // Parameter crash_callback: Callback for a client crash dump request. | |
72 // Parameter crash_context: Context for client crash dump request callback. | |
73 // Parameter exit_callback: Callback for client process exit. | |
74 // Parameter exit_context: Context for client exit callback. | |
75 // Parameter generate_dumps: Whether to automatically generate dumps. | |
76 // Client code of this class might want to generate dumps explicitly in the | |
77 // crash dump request callback. In that case, false can be passed for this | |
78 // parameter. | |
79 // Parameter dump_path: Path for generating dumps; required only if true is | |
80 // passed for generateDumps parameter; NULL can be passed otherwise. | |
81 CrashGenerationServer(const std::wstring& pipe_name, | |
82 SECURITY_ATTRIBUTES* pipe_sec_attrs, | |
83 OnClientConnectedCallback connect_callback, | |
84 void* connect_context, | |
85 OnClientDumpRequestCallback dump_callback, | |
86 void* dump_context, | |
87 OnClientExitedCallback exit_callback, | |
88 void* exit_context, | |
89 bool generate_dumps, | |
90 const std::wstring* dump_path); | |
91 | |
92 ~CrashGenerationServer(); | |
93 | |
94 // Performs initialization steps needed to start listening to clients. Upon | |
95 // successful return clients may connect to this server's pipe. | |
96 // | |
97 // Returns true if initialization is successful; false otherwise. | |
98 bool Start(); | |
99 | |
100 private: | |
101 // Various states the client can be in during the handshake with | |
102 // the server. | |
103 enum IPCServerState { | |
104 // Server starts in this state. | |
105 IPC_SERVER_STATE_UNINITIALIZED, | |
106 | |
107 // Server is in error state and it cannot serve any clients. | |
108 IPC_SERVER_STATE_ERROR, | |
109 | |
110 // Server starts in this state. | |
111 IPC_SERVER_STATE_INITIAL, | |
112 | |
113 // Server has issued an async connect to the pipe and it is waiting | |
114 // for the connection to be established. | |
115 IPC_SERVER_STATE_CONNECTING, | |
116 | |
117 // Server is connected successfully. | |
118 IPC_SERVER_STATE_CONNECTED, | |
119 | |
120 // Server has issued an async read from the pipe and it is waiting for | |
121 // the read to finish. | |
122 IPC_SERVER_STATE_READING, | |
123 | |
124 // Server is done reading from the pipe. | |
125 IPC_SERVER_STATE_READ_DONE, | |
126 | |
127 // Server has issued an async write to the pipe and it is waiting for | |
128 // the write to finish. | |
129 IPC_SERVER_STATE_WRITING, | |
130 | |
131 // Server is done writing to the pipe. | |
132 IPC_SERVER_STATE_WRITE_DONE, | |
133 | |
134 // Server has issued an async read from the pipe for an ack and it | |
135 // is waiting for the read to finish. | |
136 IPC_SERVER_STATE_READING_ACK, | |
137 | |
138 // Server is done writing to the pipe and it is now ready to disconnect | |
139 // and reconnect. | |
140 IPC_SERVER_STATE_DISCONNECTING | |
141 }; | |
142 | |
143 // | |
144 // Helper methods to handle various server IPC states. | |
145 // | |
146 void HandleErrorState(); | |
147 void HandleInitialState(); | |
148 void HandleConnectingState(); | |
149 void HandleConnectedState(); | |
150 void HandleReadingState(); | |
151 void HandleReadDoneState(); | |
152 void HandleWritingState(); | |
153 void HandleWriteDoneState(); | |
154 void HandleReadingAckState(); | |
155 void HandleDisconnectingState(); | |
156 | |
157 // Prepares reply for a client from the given parameters. | |
158 bool PrepareReply(const ClientInfo& client_info, | |
159 ProtocolMessage* reply) const; | |
160 | |
161 // Duplicates various handles in the ClientInfo object for the client | |
162 // process and stores them in the given ProtocolMessage instance. If | |
163 // creating any handle fails, ProtocolMessage will contain the handles | |
164 // already created successfully, which should be closed by the caller. | |
165 bool CreateClientHandles(const ClientInfo& client_info, | |
166 ProtocolMessage* reply) const; | |
167 | |
168 // Response to the given client. Return true if all steps of | |
169 // responding to the client succeed, false otherwise. | |
170 bool RespondToClient(ClientInfo* client_info); | |
171 | |
172 // Handles a connection request from the client. | |
173 void HandleConnectionRequest(); | |
174 | |
175 // Handles a dump request from the client. | |
176 void HandleDumpRequest(const ClientInfo& client_info); | |
177 | |
178 // Callback for pipe connected event. | |
179 static void CALLBACK OnPipeConnected(void* context, BOOLEAN timer_or_wait); | |
180 | |
181 // Callback for a dump request. | |
182 static void CALLBACK OnDumpRequest(void* context, BOOLEAN timer_or_wait); | |
183 | |
184 // Callback for client process exit event. | |
185 static void CALLBACK OnClientEnd(void* context, BOOLEAN timer_or_wait); | |
186 | |
187 // Releases resources for a client. | |
188 static DWORD WINAPI CleanupClient(void* context); | |
189 | |
190 // Cleans up for the given client. | |
191 void DoCleanup(ClientInfo* client_info); | |
192 | |
193 // Adds the given client to the list of registered clients. | |
194 bool AddClient(ClientInfo* client_info); | |
195 | |
196 // Generates dump for the given client. | |
197 bool GenerateDump(const ClientInfo& client, std::wstring* dump_path); | |
198 | |
199 // Puts the server in a permanent error state and sets a signal such that | |
200 // the state will be immediately entered after the current state transition | |
201 // is complete. | |
202 void EnterErrorState(); | |
203 | |
204 // Puts the server in the specified state and sets a signal such that the | |
205 // state is immediately entered after the current state transition is | |
206 // complete. | |
207 void EnterStateImmediately(IPCServerState state); | |
208 | |
209 // Puts the server in the specified state. No signal will be set, so the state | |
210 // transition will only occur when signaled manually or by completion of an | |
211 // asynchronous IO operation. | |
212 void EnterStateWhenSignaled(IPCServerState state); | |
213 | |
214 // Sync object for thread-safe access to the shared list of clients. | |
215 CRITICAL_SECTION clients_sync_; | |
216 | |
217 // List of clients. | |
218 std::list<ClientInfo*> clients_; | |
219 | |
220 // Pipe name. | |
221 std::wstring pipe_name_; | |
222 | |
223 // Pipe security attributes | |
224 SECURITY_ATTRIBUTES* pipe_sec_attrs_; | |
225 | |
226 // Handle to the pipe used for handshake with clients. | |
227 HANDLE pipe_; | |
228 | |
229 // Pipe wait handle. | |
230 HANDLE pipe_wait_handle_; | |
231 | |
232 // Handle to server-alive mutex. | |
233 HANDLE server_alive_handle_; | |
234 | |
235 // Callback for a successful client connection. | |
236 OnClientConnectedCallback connect_callback_; | |
237 | |
238 // Context for client connected callback. | |
239 void* connect_context_; | |
240 | |
241 // Callback for a client dump request. | |
242 OnClientDumpRequestCallback dump_callback_; | |
243 | |
244 // Context for client dump request callback. | |
245 void* dump_context_; | |
246 | |
247 // Callback for client process exit. | |
248 OnClientExitedCallback exit_callback_; | |
249 | |
250 // Context for client process exit callback. | |
251 void* exit_context_; | |
252 | |
253 // Whether to generate dumps. | |
254 bool generate_dumps_; | |
255 | |
256 // Instance of a mini dump generator. | |
257 scoped_ptr<MinidumpGenerator> dump_generator_; | |
258 | |
259 // State of the server in performing the IPC with the client. | |
260 // Note that since we restrict the pipe to one instance, we | |
261 // only need to keep one state of the server. Otherwise, server | |
262 // would have one state per client it is talking to. | |
263 volatile IPCServerState server_state_; | |
264 | |
265 // Whether the server is shutting down. | |
266 volatile bool shutting_down_; | |
267 | |
268 // Overlapped instance for async I/O on the pipe. | |
269 OVERLAPPED overlapped_; | |
270 | |
271 // Message object used in IPC with the client. | |
272 ProtocolMessage msg_; | |
273 | |
274 // Client Info for the client that's connecting to the server. | |
275 ClientInfo* client_info_; | |
276 | |
277 // Count of clean-up work items that are currently running or are | |
278 // already queued to run. | |
279 volatile LONG cleanup_item_count_; | |
280 | |
281 // Disable copy ctor and operator=. | |
282 CrashGenerationServer(const CrashGenerationServer& crash_server); | |
283 CrashGenerationServer& operator=(const CrashGenerationServer& crash_server); | |
284 }; | |
285 | |
286 } // namespace google_breakpad | |
287 | |
288 #endif // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ | |
OLD | NEW |