~ubuntu-branches/ubuntu/trusty/tomahawk/trusty-proposed

« back to all changes in this revision

Viewing changes to thirdparty/breakpad/client/linux/handler/exception_handler.h

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-03-07 21:50:13 UTC
  • Revision ID: package-import@ubuntu.com-20130307215013-6gdjkdds7i9uenvs
Tags: upstream-0.6.0+dfsg
ImportĀ upstreamĀ versionĀ 0.6.0+dfsg

Show diffs side-by-side

added added

removed removed

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