Planeshift

crash_generation_server.h

Go to the documentation of this file.
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__