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