xref: /aosp_15_r20/external/google-breakpad/src/client/windows/crash_generation/crash_generation_server.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2008 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__
30 #define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__
31 
32 #include <list>
33 #include <string>
34 #include "client/windows/common/ipc_protocol.h"
35 #include "client/windows/crash_generation/minidump_generator.h"
36 #include "common/scoped_ptr.h"
37 
38 namespace google_breakpad {
39 class ClientInfo;
40 
41 // Abstraction for server side implementation of out-of-process crash
42 // generation protocol for Windows platform only. It generates Windows
43 // minidump files for client processes that request dump generation. When
44 // the server is requested to start listening for clients (by calling the
45 // Start method), it creates a named pipe and waits for the clients to
46 // register. In response, it hands them event handles that the client can
47 // signal to request dump generation. When the clients request dump
48 // generation in this way, the server generates Windows minidump files.
49 class CrashGenerationServer {
50  public:
51   typedef void (*OnClientConnectedCallback)(void* context,
52                                             const ClientInfo* client_info);
53 
54   typedef void (*OnClientDumpRequestCallback)(void* context,
55                                               const ClientInfo* client_info,
56                                               const std::wstring* file_path);
57 
58   typedef void (*OnClientExitedCallback)(void* context,
59                                          const ClientInfo* client_info);
60 
61   typedef void (*OnClientUploadRequestCallback)(void* context,
62                                                 const DWORD crash_id);
63 
64   // Creates an instance with the given parameters.
65   //
66   // Parameter pipe_name: Name of the Windows named pipe
67   // Parameter pipe_sec_attrs Security attributes to set on the pipe. Pass
68   //     NULL to use default security on the pipe. By default, the pipe created
69   //     allows Local System, Administrators and the Creator full control and
70   //     the Everyone group read access on the pipe.
71   // Parameter connect_callback: Callback for a new client connection.
72   // Parameter connect_context: Context for client connection callback.
73   // Parameter crash_callback: Callback for a client crash dump request.
74   // Parameter crash_context: Context for client crash dump request callback.
75   // Parameter exit_callback: Callback for client process exit.
76   // Parameter exit_context: Context for client exit callback.
77   // Parameter generate_dumps: Whether to automatically generate dumps.
78   // Client code of this class might want to generate dumps explicitly in the
79   // crash dump request callback. In that case, false can be passed for this
80   // parameter.
81   // Parameter dump_path: Path for generating dumps; required only if true is
82   // passed for generateDumps parameter; NULL can be passed otherwise.
83   CrashGenerationServer(const std::wstring& pipe_name,
84                         SECURITY_ATTRIBUTES* pipe_sec_attrs,
85                         OnClientConnectedCallback connect_callback,
86                         void* connect_context,
87                         OnClientDumpRequestCallback dump_callback,
88                         void* dump_context,
89                         OnClientExitedCallback exit_callback,
90                         void* exit_context,
91                         OnClientUploadRequestCallback upload_request_callback,
92                         void* upload_context,
93                         bool generate_dumps,
94                         const std::wstring* dump_path);
95 
96   ~CrashGenerationServer();
97 
98   // Performs initialization steps needed to start listening to clients. Upon
99   // successful return clients may connect to this server's pipe.
100   //
101   // Returns true if initialization is successful; false otherwise.
102   bool Start();
103 
pre_fetch_custom_info(bool do_pre_fetch)104   void pre_fetch_custom_info(bool do_pre_fetch) {
105     pre_fetch_custom_info_ = do_pre_fetch;
106   }
107 
108  private:
109   // Various states the client can be in during the handshake with
110   // the server.
111   enum IPCServerState {
112     // Server starts in this state.
113     IPC_SERVER_STATE_UNINITIALIZED,
114 
115     // Server is in error state and it cannot serve any clients.
116     IPC_SERVER_STATE_ERROR,
117 
118     // Server starts in this state.
119     IPC_SERVER_STATE_INITIAL,
120 
121     // Server has issued an async connect to the pipe and it is waiting
122     // for the connection to be established.
123     IPC_SERVER_STATE_CONNECTING,
124 
125     // Server is connected successfully.
126     IPC_SERVER_STATE_CONNECTED,
127 
128     // Server has issued an async read from the pipe and it is waiting for
129     // the read to finish.
130     IPC_SERVER_STATE_READING,
131 
132     // Server is done reading from the pipe.
133     IPC_SERVER_STATE_READ_DONE,
134 
135     // Server has issued an async write to the pipe and it is waiting for
136     // the write to finish.
137     IPC_SERVER_STATE_WRITING,
138 
139     // Server is done writing to the pipe.
140     IPC_SERVER_STATE_WRITE_DONE,
141 
142     // Server has issued an async read from the pipe for an ack and it
143     // is waiting for the read to finish.
144     IPC_SERVER_STATE_READING_ACK,
145 
146     // Server is done writing to the pipe and it is now ready to disconnect
147     // and reconnect.
148     IPC_SERVER_STATE_DISCONNECTING
149   };
150 
151   //
152   // Helper methods to handle various server IPC states.
153   //
154   void HandleErrorState();
155   void HandleInitialState();
156   void HandleConnectingState();
157   void HandleConnectedState();
158   void HandleReadingState();
159   void HandleReadDoneState();
160   void HandleWritingState();
161   void HandleWriteDoneState();
162   void HandleReadingAckState();
163   void HandleDisconnectingState();
164 
165   // Prepares reply for a client from the given parameters.
166   bool PrepareReply(const ClientInfo& client_info,
167                     ProtocolMessage* reply) const;
168 
169   // Duplicates various handles in the ClientInfo object for the client
170   // process and stores them in the given ProtocolMessage instance. If
171   // creating any handle fails, ProtocolMessage will contain the handles
172   // already created successfully, which should be closed by the caller.
173   bool CreateClientHandles(const ClientInfo& client_info,
174                            ProtocolMessage* reply) const;
175 
176   // Response to the given client. Return true if all steps of
177   // responding to the client succeed, false otherwise.
178   bool RespondToClient(ClientInfo* client_info);
179 
180   // Handles a connection request from the client.
181   void HandleConnectionRequest();
182 
183   // Handles a dump request from the client.
184   void HandleDumpRequest(const ClientInfo& client_info);
185 
186   // Callback for pipe connected event.
187   static void CALLBACK OnPipeConnected(void* context, BOOLEAN timer_or_wait);
188 
189   // Callback for a dump request.
190   static void CALLBACK OnDumpRequest(void* context, BOOLEAN timer_or_wait);
191 
192   // Callback for client process exit event.
193   static void CALLBACK OnClientEnd(void* context, BOOLEAN timer_or_wait);
194 
195   // Handles client process exit.
196   void HandleClientProcessExit(ClientInfo* client_info);
197 
198   // Adds the given client to the list of registered clients.
199   bool AddClient(ClientInfo* client_info);
200 
201   // Generates dump for the given client.
202   bool GenerateDump(const ClientInfo& client, std::wstring* dump_path);
203 
204   // Puts the server in a permanent error state and sets a signal such that
205   // the state will be immediately entered after the current state transition
206   // is complete.
207   void EnterErrorState();
208 
209   // Puts the server in the specified state and sets a signal such that the
210   // state is immediately entered after the current state transition is
211   // complete.
212   void EnterStateImmediately(IPCServerState state);
213 
214   // Puts the server in the specified state. No signal will be set, so the state
215   // transition will only occur when signaled manually or by completion of an
216   // asynchronous IO operation.
217   void EnterStateWhenSignaled(IPCServerState state);
218 
219   // Sync object for thread-safe access to the shared list of clients.
220   CRITICAL_SECTION sync_;
221 
222   // List of clients.
223   std::list<ClientInfo*> clients_;
224 
225   // Pipe name.
226   std::wstring pipe_name_;
227 
228   // Pipe security attributes
229   SECURITY_ATTRIBUTES* pipe_sec_attrs_;
230 
231   // Handle to the pipe used for handshake with clients.
232   HANDLE pipe_;
233 
234   // Pipe wait handle.
235   HANDLE pipe_wait_handle_;
236 
237   // Handle to server-alive mutex.
238   HANDLE server_alive_handle_;
239 
240   // Callback for a successful client connection.
241   OnClientConnectedCallback connect_callback_;
242 
243   // Context for client connected callback.
244   void* connect_context_;
245 
246   // Callback for a client dump request.
247   OnClientDumpRequestCallback dump_callback_;
248 
249   // Context for client dump request callback.
250   void* dump_context_;
251 
252   // Callback for client process exit.
253   OnClientExitedCallback exit_callback_;
254 
255   // Context for client process exit callback.
256   void* exit_context_;
257 
258   // Callback for upload request.
259   OnClientUploadRequestCallback upload_request_callback_;
260 
261   // Context for upload request callback.
262   void* upload_context_;
263 
264   // Whether to generate dumps.
265   bool generate_dumps_;
266 
267   // Wether to populate custom information up-front.
268   bool pre_fetch_custom_info_;
269 
270   // The dump path for the server.
271   const std::wstring dump_path_;
272 
273   // State of the server in performing the IPC with the client.
274   // Note that since we restrict the pipe to one instance, we
275   // only need to keep one state of the server. Otherwise, server
276   // would have one state per client it is talking to.
277   IPCServerState server_state_;
278 
279   // Whether the server is shutting down.
280   bool shutting_down_;
281 
282   // Overlapped instance for async I/O on the pipe.
283   OVERLAPPED overlapped_;
284 
285   // Message object used in IPC with the client.
286   ProtocolMessage msg_;
287 
288   // Client Info for the client that's connecting to the server.
289   ClientInfo* client_info_;
290 
291   // Disable copy ctor and operator=.
292   CrashGenerationServer(const CrashGenerationServer& crash_server);
293   CrashGenerationServer& operator=(const CrashGenerationServer& crash_server);
294 };
295 
296 }  // namespace google_breakpad
297 
298 #endif  // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__
299