diff --git a/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc b/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc index 98da9ccae7584b..60c3084d357d36 100644 --- a/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc +++ b/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc @@ -4,21 +4,72 @@ #include "components/gwp_asan/crash_handler/crash_analyzer.h" +#include +#include +#include +#include + #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 crash_key_vector(crash_key_value.begin(), + crash_key_value.end()); + + std::vector annotations; + annotations.emplace_back( + kMallocCrashKey, + static_cast(crashpad::Annotation::Type::kString), + crash_key_vector); + + auto module = std::make_unique(); + module->SetAnnotationObjects(annotations); + + auto exception = std::make_unique(); + // 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(); + 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); @@ -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(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(&gpa), &proto); + bool proto_present = + CrashAnalyzer::GetExceptionInfo(process_snapshot, &proto); + ASSERT_TRUE(proto_present); histogram_tester.ExpectTotalCount(CrashAnalyzer::kCrashAnalysisHistogram, 0); @@ -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(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(&gpa), &proto); + bool proto_present = + CrashAnalyzer::GetExceptionInfo(process_snapshot, &proto); + ASSERT_TRUE(proto_present); int result = static_cast( CrashAnalyzer::GwpAsanCrashAnalysisResult::kErrorBadMetadataIndex);