aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux/handler
diff options
context:
space:
mode:
authorprimiano@chromium.org <primiano@chromium.org>2014-10-28 16:45:14 +0000
committerprimiano@chromium.org <primiano@chromium.org>2014-10-28 16:45:14 +0000
commit507a09f4de7e4c9881135c427353a40dab410c5a (patch)
treedc9561f724ba35a31c74e88b23fc5c85d6105dd1 /src/client/linux/handler
parentFix breakpad on mips and x86_64 for the NDK r10c update. (diff)
downloadbreakpad-507a09f4de7e4c9881135c427353a40dab410c5a.tar.xz
Introduce microdump writer class.
Microdumps are a very lightweight variant of minidumps. They are meant to dump a minimal crash report on the system log (logcat on Android), containing only the state of the crashing thread. This is to deal with cases where the user has opted out from crash uploading but we still want to generate meaningful information on the device to pull a stacktrace for development purposes. Conversely to conventional stack traces (e.g. the one generated by Android's debuggerd or Chromium's base::stacktrace) microdumps do NOT require unwind tables to be present in the target binary. This allows to save precious binary size (~1.5 MB for Chrome on Arm, ~10 MB on arm64). More information and design doc on crbug.com/410294 BUG=chromium:410294 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1398 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/linux/handler')
-rw-r--r--src/client/linux/handler/exception_handler.cc13
-rw-r--r--src/client/linux/handler/minidump_descriptor.cc11
-rw-r--r--src/client/linux/handler/minidump_descriptor.h45
3 files changed, 56 insertions, 13 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index 7cad7756..3e2d1962 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -91,6 +91,7 @@
#include "common/linux/linux_libc_support.h"
#include "common/memory.h"
#include "client/linux/log/log.h"
+#include "client/linux/microdump_writer/microdump_writer.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
@@ -210,7 +211,8 @@ ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
if (server_fd >= 0)
crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd));
- if (!IsOutOfProcess() && !minidump_descriptor_.IsFD())
+ if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() &&
+ !minidump_descriptor_.IsMicrodumpOnConsole())
minidump_descriptor_.UpdatePath();
pthread_mutex_lock(&g_handler_stack_mutex_);
@@ -548,6 +550,12 @@ void ExceptionHandler::WaitForContinueSignal() {
// Runs on the cloned process.
bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
size_t context_size) {
+ if (minidump_descriptor_.IsMicrodumpOnConsole()) {
+ return google_breakpad::WriteMicrodump(crashing_process,
+ context,
+ context_size,
+ mapping_list_);
+ }
if (minidump_descriptor_.IsFD()) {
return google_breakpad::WriteMinidump(minidump_descriptor_.fd(),
minidump_descriptor_.size_limit(),
@@ -583,7 +591,8 @@ bool ExceptionHandler::WriteMinidump(const string& dump_path,
__attribute__((optimize("no-omit-frame-pointer")))
#endif
bool ExceptionHandler::WriteMinidump() {
- if (!IsOutOfProcess() && !minidump_descriptor_.IsFD()) {
+ if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() &&
+ !minidump_descriptor_.IsMicrodumpOnConsole()) {
// Update the path of the minidump so that this can be called multiple times
// and new files are created for each minidump. This is done before the
// generation happens, as clients may want to access the MinidumpDescriptor
diff --git a/src/client/linux/handler/minidump_descriptor.cc b/src/client/linux/handler/minidump_descriptor.cc
index c4618adc..029f8926 100644
--- a/src/client/linux/handler/minidump_descriptor.cc
+++ b/src/client/linux/handler/minidump_descriptor.cc
@@ -35,8 +35,12 @@
namespace google_breakpad {
+//static
+const MinidumpDescriptor::MicrodumpOnConsole kMicrodumpOnConsole = {};
+
MinidumpDescriptor::MinidumpDescriptor(const MinidumpDescriptor& descriptor)
- : fd_(descriptor.fd_),
+ : mode_(descriptor.mode_),
+ fd_(descriptor.fd_),
directory_(descriptor.directory_),
c_path_(NULL),
size_limit_(descriptor.size_limit_) {
@@ -50,6 +54,7 @@ MinidumpDescriptor& MinidumpDescriptor::operator=(
const MinidumpDescriptor& descriptor) {
assert(descriptor.path_.empty());
+ mode_ = descriptor.mode_;
fd_ = descriptor.fd_;
directory_ = descriptor.directory_;
path_.clear();
@@ -63,7 +68,7 @@ MinidumpDescriptor& MinidumpDescriptor::operator=(
}
void MinidumpDescriptor::UpdatePath() {
- assert(fd_ == -1 && !directory_.empty());
+ assert(mode_ == kWriteMinidumpToFile && !directory_.empty());
GUID guid;
char guid_str[kGUIDStringLength + 1];
@@ -72,7 +77,7 @@ void MinidumpDescriptor::UpdatePath() {
}
path_.clear();
- path_ = directory_ + "/" + guid_str + ".dmp";
+ path_ = directory_ + "/" + guid_str + ".dmp";
c_path_ = path_.c_str();
}
diff --git a/src/client/linux/handler/minidump_descriptor.h b/src/client/linux/handler/minidump_descriptor.h
index 9ffe622b..ed656cee 100644
--- a/src/client/linux/handler/minidump_descriptor.h
+++ b/src/client/linux/handler/minidump_descriptor.h
@@ -37,18 +37,25 @@
#include "common/using_std_string.h"
-// The MinidumpDescriptor describes how to access a minidump: it can contain
-// either a file descriptor or a path.
-// Note that when using files, it is created with the path to a directory.
-// The actual path where the minidump is generated is created by this class.
+// This class describes how a crash dump should be generated, either:
+// - Writing a full minidump to a file in a given directory (the actual path,
+// inside the directory, is determined by this class).
+// - Writing a full minidump to a given fd.
+// - Writing a reduced microdump to the console (logcat on Android).
namespace google_breakpad {
class MinidumpDescriptor {
public:
- MinidumpDescriptor() : fd_(-1), size_limit_(-1) {}
+ struct MicrodumpOnConsole {};
+ static const MicrodumpOnConsole kMicrodumpOnConsole;
+
+ MinidumpDescriptor() : mode_(kUninitialized),
+ fd_(-1),
+ size_limit_(-1) {}
explicit MinidumpDescriptor(const string& directory)
- : fd_(-1),
+ : mode_(kWriteMinidumpToFile),
+ fd_(-1),
directory_(directory),
c_path_(NULL),
size_limit_(-1) {
@@ -56,16 +63,24 @@ class MinidumpDescriptor {
}
explicit MinidumpDescriptor(int fd)
- : fd_(fd),
+ : mode_(kWriteMinidumpToFd),
+ fd_(fd),
c_path_(NULL),
size_limit_(-1) {
assert(fd != -1);
}
+ explicit MinidumpDescriptor(const MicrodumpOnConsole&)
+ : mode_(kWriteMicrodumpToConsole),
+ fd_(-1),
+ size_limit_(-1) {}
+
explicit MinidumpDescriptor(const MinidumpDescriptor& descriptor);
MinidumpDescriptor& operator=(const MinidumpDescriptor& descriptor);
- bool IsFD() const { return fd_ != -1; }
+ static MinidumpDescriptor getMicrodumpDescriptor();
+
+ bool IsFD() const { return mode_ == kWriteMinidumpToFd; }
int fd() const { return fd_; }
@@ -73,6 +88,10 @@ class MinidumpDescriptor {
const char* path() const { return c_path_; }
+ bool IsMicrodumpOnConsole() const {
+ return mode_ == kWriteMicrodumpToConsole;
+ }
+
// Updates the path so it is unique.
// Should be called from a normal context: this methods uses the heap.
void UpdatePath();
@@ -81,6 +100,16 @@ class MinidumpDescriptor {
void set_size_limit(off_t limit) { size_limit_ = limit; }
private:
+ enum DumpMode {
+ kUninitialized = 0,
+ kWriteMinidumpToFile,
+ kWriteMinidumpToFd,
+ kWriteMicrodumpToConsole
+ };
+
+ // Specifies the dump mode (see DumpMode).
+ DumpMode mode_;
+
// The file descriptor where the minidump is generated.
int fd_;