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