chromium/third_party/breakpad/breakpad/src/client/linux/handler/exception_handler_unittest.cc

// Copyright 2010 Google LLC
//
// 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 LLC 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.

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include <poll.h>
#include <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/wait.h>
#if defined(__mips__)
#include <sys/cachectl.h>
#endif

#include <string>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/ignore_ret.h"
#include "common/linux/linux_libc_support.h"
#include "common/tests/auto_tempdir.h"
#include "common/using_std_string.h"
#include "third_party/lss/linux_syscall_support.h"
#include "google_breakpad/processor/minidump.h"

usingnamespacegoogle_breakpad;

namespace {

// Flush the instruction cache for a given memory range.
// Only required on ARM and mips.
void FlushInstructionCache(const char* memory, uint32_t memory_size) {}

void sigchld_handler(int signo) {}

int CreateTMPFile(const string& dir, string* path) {}

class ExceptionHandlerTest : public ::testing::Test {};


void WaitForProcessToTerminate(pid_t process_id, int expected_status) {}

// Reads the minidump path sent over the pipe |fd| and sets it in |path|.
void ReadMinidumpPathFromPipe(int fd, string* path) {}

}  // namespace

TEST(ExceptionHandlerTest, SimpleWithPath) {}

TEST(ExceptionHandlerTest, SimpleWithFD) {}

static bool DoneCallback(const MinidumpDescriptor& descriptor,
                         void* context,
                         bool succeeded) {}

#ifndef ADDRESS_SANITIZER

// This is a replacement for "*reinterpret_cast<volatile int*>(NULL) = 0;"
// It is needed because GCC is allowed to assume that the program will
// not execute any undefined behavior (UB) operation. Further, when GCC
// observes that UB statement is reached, it can assume that all statements
// leading to the UB one are never executed either, and can completely
// optimize them out. In the case of ExceptionHandlerTest::ExternalDumper,
// GCC-4.9 optimized out the entire set up of ExceptionHandler, causing
// test failure.
volatile int* p_null;  // external linkage, so GCC can't tell that it
                       // remains NULL. Volatile just for a good measure.
static void DoNullPointerDereference() {}

void ChildCrash(bool use_fd) {}

TEST(ExceptionHandlerTest, ChildCrashWithPath) {}

TEST(ExceptionHandlerTest, ChildCrashWithFD) {}

#if !defined(__ANDROID_API__) || __ANDROID_API__ >= __ANDROID_API_N__
static void* SleepFunction(void* unused) {}

static void* CrashFunction(void* b_ptr) {}

// Tests that concurrent crashes do not enter a loop by alternately triggering
// the signal handler.
TEST(ExceptionHandlerTest, ParallelChildCrashesDontHang) {}
#endif  // !defined(__ANDROID_API__) || __ANDROID_API__ >= __ANDROID_API_N__

static bool DoneCallbackReturnFalse(const MinidumpDescriptor& descriptor,
                                    void* context,
                                    bool succeeded) {}

static bool DoneCallbackReturnTrue(const MinidumpDescriptor& descriptor,
                                   void* context,
                                   bool succeeded) {}

static bool DoneCallbackRaiseSIGKILL(const MinidumpDescriptor& descriptor,
                                     void* context,
                                     bool succeeded) {}

static bool FilterCallbackReturnFalse(void* context) {}

static bool FilterCallbackReturnTrue(void* context) {}

// SIGKILL cannot be blocked and a handler cannot be installed for it. In the
// following tests, if the child dies with signal SIGKILL, then the signal was
// redelivered to this handler. If the child dies with SIGSEGV then it wasn't.
static void RaiseSIGKILL(int sig) {}

static bool InstallRaiseSIGKILL() {}

static void CrashWithCallbacks(ExceptionHandler::FilterCallback filter,
                               ExceptionHandler::MinidumpCallback done,
                               string path) {}

TEST(ExceptionHandlerTest, RedeliveryOnFilterCallbackFalse) {}

TEST(ExceptionHandlerTest, RedeliveryOnDoneCallbackFalse) {}

TEST(ExceptionHandlerTest, NoRedeliveryOnDoneCallbackTrue) {}

TEST(ExceptionHandlerTest, NoRedeliveryOnFilterCallbackTrue) {}

TEST(ExceptionHandlerTest, RedeliveryToDefaultHandler) {}

// Check that saving and restoring the signal handler with 'signal'
// instead of 'sigaction' doesn't make the Breakpad signal handler
// crash. See comments in ExceptionHandler::SignalHandler for full
// details.
TEST(ExceptionHandlerTest, RedeliveryOnBadSignalHandlerFlag) {}

TEST(ExceptionHandlerTest, StackedHandlersDeliveredToTop) {}

TEST(ExceptionHandlerTest, StackedHandlersNotDeliveredToBottom) {}

TEST(ExceptionHandlerTest, StackedHandlersFilteredToBottom) {}

TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) {}

namespace {
const int kSimpleFirstChanceReturnStatus =;
bool SimpleFirstChanceHandler(int, siginfo_t*, void*) {}
}

TEST(ExceptionHandlerTest, FirstChanceHandlerRuns) {}

#endif  // !ADDRESS_SANITIZER

const unsigned char kIllegalInstruction[] =;

// Test that memory around the instruction pointer is written
// to the dump as a MinidumpMemoryRegion.
TEST(ExceptionHandlerTest, InstructionPointerMemory) {}

// Test that the memory region around the instruction pointer is
// bounded correctly on the low end.
TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {}

// Test that the memory region around the instruction pointer is
// bounded correctly on the high end.
TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {}

#ifndef ADDRESS_SANITIZER

// Ensure that an extra memory block doesn't get added when the instruction
// pointer is not in mapped memory.
TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) {}

#endif  // !ADDRESS_SANITIZER

// Test that anonymous memory maps can be annotated with names and IDs.
TEST(ExceptionHandlerTest, ModuleInfo) {}

#ifndef ADDRESS_SANITIZER

static const unsigned kControlMsgSize =;

static bool
CrashHandler(const void* crash_context, size_t crash_context_size,
             void* context) {}

TEST(ExceptionHandlerTest, ExternalDumper) {}

#endif  // !ADDRESS_SANITIZER

TEST(ExceptionHandlerTest, WriteMinidumpExceptionStream) {}

TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithFD) {}

TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithPath) {}

// Test that an additional memory region can be added to the minidump.
TEST(ExceptionHandlerTest, AdditionalMemory) {}

// Test that a memory region that was previously registered
// can be unregistered.
TEST(ExceptionHandlerTest, AdditionalMemoryRemove) {}

static bool SimpleCallback(const MinidumpDescriptor& descriptor,
                           void* context,
                           bool succeeded) {}

TEST(ExceptionHandlerTest, WriteMinidumpForChild) {}