| // Copyright (c) 2008, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ |
| #define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ |
| |
| #include <list> |
| #include <string> |
| #include "client/windows/common/ipc_protocol.h" |
| #include "client/windows/crash_generation/minidump_generator.h" |
| #include "common/scoped_ptr.h" |
| |
| namespace google_breakpad { |
| class ClientInfo; |
| |
| // Abstraction for server side implementation of out-of-process crash |
| // generation protocol for Windows platform only. It generates Windows |
| // minidump files for client processes that request dump generation. When |
| // the server is requested to start listening for clients (by calling the |
| // Start method), it creates a named pipe and waits for the clients to |
| // register. In response, it hands them event handles that the client can |
| // signal to request dump generation. When the clients request dump |
| // generation in this way, the server generates Windows minidump files. |
| class CrashGenerationServer { |
| public: |
| typedef void (*OnClientConnectedCallback)(void* context, |
| const ClientInfo* client_info); |
| |
| typedef void (*OnClientDumpRequestCallback)(void* context, |
| const ClientInfo* client_info, |
| const std::wstring* file_path); |
| |
| typedef void (*OnClientExitedCallback)(void* context, |
| const ClientInfo* client_info); |
| |
| typedef void (*OnClientUploadRequestCallback)(void* context, |
| const DWORD crash_id); |
| |
| // Creates an instance with the given parameters. |
| // |
| // Parameter pipe_name: Name of the Windows named pipe |
| // Parameter pipe_sec_attrs Security attributes to set on the pipe. Pass |
| // NULL to use default security on the pipe. By default, the pipe created |
| // allows Local System, Administrators and the Creator full control and |
| // the Everyone group read access on the pipe. |
| // Parameter connect_callback: Callback for a new client connection. |
| // Parameter connect_context: Context for client connection callback. |
| // Parameter crash_callback: Callback for a client crash dump request. |
| // Parameter crash_context: Context for client crash dump request callback. |
| // Parameter exit_callback: Callback for client process exit. |
| // Parameter exit_context: Context for client exit callback. |
| // Parameter generate_dumps: Whether to automatically generate dumps. |
| // Client code of this class might want to generate dumps explicitly in the |
| // crash dump request callback. In that case, false can be passed for this |
| // parameter. |
| // Parameter dump_path: Path for generating dumps; required only if true is |
| // passed for generateDumps parameter; NULL can be passed otherwise. |
| CrashGenerationServer(const std::wstring& pipe_name, |
| SECURITY_ATTRIBUTES* pipe_sec_attrs, |
| OnClientConnectedCallback connect_callback, |
| void* connect_context, |
| OnClientDumpRequestCallback dump_callback, |
| void* dump_context, |
| OnClientExitedCallback exit_callback, |
| void* exit_context, |
| OnClientUploadRequestCallback upload_request_callback, |
| void* upload_context, |
| bool generate_dumps, |
| const std::wstring* dump_path); |
| |
| ~CrashGenerationServer(); |
| |
| // Performs initialization steps needed to start listening to clients. Upon |
| // successful return clients may connect to this server's pipe. |
| // |
| // Returns true if initialization is successful; false otherwise. |
| bool Start(); |
| |
| void pre_fetch_custom_info(bool do_pre_fetch) { |
| pre_fetch_custom_info_ = do_pre_fetch; |
| } |
| |
| private: |
| // Various states the client can be in during the handshake with |
| // the server. |
| enum IPCServerState { |
| // Server starts in this state. |
| IPC_SERVER_STATE_UNINITIALIZED, |
| |
| // Server is in error state and it cannot serve any clients. |
| IPC_SERVER_STATE_ERROR, |
| |
| // Server starts in this state. |
| IPC_SERVER_STATE_INITIAL, |
| |
| // Server has issued an async connect to the pipe and it is waiting |
| // for the connection to be established. |
| IPC_SERVER_STATE_CONNECTING, |
| |
| // Server is connected successfully. |
| IPC_SERVER_STATE_CONNECTED, |
| |
| // Server has issued an async read from the pipe and it is waiting for |
| // the read to finish. |
| IPC_SERVER_STATE_READING, |
| |
| // Server is done reading from the pipe. |
| IPC_SERVER_STATE_READ_DONE, |
| |
| // Server has issued an async write to the pipe and it is waiting for |
| // the write to finish. |
| IPC_SERVER_STATE_WRITING, |
| |
| // Server is done writing to the pipe. |
| IPC_SERVER_STATE_WRITE_DONE, |
| |
| // Server has issued an async read from the pipe for an ack and it |
| // is waiting for the read to finish. |
| IPC_SERVER_STATE_READING_ACK, |
| |
| // Server is done writing to the pipe and it is now ready to disconnect |
| // and reconnect. |
| IPC_SERVER_STATE_DISCONNECTING |
| }; |
| |
| // |
| // Helper methods to handle various server IPC states. |
| // |
| void HandleErrorState(); |
| void HandleInitialState(); |
| void HandleConnectingState(); |
| void HandleConnectedState(); |
| void HandleReadingState(); |
| void HandleReadDoneState(); |
| void HandleWritingState(); |
| void HandleWriteDoneState(); |
| void HandleReadingAckState(); |
| void HandleDisconnectingState(); |
| |
| // Prepares reply for a client from the given parameters. |
| bool PrepareReply(const ClientInfo& client_info, |
| ProtocolMessage* reply) const; |
| |
| // Duplicates various handles in the ClientInfo object for the client |
| // process and stores them in the given ProtocolMessage instance. If |
| // creating any handle fails, ProtocolMessage will contain the handles |
| // already created successfully, which should be closed by the caller. |
| bool CreateClientHandles(const ClientInfo& client_info, |
| ProtocolMessage* reply) const; |
| |
| // Response to the given client. Return true if all steps of |
| // responding to the client succeed, false otherwise. |
| bool RespondToClient(ClientInfo* client_info); |
| |
| // Handles a connection request from the client. |
| void HandleConnectionRequest(); |
| |
| // Handles a dump request from the client. |
| void HandleDumpRequest(const ClientInfo& client_info); |
| |
| // Callback for pipe connected event. |
| static void CALLBACK OnPipeConnected(void* context, BOOLEAN timer_or_wait); |
| |
| // Callback for a dump request. |
| static void CALLBACK OnDumpRequest(void* context, BOOLEAN timer_or_wait); |
| |
| // Callback for client process exit event. |
| static void CALLBACK OnClientEnd(void* context, BOOLEAN timer_or_wait); |
| |
| // Handles client process exit. |
| void HandleClientProcessExit(ClientInfo* client_info); |
| |
| // Adds the given client to the list of registered clients. |
| bool AddClient(ClientInfo* client_info); |
| |
| // Generates dump for the given client. |
| bool GenerateDump(const ClientInfo& client, std::wstring* dump_path); |
| |
| // Puts the server in a permanent error state and sets a signal such that |
| // the state will be immediately entered after the current state transition |
| // is complete. |
| void EnterErrorState(); |
| |
| // Puts the server in the specified state and sets a signal such that the |
| // state is immediately entered after the current state transition is |
| // complete. |
| void EnterStateImmediately(IPCServerState state); |
| |
| // Puts the server in the specified state. No signal will be set, so the state |
| // transition will only occur when signaled manually or by completion of an |
| // asynchronous IO operation. |
| void EnterStateWhenSignaled(IPCServerState state); |
| |
| // Sync object for thread-safe access to the shared list of clients. |
| CRITICAL_SECTION sync_; |
| |
| // List of clients. |
| std::list<ClientInfo*> clients_; |
| |
| // Pipe name. |
| std::wstring pipe_name_; |
| |
| // Pipe security attributes |
| SECURITY_ATTRIBUTES* pipe_sec_attrs_; |
| |
| // Handle to the pipe used for handshake with clients. |
| HANDLE pipe_; |
| |
| // Pipe wait handle. |
| HANDLE pipe_wait_handle_; |
| |
| // Handle to server-alive mutex. |
| HANDLE server_alive_handle_; |
| |
| // Callback for a successful client connection. |
| OnClientConnectedCallback connect_callback_; |
| |
| // Context for client connected callback. |
| void* connect_context_; |
| |
| // Callback for a client dump request. |
| OnClientDumpRequestCallback dump_callback_; |
| |
| // Context for client dump request callback. |
| void* dump_context_; |
| |
| // Callback for client process exit. |
| OnClientExitedCallback exit_callback_; |
| |
| // Context for client process exit callback. |
| void* exit_context_; |
| |
| // Callback for upload request. |
| OnClientUploadRequestCallback upload_request_callback_; |
| |
| // Context for upload request callback. |
| void* upload_context_; |
| |
| // Whether to generate dumps. |
| bool generate_dumps_; |
| |
| // Wether to populate custom information up-front. |
| bool pre_fetch_custom_info_; |
| |
| // The dump path for the server. |
| const std::wstring dump_path_; |
| |
| // State of the server in performing the IPC with the client. |
| // Note that since we restrict the pipe to one instance, we |
| // only need to keep one state of the server. Otherwise, server |
| // would have one state per client it is talking to. |
| IPCServerState server_state_; |
| |
| // Whether the server is shutting down. |
| bool shutting_down_; |
| |
| // Overlapped instance for async I/O on the pipe. |
| OVERLAPPED overlapped_; |
| |
| // Message object used in IPC with the client. |
| ProtocolMessage msg_; |
| |
| // Client Info for the client that's connecting to the server. |
| ClientInfo* client_info_; |
| |
| // Disable copy ctor and operator=. |
| CrashGenerationServer(const CrashGenerationServer& crash_server); |
| CrashGenerationServer& operator=(const CrashGenerationServer& crash_server); |
| }; |
| |
| } // namespace google_breakpad |
| |
| #endif // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ |