blob: 961814dee03ffc5d378e3102447a1abb027be5f8 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_GWP_ASAN_CRASH_HANDLER_CRASH_ANALYZER_H_
#define COMPONENTS_GWP_ASAN_CRASH_HANDLER_CRASH_ANALYZER_H_
#include <stddef.h>
#include "base/gtest_prod_util.h"
#include "components/gwp_asan/common/allocator_state.h"
#include "components/gwp_asan/crash_handler/crash.pb.h"
#include "third_party/crashpad/crashpad/util/misc/address_types.h"
namespace crashpad {
class ExceptionSnapshot;
class ProcessMemory;
class ProcessSnapshot;
} // namespace crashpad
namespace gwp_asan {
namespace internal {
class CrashAnalyzer {
public:
// Captures the result of the GWP-ASan crash analyzer, whether the crash is
// determined to be related or unrelated to GWP-ASan or if an error was
// encountered analyzing the exception.
//
// These values are persisted via UMA--entries should not be renumbered and
// numeric values should never be reused.
enum class GwpAsanCrashAnalysisResult {
// The crash is not caused by GWP-ASan.
kUnrelatedCrash = 0,
// The crash is caused by GWP-ASan.
kGwpAsanCrash = 1,
// The ProcessMemory from the snapshot was null.
kErrorNullProcessMemory = 2,
// Failed to read the crashing process' memory of the global allocator.
kErrorFailedToReadAllocator = 3,
// The crashing process' global allocator members failed sanity checks.
kErrorAllocatorFailedSanityCheck = 4,
// Failed to read crash stack traces.
kErrorFailedToReadStackTrace = 5,
// The ExceptionSnapshot CPU context was null.
kErrorNullCpuContext = 6,
// The crashing process' bitness does not match the crash handler.
kErrorMismatchedBitness = 7,
// The allocator computed an invalid slot index.
kErrorBadSlot = 8,
// Failed to read the crashing process' memory of the SlotMetadata.
kErrorFailedToReadSlotMetadata = 9,
// The allocator stored an invalid metadata index for a given slot.
kErrorBadMetadataIndex = 10,
// The computed metadata index was outdated.
kErrorOutdatedMetadataIndex = 11,
// Failed to read the crashing process' slot to metadata mapping.
kErrorFailedToReadSlotMetadataMapping = 12,
// Number of values in this enumeration, required by UMA.
kMaxValue = kErrorFailedToReadSlotMetadataMapping
};
// Given a ProcessSnapshot, determine if the exception is related to GWP-ASan.
// If it is, return kGwpAsanCrash and fill out the info parameter with
// details about the exception. Otherwise, return a value indicating that the
// crash is unrelated or that an error occured.
static GwpAsanCrashAnalysisResult GetExceptionInfo(
const crashpad::ProcessSnapshot& process_snapshot,
gwp_asan::Crash* proto);
private:
using SlotMetadata = AllocatorState::SlotMetadata;
// Given an ExceptionSnapshot, return the address of where the exception
// occurred (or null if it was not a data access exception.)
static crashpad::VMAddress GetAccessAddress(
const crashpad::ExceptionSnapshot& exception);
// If the allocator annotation is present in the given snapshot, then return
// the address for the GuardedPageAllocator in the crashing process.
static crashpad::VMAddress GetAllocatorAddress(
const crashpad::ProcessSnapshot& process_snapshot);
// This method implements the underlying logic for GetExceptionInfo(). It
// analyzes the GuardedPageAllocator of the crashing process, and if the
// exception occurred in the GWP-ASan region it fills out the protobuf
// parameter and returns kGwpAsanCrash.
static GwpAsanCrashAnalysisResult AnalyzeCrashedAllocator(
const crashpad::ProcessMemory& memory,
const crashpad::ExceptionSnapshot& exception,
crashpad::VMAddress gpa_addr,
gwp_asan::Crash* proto);
// This method fills out an AllocationInfo protobuf from a stack trace
// and a SlotMetadata::AllocationInfo struct.
static void ReadAllocationInfo(const uint8_t* stack_trace,
size_t stack_trace_offset,
const SlotMetadata::AllocationInfo& slot_info,
gwp_asan::Crash_AllocationInfo* proto_info);
FRIEND_TEST_ALL_PREFIXES(CrashAnalyzerTest, StackTraceCollection);
};
} // namespace internal
} // namespace gwp_asan
#endif // COMPONENTS_GWP_ASAN_CRASH_HANDLER_CRASH_ANALYZER_H_