| 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 |