LCOV - code coverage report
Current view: directory - toolkit/crashreporter/google-breakpad/src/client/linux/handler - exception_handler.h (source / functions) Found Hit Coverage
Test: app.info Lines: 8 7 87.5 %
Date: 2012-06-02 Functions: 3 2 66.7 %

       1                 : // Copyright (c) 2010 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_LINUX_HANDLER_EXCEPTION_HANDLER_H_
      31                 : #define CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_
      32                 : 
      33                 : #include <string>
      34                 : #include <vector>
      35                 : 
      36                 : #include <pthread.h>
      37                 : #include <signal.h>
      38                 : #include <stdint.h>
      39                 : #include <stdio.h>
      40                 : 
      41                 : #include "client/linux/android_ucontext.h"
      42                 : #include "client/linux/crash_generation/crash_generation_client.h"
      43                 : #include "client/linux/minidump_writer/minidump_writer.h"
      44                 : #include "google_breakpad/common/minidump_format.h"
      45                 : #include "processor/scoped_ptr.h"
      46                 : 
      47                 : struct sigaction;
      48                 : 
      49                 : namespace google_breakpad {
      50                 : 
      51                 : class ExceptionHandler;
      52                 : 
      53                 : // ExceptionHandler
      54                 : //
      55                 : // ExceptionHandler can write a minidump file when an exception occurs,
      56                 : // or when WriteMinidump() is called explicitly by your program.
      57                 : //
      58                 : // To have the exception handler write minidumps when an uncaught exception
      59                 : // (crash) occurs, you should create an instance early in the execution
      60                 : // of your program, and keep it around for the entire time you want to
      61                 : // have crash handling active (typically, until shutdown).
      62                 : // (NOTE): There should be only be one this kind of exception handler
      63                 : // object per process.
      64                 : //
      65                 : // If you want to write minidumps without installing the exception handler,
      66                 : // you can create an ExceptionHandler with install_handler set to false,
      67                 : // then call WriteMinidump.  You can also use this technique if you want to
      68                 : // use different minidump callbacks for different call sites.
      69                 : //
      70                 : // In either case, a callback function is called when a minidump is written,
      71                 : // which receives the unqiue id of the minidump.  The caller can use this
      72                 : // id to collect and write additional application state, and to launch an
      73                 : // external crash-reporting application.
      74                 : //
      75                 : // Caller should try to make the callbacks as crash-friendly as possible,
      76                 : // it should avoid use heap memory allocation as much as possible.
      77                 : class ExceptionHandler {
      78                 :  public:
      79                 :   // A callback function to run before Breakpad performs any substantial
      80                 :   // processing of an exception.  A FilterCallback is called before writing
      81                 :   // a minidump.  context is the parameter supplied by the user as
      82                 :   // callback_context when the handler was created.
      83                 :   //
      84                 :   // If a FilterCallback returns true, Breakpad will continue processing,
      85                 :   // attempting to write a minidump.  If a FilterCallback returns false,
      86                 :   // Breakpad  will immediately report the exception as unhandled without
      87                 :   // writing a minidump, allowing another handler the opportunity to handle it.
      88                 :   typedef bool (*FilterCallback)(void *context);
      89                 : 
      90                 :   // A callback function to run after the minidump has been written.
      91                 :   // minidump_id is a unique id for the dump, so the minidump
      92                 :   // file is <dump_path>\<minidump_id>.dmp.  context is the parameter supplied
      93                 :   // by the user as callback_context when the handler was created.  succeeded
      94                 :   // indicates whether a minidump file was successfully written.
      95                 :   //
      96                 :   // If an exception occurred and the callback returns true, Breakpad will
      97                 :   // treat the exception as fully-handled, suppressing any other handlers from
      98                 :   // being notified of the exception.  If the callback returns false, Breakpad
      99                 :   // will treat the exception as unhandled, and allow another handler to handle
     100                 :   // it. If there are no other handlers, Breakpad will report the exception to
     101                 :   // the system as unhandled, allowing a debugger or native crash dialog the
     102                 :   // opportunity to handle the exception.  Most callback implementations
     103                 :   // should normally return the value of |succeeded|, or when they wish to
     104                 :   // not report an exception of handled, false.  Callbacks will rarely want to
     105                 :   // return true directly (unless |succeeded| is true).
     106                 :   typedef bool (*MinidumpCallback)(const char *dump_path,
     107                 :                                    const char *minidump_id,
     108                 :                                    void *context,
     109                 :                                    bool succeeded);
     110                 : 
     111                 :   // In certain cases, a user may wish to handle the generation of the minidump
     112                 :   // themselves. In this case, they can install a handler callback which is
     113                 :   // called when a crash has occured. If this function returns true, no other
     114                 :   // processing of occurs and the process will shortly be crashed. If this
     115                 :   // returns false, the normal processing continues.
     116                 :   typedef bool (*HandlerCallback)(const void* crash_context,
     117                 :                                   size_t crash_context_size,
     118                 :                                   void* context);
     119                 : 
     120                 :   // Creates a new ExceptionHandler instance to handle writing minidumps.
     121                 :   // Before writing a minidump, the optional filter callback will be called.
     122                 :   // Its return value determines whether or not Breakpad should write a
     123                 :   // minidump.  Minidump files will be written to dump_path, and the optional
     124                 :   // callback is called after writing the dump file, as described above.
     125                 :   // If install_handler is true, then a minidump will be written whenever
     126                 :   // an unhandled exception occurs.  If it is false, minidumps will only
     127                 :   // be written when WriteMinidump is called.
     128                 :   ExceptionHandler(const std::string &dump_path,
     129                 :                    FilterCallback filter, MinidumpCallback callback,
     130                 :                    void *callback_context,
     131                 :                    bool install_handler);
     132                 : 
     133                 :   // Creates a new ExceptionHandler instance that can attempt to
     134                 :   // perform out-of-process dump generation if server_fd is valid. If
     135                 :   // server_fd is invalid, in-process dump generation will be
     136                 :   // used. See the above ctor for a description of the other
     137                 :   // parameters.
     138                 :   ExceptionHandler(const std::string& dump_path,
     139                 :                    FilterCallback filter, MinidumpCallback callback,
     140                 :                    void* callback_context,
     141                 :                    bool install_handler,
     142                 :                    const int server_fd);
     143                 : 
     144                 :   ~ExceptionHandler();
     145                 : 
     146                 :   // Get and set the minidump path.
     147               0 :   std::string dump_path() const { return dump_path_; }
     148            2794 :   void set_dump_path(const std::string &dump_path) {
     149            2794 :     dump_path_ = dump_path;
     150            2794 :     dump_path_c_ = dump_path_.c_str();
     151            2794 :     UpdateNextID();
     152            2794 :   }
     153                 : 
     154                 :   void set_crash_handler(HandlerCallback callback) {
     155                 :     crash_handler_ = callback;
     156                 :   }
     157                 : 
     158                 :   // Writes a minidump immediately.  This can be used to capture the
     159                 :   // execution state independently of a crash.  Returns true on success.
     160                 :   bool WriteMinidump();
     161                 : 
     162                 :   // Variant of WriteMinidump() above that optionally allows writing
     163                 :   // an artificial exception stream in the minidump.
     164                 :   bool WriteMinidump(bool write_exception_stream);
     165                 : 
     166                 :   // Convenience form of WriteMinidump which does not require an
     167                 :   // ExceptionHandler instance.
     168                 :   static bool WriteMinidump(const std::string &dump_path,
     169                 :                             MinidumpCallback callback,
     170                 :                             void *callback_context);
     171                 : 
     172                 :   // Variant of WriteMinidump() above that optionally allows writing
     173                 :   // an artificial exception stream in the minidump.
     174                 :   static bool WriteMinidump(const std::string &dump_path,
     175                 :                             bool write_exception_stream,
     176                 :                             MinidumpCallback callback,
     177                 :                             void* callback_context);
     178                 : 
     179                 :   // Write a minidump of |child| immediately.  This can be used to
     180                 :   // capture the execution state of |child| independently of a crash.
     181                 :   // Pass a meaningful |child_blamed_thread| to make that thread in
     182                 :   // the child process the one from which a crash signature is
     183                 :   // extracted.
     184                 :   //
     185                 :   // WARNING: the return of this function *must* be ordered
     186                 :   // happens-before the code that will eventually reap |child|.
     187                 :   // Otherwise there's a pernicious race condition in which |child|
     188                 :   // exits, is reaped, another process created with its pid, then that
     189                 :   // new process dumped.
     190                 :   static bool WriteMinidumpForChild(pid_t child,
     191                 :                                     pid_t child_blamed_thread,
     192                 :                                     const std::string &dump_path,
     193                 :                                     MinidumpCallback callback,
     194                 :                                     void *callback_context);
     195                 : 
     196                 :   // This structure is passed to minidump_writer.h:WriteMinidump via an opaque
     197                 :   // blob. It shouldn't be needed in any user code.
     198                 :   struct CrashContext {
     199                 :     siginfo_t siginfo;
     200                 :     pid_t tid;  // the crashing thread.
     201                 :     struct ucontext context;
     202                 : #if !defined(__ARM_EABI__)
     203                 :     // #ifdef this out because FP state is not part of user ABI for Linux ARM.
     204                 :     struct _libc_fpstate float_state;
     205                 : #endif
     206                 :   };
     207                 : 
     208                 :   // Returns whether out-of-process dump generation is used or not.
     209            1410 :   bool IsOutOfProcess() const {
     210            1410 :       return crash_generation_client_.get() != NULL;
     211                 :   }
     212                 : 
     213                 :   // Add information about a memory mapping. This can be used if
     214                 :   // a custom library loader is used that maps things in a way
     215                 :   // that the linux dumper can't handle by reading the maps file.
     216                 :   void AddMappingInfo(const std::string& name,
     217                 :                       const u_int8_t identifier[sizeof(MDGUID)],
     218                 :                       uintptr_t start_address,
     219                 :                       size_t mapping_size,
     220                 :                       size_t file_offset);
     221                 : 
     222                 :   // Calling RegisterAppMemory(p, len) causes len bytes starting
     223                 :   // at address p to be copied to the minidump when a crash happens.
     224                 :   void RegisterAppMemory(void *ptr, size_t length);
     225                 :   void UnregisterAppMemory(void *ptr);
     226                 : 
     227                 :  private:
     228                 :   void Init(const std::string &dump_path,
     229                 :             const int server_fd);
     230                 :   bool InstallHandlers();
     231                 :   void UninstallHandlers();
     232                 :   void PreresolveSymbols();
     233                 :   bool GenerateDump(CrashContext *context);
     234                 :   void SendContinueSignalToChild();
     235                 :   void WaitForContinueSignal();
     236                 : 
     237                 :   void UpdateNextID();
     238                 :   static void SignalHandler(int sig, siginfo_t* info, void* uc);
     239                 :   bool HandleSignal(int sig, siginfo_t* info, void* uc);
     240                 :   static int ThreadEntry(void* arg);
     241                 :   bool DoDump(pid_t crashing_process, const void* context,
     242                 :               size_t context_size);
     243                 : 
     244                 :   const FilterCallback filter_;
     245                 :   const MinidumpCallback callback_;
     246                 :   void* const callback_context_;
     247                 : 
     248                 :   scoped_ptr<CrashGenerationClient> crash_generation_client_;
     249                 : 
     250                 :   std::string dump_path_;
     251                 :   std::string next_minidump_path_;
     252                 :   std::string next_minidump_id_;
     253                 : 
     254                 :   // Pointers to C-string representations of the above. These are set
     255                 :   // when the above are set so we can avoid calling c_str during
     256                 :   // an exception.
     257                 :   const char* dump_path_c_;
     258                 :   const char* next_minidump_path_c_;
     259                 :   const char* next_minidump_id_c_;
     260                 : 
     261                 :   const bool handler_installed_;
     262                 :   HandlerCallback crash_handler_;
     263                 : 
     264                 :   // The global exception handler stack. This is need becuase there may exist
     265                 :   // multiple ExceptionHandler instances in a process. Each will have itself
     266                 :   // registered in this stack.
     267                 :   static std::vector<ExceptionHandler*> *handler_stack_;
     268                 :   // The index of the handler that should handle the next exception.
     269                 :   static unsigned handler_stack_index_;
     270                 :   static pthread_mutex_t handler_stack_mutex_;
     271                 : 
     272                 :   // A vector of the old signal handlers.
     273                 :   std::vector<std::pair<int, struct sigaction *> > old_handlers_;
     274                 : 
     275                 :   // We need to explicitly enable ptrace of parent processes on some
     276                 :   // kernels, but we need to know the PID of the cloned process before we
     277                 :   // can do this. We create a pipe which we can use to block the
     278                 :   // cloned process after creating it, until we have explicitly enabled 
     279                 :   // ptrace. This is used to store the file descriptors for the pipe
     280                 :   int fdes[2];
     281                 : 
     282                 :   // Callers can add extra info about mappings for cases where the
     283                 :   // dumper code cannot extract enough information from /proc/<pid>/maps.
     284                 :   MappingList mapping_info_;
     285                 : 
     286                 :   // Callers can request additional memory regions to be included in
     287                 :   // the dump.
     288                 :   AppMemoryList app_memory_info_;
     289                 : };
     290                 : 
     291                 : }  // namespace google_breakpad
     292                 : 
     293                 : #endif  // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_

Generated by: LCOV version 1.7