Skip to content

Commit

Permalink
GWP-ASan: Refactor CrashAnalyzerTest
Browse files Browse the repository at this point in the history
Refactor the CrashAnalyzerTests to use CrashAnalyzer::GetExceptionInfo()
instead of AnalyzeCrashedAllocator()--this is in anticipation of an
upcoming refactor. There is no functional change, but it does have the
benefit of having these tests use the public interface instead of a
private internal method.

Bug: 960532
Change-Id: I19cf964e15f08c0b6444103087acb050b63da228
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1611201
Commit-Queue: Vlad Tsyrklevich <vtsyrklevich@chromium.org>
Auto-Submit: Vlad Tsyrklevich <vtsyrklevich@chromium.org>
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#659334}
  • Loading branch information
vlad902 authored and Commit Bot committed May 14, 2019
1 parent 20f3bc4 commit 8109ebd
Showing 1 changed file with 64 additions and 13 deletions.
77 changes: 64 additions & 13 deletions components/gwp_asan/crash_handler/crash_analyzer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,72 @@

#include "components/gwp_asan/crash_handler/crash_analyzer.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/debug/stack_trace.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "build/build_config.h"
#include "components/gwp_asan/client/guarded_page_allocator.h"
#include "components/gwp_asan/common/allocator_state.h"
#include "components/gwp_asan/common/crash_key_name.h"
#include "components/gwp_asan/crash_handler/crash.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/crashpad/crashpad/client/annotation.h"
#include "third_party/crashpad/crashpad/snapshot/annotation_snapshot.h"
#include "third_party/crashpad/crashpad/snapshot/cpu_context.h"
#include "third_party/crashpad/crashpad/snapshot/test/test_exception_snapshot.h"
#include "third_party/crashpad/crashpad/snapshot/test/test_module_snapshot.h"
#include "third_party/crashpad/crashpad/snapshot/test/test_process_snapshot.h"
#include "third_party/crashpad/crashpad/test/process_type.h"
#include "third_party/crashpad/crashpad/util/process/process_memory_native.h"

namespace gwp_asan {
namespace internal {

namespace {

// Initializes this ProcessSnapshot so that it appears the given allocator was
// used for backing malloc.
void InitializeSnapshot(crashpad::test::TestProcessSnapshot* process_snapshot,
const GuardedPageAllocator& gpa) {
std::string crash_key_value = gpa.GetCrashKey();
std::vector<uint8_t> crash_key_vector(crash_key_value.begin(),
crash_key_value.end());

std::vector<crashpad::AnnotationSnapshot> annotations;
annotations.emplace_back(
kMallocCrashKey,
static_cast<uint16_t>(crashpad::Annotation::Type::kString),
crash_key_vector);

auto module = std::make_unique<crashpad::test::TestModuleSnapshot>();
module->SetAnnotationObjects(annotations);

auto exception = std::make_unique<crashpad::test::TestExceptionSnapshot>();
// Just match the bitness, the actual architecture doesn't matter.
#if defined(ARCH_CPU_64_BITS)
exception->MutableContext()->architecture =
crashpad::CPUArchitecture::kCPUArchitectureX86_64;
#else
exception->MutableContext()->architecture =
crashpad::CPUArchitecture::kCPUArchitectureX86;
#endif

auto memory = std::make_unique<crashpad::ProcessMemoryNative>();
ASSERT_TRUE(memory->Initialize(crashpad::test::GetSelfProcess()));

process_snapshot->AddModule(std::move(module));
process_snapshot->SetException(std::move(exception));
process_snapshot->SetProcessMemory(std::move(memory));
}

} // namespace

TEST(CrashAnalyzerTest, StackTraceCollection) {
GuardedPageAllocator gpa;
gpa.Init(1, 1, 1);
Expand All @@ -27,17 +78,17 @@ TEST(CrashAnalyzerTest, StackTraceCollection) {
ASSERT_NE(ptr, nullptr);
gpa.Deallocate(ptr);

crashpad::ProcessMemoryNative memory;
ASSERT_TRUE(memory.Initialize(crashpad::test::GetSelfProcess()));

// Lets pretend a double free() occurred on the allocation we saw previously.
crashpad::test::TestExceptionSnapshot exception_snapshot;
gpa.state_.double_free_address = reinterpret_cast<uintptr_t>(ptr);

crashpad::test::TestProcessSnapshot process_snapshot;
InitializeSnapshot(&process_snapshot, gpa);

base::HistogramTester histogram_tester;
gwp_asan::Crash proto;
CrashAnalyzer::AnalyzeCrashedAllocator(
memory, exception_snapshot, reinterpret_cast<uintptr_t>(&gpa), &proto);
bool proto_present =
CrashAnalyzer::GetExceptionInfo(process_snapshot, &proto);
ASSERT_TRUE(proto_present);

histogram_tester.ExpectTotalCount(CrashAnalyzer::kCrashAnalysisHistogram, 0);

Expand Down Expand Up @@ -85,21 +136,21 @@ TEST(CrashAnalyzerTest, InternalError) {
GuardedPageAllocator gpa;
gpa.Init(1, 1, 1);

crashpad::ProcessMemoryNative memory;
ASSERT_TRUE(memory.Initialize(crashpad::test::GetSelfProcess()));

// Lets pretend a invalid free() occurred in the allocator region.
crashpad::test::TestExceptionSnapshot exception_snapshot;
// Lets pretend an invalid free() occurred in the allocator region.
gpa.state_.free_invalid_address =
reinterpret_cast<uintptr_t>(gpa.state_.first_page_addr);
// Out of bounds slot_to_metadata_idx, allocator was initialized with only a
// single entry slot/metadata entry.
gpa.slot_to_metadata_idx_[0] = 5;

crashpad::test::TestProcessSnapshot process_snapshot;
InitializeSnapshot(&process_snapshot, gpa);

base::HistogramTester histogram_tester;
gwp_asan::Crash proto;
CrashAnalyzer::AnalyzeCrashedAllocator(
memory, exception_snapshot, reinterpret_cast<uintptr_t>(&gpa), &proto);
bool proto_present =
CrashAnalyzer::GetExceptionInfo(process_snapshot, &proto);
ASSERT_TRUE(proto_present);

int result = static_cast<int>(
CrashAnalyzer::GwpAsanCrashAnalysisResult::kErrorBadMetadataIndex);
Expand Down

0 comments on commit 8109ebd

Please sign in to comment.