Planeshift
|
00001 // Copyright (c) 2008, Google Inc. 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // * Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // * Redistributions in binary form must reproduce the above 00011 // copyright notice, this list of conditions and the following disclaimer 00012 // in the documentation and/or other materials provided with the 00013 // distribution. 00014 // * Neither the name of Google Inc. nor the names of its 00015 // contributors may be used to endorse or promote products derived from 00016 // this software without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 #ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ 00031 #define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ 00032 00033 #include <list> 00034 #include <string> 00035 #include "client/windows/common/ipc_protocol.h" 00036 #include "client/windows/crash_generation/minidump_generator.h" 00037 #include "common/scoped_ptr.h" 00038 00039 namespace google_breakpad { 00040 class ClientInfo; 00041 00042 // Abstraction for server side implementation of out-of-process crash 00043 // generation protocol for Windows platform only. It generates Windows 00044 // minidump files for client processes that request dump generation. When 00045 // the server is requested to start listening for clients (by calling the 00046 // Start method), it creates a named pipe and waits for the clients to 00047 // register. In response, it hands them event handles that the client can 00048 // signal to request dump generation. When the clients request dump 00049 // generation in this way, the server generates Windows minidump files. 00050 class CrashGenerationServer { 00051 public: 00052 typedef void (*OnClientConnectedCallback)(void* context, 00053 const ClientInfo* client_info); 00054 00055 typedef void (*OnClientDumpRequestCallback)(void* context, 00056 const ClientInfo* client_info, 00057 const std::wstring* file_path); 00058 00059 typedef void (*OnClientExitedCallback)(void* context, 00060 const ClientInfo* client_info); 00061 00062 typedef void (*OnClientUploadRequestCallback)(void* context, 00063 const DWORD crash_id); 00064 00065 // Creates an instance with the given parameters. 00066 // 00067 // Parameter pipe_name: Name of the Windows named pipe 00068 // Parameter pipe_sec_attrs Security attributes to set on the pipe. Pass 00069 // NULL to use default security on the pipe. By default, the pipe created 00070 // allows Local System, Administrators and the Creator full control and 00071 // the Everyone group read access on the pipe. 00072 // Parameter connect_callback: Callback for a new client connection. 00073 // Parameter connect_context: Context for client connection callback. 00074 // Parameter crash_callback: Callback for a client crash dump request. 00075 // Parameter crash_context: Context for client crash dump request callback. 00076 // Parameter exit_callback: Callback for client process exit. 00077 // Parameter exit_context: Context for client exit callback. 00078 // Parameter generate_dumps: Whether to automatically generate dumps. 00079 // Client code of this class might want to generate dumps explicitly in the 00080 // crash dump request callback. In that case, false can be passed for this 00081 // parameter. 00082 // Parameter dump_path: Path for generating dumps; required only if true is 00083 // passed for generateDumps parameter; NULL can be passed otherwise. 00084 CrashGenerationServer(const std::wstring& pipe_name, 00085 SECURITY_ATTRIBUTES* pipe_sec_attrs, 00086 OnClientConnectedCallback connect_callback, 00087 void* connect_context, 00088 OnClientDumpRequestCallback dump_callback, 00089 void* dump_context, 00090 OnClientExitedCallback exit_callback, 00091 void* exit_context, 00092 OnClientUploadRequestCallback upload_request_callback, 00093 void* upload_context, 00094 bool generate_dumps, 00095 const std::wstring* dump_path); 00096 00097 ~CrashGenerationServer(); 00098 00099 // Performs initialization steps needed to start listening to clients. Upon 00100 // successful return clients may connect to this server's pipe. 00101 // 00102 // Returns true if initialization is successful; false otherwise. 00103 bool Start(); 00104 00105 void pre_fetch_custom_info(bool do_pre_fetch) { 00106 pre_fetch_custom_info_ = do_pre_fetch; 00107 } 00108 00109 private: 00110 // Various states the client can be in during the handshake with 00111 // the server. 00112 enum IPCServerState { 00113 // Server starts in this state. 00114 IPC_SERVER_STATE_UNINITIALIZED, 00115 00116 // Server is in error state and it cannot serve any clients. 00117 IPC_SERVER_STATE_ERROR, 00118 00119 // Server starts in this state. 00120 IPC_SERVER_STATE_INITIAL, 00121 00122 // Server has issued an async connect to the pipe and it is waiting 00123 // for the connection to be established. 00124 IPC_SERVER_STATE_CONNECTING, 00125 00126 // Server is connected successfully. 00127 IPC_SERVER_STATE_CONNECTED, 00128 00129 // Server has issued an async read from the pipe and it is waiting for 00130 // the read to finish. 00131 IPC_SERVER_STATE_READING, 00132 00133 // Server is done reading from the pipe. 00134 IPC_SERVER_STATE_READ_DONE, 00135 00136 // Server has issued an async write to the pipe and it is waiting for 00137 // the write to finish. 00138 IPC_SERVER_STATE_WRITING, 00139 00140 // Server is done writing to the pipe. 00141 IPC_SERVER_STATE_WRITE_DONE, 00142 00143 // Server has issued an async read from the pipe for an ack and it 00144 // is waiting for the read to finish. 00145 IPC_SERVER_STATE_READING_ACK, 00146 00147 // Server is done writing to the pipe and it is now ready to disconnect 00148 // and reconnect. 00149 IPC_SERVER_STATE_DISCONNECTING 00150 }; 00151 00152 // 00153 // Helper methods to handle various server IPC states. 00154 // 00155 void HandleErrorState(); 00156 void HandleInitialState(); 00157 void HandleConnectingState(); 00158 void HandleConnectedState(); 00159 void HandleReadingState(); 00160 void HandleReadDoneState(); 00161 void HandleWritingState(); 00162 void HandleWriteDoneState(); 00163 void HandleReadingAckState(); 00164 void HandleDisconnectingState(); 00165 00166 // Prepares reply for a client from the given parameters. 00167 bool PrepareReply(const ClientInfo& client_info, 00168 ProtocolMessage* reply) const; 00169 00170 // Duplicates various handles in the ClientInfo object for the client 00171 // process and stores them in the given ProtocolMessage instance. If 00172 // creating any handle fails, ProtocolMessage will contain the handles 00173 // already created successfully, which should be closed by the caller. 00174 bool CreateClientHandles(const ClientInfo& client_info, 00175 ProtocolMessage* reply) const; 00176 00177 // Response to the given client. Return true if all steps of 00178 // responding to the client succeed, false otherwise. 00179 bool RespondToClient(ClientInfo* client_info); 00180 00181 // Handles a connection request from the client. 00182 void HandleConnectionRequest(); 00183 00184 // Handles a dump request from the client. 00185 void HandleDumpRequest(const ClientInfo& client_info); 00186 00187 // Callback for pipe connected event. 00188 static void CALLBACK OnPipeConnected(void* context, BOOLEAN timer_or_wait); 00189 00190 // Callback for a dump request. 00191 static void CALLBACK OnDumpRequest(void* context, BOOLEAN timer_or_wait); 00192 00193 // Callback for client process exit event. 00194 static void CALLBACK OnClientEnd(void* context, BOOLEAN timer_or_wait); 00195 00196 // Handles client process exit. 00197 void HandleClientProcessExit(ClientInfo* client_info); 00198 00199 // Adds the given client to the list of registered clients. 00200 bool AddClient(ClientInfo* client_info); 00201 00202 // Generates dump for the given client. 00203 bool GenerateDump(const ClientInfo& client, std::wstring* dump_path); 00204 00205 // Puts the server in a permanent error state and sets a signal such that 00206 // the state will be immediately entered after the current state transition 00207 // is complete. 00208 void EnterErrorState(); 00209 00210 // Puts the server in the specified state and sets a signal such that the 00211 // state is immediately entered after the current state transition is 00212 // complete. 00213 void EnterStateImmediately(IPCServerState state); 00214 00215 // Puts the server in the specified state. No signal will be set, so the state 00216 // transition will only occur when signaled manually or by completion of an 00217 // asynchronous IO operation. 00218 void EnterStateWhenSignaled(IPCServerState state); 00219 00220 // Sync object for thread-safe access to the shared list of clients. 00221 CRITICAL_SECTION sync_; 00222 00223 // List of clients. 00224 std::list<ClientInfo*> clients_; 00225 00226 // Pipe name. 00227 std::wstring pipe_name_; 00228 00229 // Pipe security attributes 00230 SECURITY_ATTRIBUTES* pipe_sec_attrs_; 00231 00232 // Handle to the pipe used for handshake with clients. 00233 HANDLE pipe_; 00234 00235 // Pipe wait handle. 00236 HANDLE pipe_wait_handle_; 00237 00238 // Handle to server-alive mutex. 00239 HANDLE server_alive_handle_; 00240 00241 // Callback for a successful client connection. 00242 OnClientConnectedCallback connect_callback_; 00243 00244 // Context for client connected callback. 00245 void* connect_context_; 00246 00247 // Callback for a client dump request. 00248 OnClientDumpRequestCallback dump_callback_; 00249 00250 // Context for client dump request callback. 00251 void* dump_context_; 00252 00253 // Callback for client process exit. 00254 OnClientExitedCallback exit_callback_; 00255 00256 // Context for client process exit callback. 00257 void* exit_context_; 00258 00259 // Callback for upload request. 00260 OnClientUploadRequestCallback upload_request_callback_; 00261 00262 // Context for upload request callback. 00263 void* upload_context_; 00264 00265 // Whether to generate dumps. 00266 bool generate_dumps_; 00267 00268 // Wether to populate custom information up-front. 00269 bool pre_fetch_custom_info_; 00270 00271 // Instance of a mini dump generator. 00272 scoped_ptr<MinidumpGenerator> dump_generator_; 00273 00274 // State of the server in performing the IPC with the client. 00275 // Note that since we restrict the pipe to one instance, we 00276 // only need to keep one state of the server. Otherwise, server 00277 // would have one state per client it is talking to. 00278 IPCServerState server_state_; 00279 00280 // Whether the server is shutting down. 00281 bool shutting_down_; 00282 00283 // Overlapped instance for async I/O on the pipe. 00284 OVERLAPPED overlapped_; 00285 00286 // Message object used in IPC with the client. 00287 ProtocolMessage msg_; 00288 00289 // Client Info for the client that's connecting to the server. 00290 ClientInfo* client_info_; 00291 00292 // Disable copy ctor and operator=. 00293 CrashGenerationServer(const CrashGenerationServer& crash_server); 00294 CrashGenerationServer& operator=(const CrashGenerationServer& crash_server); 00295 }; 00296 00297 } // namespace google_breakpad 00298 00299 #endif // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__