• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2006, 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_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
31 #define CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
32 
33 #include <mach/mach.h>
34 #include <TargetConditionals.h>
35 
36 #include <string>
37 
38 #include "client/mac/handler/ucontext_compat.h"
39 #include "common/scoped_ptr.h"
40 
41 namespace google_breakpad {
42 
43 using std::string;
44 
45 class ExceptionHandler {
46  public:
47   // A callback function to run before Breakpad performs any substantial
48   // processing of an exception.  A FilterCallback is called before writing
49   // a minidump.  context is the parameter supplied by the user as
50   // callback_context when the handler was created.
51   //
52   // If a FilterCallback returns true, Breakpad will continue processing,
53   // attempting to write a minidump.  If a FilterCallback returns false, Breakpad
54   // will immediately report the exception as unhandled without writing a
55   // minidump, allowing another handler the opportunity to handle it.
56   typedef bool (*FilterCallback)(void *context);
57 
58   // A callback function to run after the minidump has been written.
59   // |minidump_id| is a unique id for the dump, so the minidump
60   // file is <dump_dir>/<minidump_id>.dmp.
61   // |context| is the value passed into the constructor.
62   // |succeeded| indicates whether a minidump file was successfully written.
63   // Return true if the exception was fully handled and breakpad should exit.
64   // Return false to allow any other exception handlers to process the
65   // exception.
66   typedef bool (*MinidumpCallback)(const char *dump_dir,
67                                    const char *minidump_id,
68                                    void *context, bool succeeded);
69 
70   // A callback function which will be called directly if an exception occurs.
71   // This bypasses the minidump file writing and simply gives the client
72   // the exception information.
73   typedef bool (*DirectCallback)( void *context,
74                                   int exception_type,
75                                   int exception_code,
76                                   int exception_subcode,
77                                   mach_port_t thread_name);
78 
79   // Creates a new ExceptionHandler instance to handle writing minidumps.
80   // Minidump files will be written to dump_path, and the optional callback
81   // is called after writing the dump file, as described above.
82   // If install_handler is true, then a minidump will be written whenever
83   // an unhandled exception occurs.  If it is false, minidumps will only
84   // be written when WriteMinidump is called.
85   // If port_name is non-NULL, attempt to perform out-of-process dump generation
86   // If port_name is NULL, in-process dump generation will be used.
87   ExceptionHandler(const string &dump_path,
88                    FilterCallback filter, MinidumpCallback callback,
89                    void *callback_context, bool install_handler,
90                    const char *port_name);
91 
92   // A special constructor if we want to bypass minidump writing and
93   // simply get a callback with the exception information.
94   ExceptionHandler(DirectCallback callback,
95                    void *callback_context,
96                    bool install_handler);
97 
98   ~ExceptionHandler();
99 
100   // Get and set the minidump path.
dump_path()101   string dump_path() const { return dump_path_; }
set_dump_path(const string & dump_path)102   void set_dump_path(const string &dump_path) {
103     dump_path_ = dump_path;
104     dump_path_c_ = dump_path_.c_str();
105     UpdateNextID();  // Necessary to put dump_path_ in next_minidump_path_.
106   }
107 
108  private:
109   // Install the SIG exception handlers.
110   bool InstallHandlers();
111 
112   // Uninstall the SIG exception handlers.
113   bool UninstallHandlers();
114 
115   // Setup the handler thread, and if |install_handler| is true, install the
116   // mach exception port handler
117   bool Setup();
118 
119   // Uninstall the mach exception handler (if any) and terminate the helper
120   // thread
121   bool Teardown();
122 
123   // All minidump writing goes through this one routine.
124   // |task_context| can be NULL. If not, it will be used to retrieve the
125   // context of the current thread, instead of using |thread_get_state|.
126   bool WriteMinidumpWithException(int exception_type,
127                                   int exception_code,
128                                   int exception_subcode,
129                                   breakpad_ucontext_t *task_context,
130                                   mach_port_t thread_name,
131                                   bool exit_after_write,
132                                   bool report_current_thread);
133 
134   // Signal handler for SIG exceptions.
135   static void SignalHandler(int sig, siginfo_t* info, void* uc);
136 
137   // disallow copy ctor and operator=
138   explicit ExceptionHandler(const ExceptionHandler &);
139   void operator=(const ExceptionHandler &);
140 
141   // Generates a new ID and stores it in next_minidump_id_, and stores the
142   // path of the next minidump to be written in next_minidump_path_.
143   void UpdateNextID();
144 
145   // The destination directory for the minidump
146   string dump_path_;
147 
148   // The basename of the next minidump w/o extension
149   string next_minidump_id_;
150 
151   // The full path to the next minidump to be written, including extension
152   string next_minidump_path_;
153 
154   // Pointers to the UTF-8 versions of above
155   const char *dump_path_c_;
156   const char *next_minidump_id_c_;
157   const char *next_minidump_path_c_;
158 
159   // The callback function and pointer to be passed back after the minidump
160   // has been written
161   FilterCallback filter_;
162   MinidumpCallback callback_;
163   void *callback_context_;
164 
165   // The callback function to be passed back when we don't want a minidump
166   // file to be written
167   DirectCallback directCallback_;
168 
169   // True, if we've installed the exception handler
170   bool installed_exception_handler_;
171 
172   // True, if we're in the process of uninstalling the exception handler and
173   // the thread.
174   bool is_in_teardown_;
175 };
176 
177 }  // namespace google_breakpad
178 
179 #endif  // CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
180