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