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