Added on-demand minidump generation for Linux, and a Linux test app.
A=brdevmn R=mochalatte Code review: http://breakpad.appspot.com/48001/show git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@451 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
5fb436d5bb
commit
f7f9dfcab6
3 changed files with 117 additions and 4 deletions
|
@ -77,12 +77,13 @@
|
|||
#include <sys/ucontext.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/wait.h>
|
||||
#include <ucontext.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common/linux/linux_libc_support.h"
|
||||
#include "common/linux/linux_syscall_support.h"
|
||||
#include "common/linux/memory.h"
|
||||
#include "client/linux/minidump_writer//minidump_writer.h"
|
||||
#include "client/linux/minidump_writer/minidump_writer.h"
|
||||
#include "common/linux/guid_creator.h"
|
||||
|
||||
// A wrapper for the tgkill syscall: send a signal to a specific thread.
|
||||
|
@ -274,6 +275,11 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
|
|||
callback_context_))
|
||||
return true;
|
||||
|
||||
return GenerateDump(&context);
|
||||
}
|
||||
|
||||
// This function may run in a compromised context: see the top of the file.
|
||||
bool ExceptionHandler::GenerateDump(CrashContext *context) {
|
||||
static const unsigned kChildStackSize = 8000;
|
||||
PageAllocator allocator;
|
||||
uint8_t* stack = (uint8_t*) allocator.Alloc(kChildStackSize);
|
||||
|
@ -286,8 +292,8 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
|
|||
ThreadArgument thread_arg;
|
||||
thread_arg.handler = this;
|
||||
thread_arg.pid = getpid();
|
||||
thread_arg.context = &context;
|
||||
thread_arg.context_size = sizeof(context);
|
||||
thread_arg.context = context;
|
||||
thread_arg.context_size = sizeof(*context);
|
||||
|
||||
const pid_t child = sys_clone(
|
||||
ThreadEntry, stack, CLONE_FILES | CLONE_FS | CLONE_UNTRACED,
|
||||
|
@ -298,7 +304,7 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
|
|||
} while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r == -1) {
|
||||
static const char msg[] = "ExceptionHandler::HandleSignal: waitpid failed:";
|
||||
static const char msg[] = "ExceptionHandler::GenerateDump waitpid failed:";
|
||||
sys_write(2, msg, sizeof(msg) - 1);
|
||||
sys_write(2, strerror(errno), strlen(strerror(errno)));
|
||||
sys_write(2, "\n", 1);
|
||||
|
@ -321,4 +327,29 @@ bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
|
|||
next_minidump_path_c_, crashing_process, context, context_size);
|
||||
}
|
||||
|
||||
// static
|
||||
bool ExceptionHandler::WriteMinidump(const std::string &dump_path,
|
||||
MinidumpCallback callback,
|
||||
void* callback_context) {
|
||||
ExceptionHandler eh(dump_path, NULL, callback, callback_context, false);
|
||||
return eh.WriteMinidump();
|
||||
}
|
||||
|
||||
bool ExceptionHandler::WriteMinidump() {
|
||||
// Allow ourselves to be dumped.
|
||||
sys_prctl(PR_SET_DUMPABLE, 1);
|
||||
|
||||
CrashContext context;
|
||||
int getcontext_result = getcontext(&context.context);
|
||||
if (getcontext_result)
|
||||
return false;
|
||||
memcpy(&context.float_state, context.context.uc_mcontext.fpregs,
|
||||
sizeof(context.float_state));
|
||||
context.tid = sys_gettid();
|
||||
|
||||
bool success = GenerateDump(&context);
|
||||
UpdateNextID();
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
|
|
@ -153,6 +153,7 @@ class ExceptionHandler {
|
|||
bool InstallHandlers();
|
||||
void UninstallHandlers();
|
||||
void PreresolveSymbols();
|
||||
bool GenerateDump(CrashContext *context);
|
||||
|
||||
void UpdateNextID();
|
||||
static void SignalHandler(int sig, siginfo_t* info, void* uc);
|
||||
|
|
81
src/processor/testdata/linux_test_app.cc
vendored
Normal file
81
src/processor/testdata/linux_test_app.cc
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright (c) 2009, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Breakpad test application for Linux. When run, it generates one on-demand
|
||||
// minidump and then crashes, which should generate an on-crash minidump.
|
||||
// dump_syms can be used to extract symbol information for use in processing.
|
||||
|
||||
// To build:
|
||||
// g++ -g -o linux_test_app -I ../../ -L../../client/linux linux_test_app.cc \
|
||||
// -lbreakpad
|
||||
// Add -m32 to build a 32-bit executable, or -m64 for a 64-bit one
|
||||
// (assuming your environment supports it). Replace -g with -gstabs+ to
|
||||
// generate an executable with STABS symbols (needs -m32), or -gdwarf-2 for one
|
||||
// with DWARF symbols (32- or 64-bit)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include "common/linux/linux_syscall_support.h"
|
||||
#include "client/linux/handler/exception_handler.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// google_breakpad::MinidumpCallback to invoke after minidump generation.
|
||||
static bool callback(const char *dump_path, const char *id,
|
||||
void *context,
|
||||
bool succeeded) {
|
||||
if (succeeded) {
|
||||
printf("dump guid is %s\n", id);
|
||||
} else {
|
||||
printf("dump failed\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
static void CrashFunction() {
|
||||
int *i = reinterpret_cast<int*>(0x45);
|
||||
*i = 5; // crash!
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
google_breakpad::ExceptionHandler eh(".", NULL, callback, NULL, true);
|
||||
if (!eh.WriteMinidump()) {
|
||||
printf("Failed to generate on-demand minidump\n");
|
||||
}
|
||||
CrashFunction();
|
||||
printf("did not crash?\n");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue