diff --git a/client/crashpad_info.cc b/client/crashpad_info.cc index 596f3491..46e73210 100644 --- a/client/crashpad_info.cc +++ b/client/crashpad_info.cc @@ -98,6 +98,7 @@ CrashpadInfo::CrashpadInfo() version_(kCrashpadInfoVersion), crashpad_handler_behavior_(TriState::kUnset), system_crash_reporter_forwarding_(TriState::kUnset), + gather_indirectly_referenced_memory_(TriState::kUnset), padding_0_(0), simple_annotations_(nullptr) #if !defined(NDEBUG) && defined(OS_WIN) diff --git a/client/crashpad_info.h b/client/crashpad_info.h index 1c4997ab..377d194e 100644 --- a/client/crashpad_info.h +++ b/client/crashpad_info.h @@ -97,6 +97,22 @@ struct CrashpadInfo { system_crash_reporter_forwarding_ = system_crash_reporter_forwarding; } + //! \brief Enables or disables Crashpad capturing indirectly referenced memory + //! in the minidump. + //! + //! When handling an exception, the Crashpad handler will scan all modules in + //! a process. The first one that has a CrashpadInfo structure populated with + //! a value other than #kUnset for this field will dictate whether the extra + //! memory is captured. + //! + //! This causes Crashpad to include pages of data referenced by locals or + //! other stack memory. Turning this on can increase the size of the minidump + //! significantly. + void set_gather_indirectly_referenced_memory( + TriState gather_indirectly_referenced_memory) { + gather_indirectly_referenced_memory_ = gather_indirectly_referenced_memory; + } + enum : uint32_t { kSignature = 'CPad', }; @@ -117,7 +133,8 @@ struct CrashpadInfo { uint32_t version_; // kVersion TriState crashpad_handler_behavior_; TriState system_crash_reporter_forwarding_; - uint16_t padding_0_; + TriState gather_indirectly_referenced_memory_; + uint8_t padding_0_; SimpleStringDictionary* simple_annotations_; // weak #if !defined(NDEBUG) && defined(OS_WIN) diff --git a/snapshot/crashpad_info_client_options.cc b/snapshot/crashpad_info_client_options.cc index e19b021e..4a89d84a 100644 --- a/snapshot/crashpad_info_client_options.cc +++ b/snapshot/crashpad_info_client_options.cc @@ -38,7 +38,8 @@ TriState CrashpadInfoClientOptions::TriStateFromCrashpadInfo( CrashpadInfoClientOptions::CrashpadInfoClientOptions() : crashpad_handler_behavior(TriState::kUnset), - system_crash_reporter_forwarding(TriState::kUnset) { + system_crash_reporter_forwarding(TriState::kUnset), + gather_indirectly_referenced_memory(TriState::kUnset) { } } // namespace crashpad diff --git a/snapshot/crashpad_info_client_options.h b/snapshot/crashpad_info_client_options.h index 3f9e03da..eeb1904d 100644 --- a/snapshot/crashpad_info_client_options.h +++ b/snapshot/crashpad_info_client_options.h @@ -59,6 +59,9 @@ struct CrashpadInfoClientOptions { //! \sa CrashpadInfo::set_system_crash_reporter_forwarding() TriState system_crash_reporter_forwarding; + + //! \sa CrashpadInfo::set_gather_indirectly_referenced_memory() + TriState gather_indirectly_referenced_memory; }; } // namespace crashpad diff --git a/snapshot/crashpad_info_client_options_test.cc b/snapshot/crashpad_info_client_options_test.cc index 9c1f88b5..b6d27301 100644 --- a/snapshot/crashpad_info_client_options_test.cc +++ b/snapshot/crashpad_info_client_options_test.cc @@ -61,6 +61,7 @@ class ScopedUnsetCrashpadInfoOptions { ~ScopedUnsetCrashpadInfoOptions() { crashpad_info_->set_crashpad_handler_behavior(TriState::kUnset); crashpad_info_->set_system_crash_reporter_forwarding(TriState::kUnset); + crashpad_info_->set_gather_indirectly_referenced_memory(TriState::kUnset); } private: @@ -87,6 +88,7 @@ TEST(CrashpadInfoClientOptions, OneModule) { EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo(); ASSERT_TRUE(crashpad_info); @@ -99,6 +101,7 @@ TEST(CrashpadInfoClientOptions, OneModule) { process_snapshot.GetCrashpadOptions(&options); EXPECT_EQ(TriState::kEnabled, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); } { @@ -109,6 +112,18 @@ TEST(CrashpadInfoClientOptions, OneModule) { process_snapshot.GetCrashpadOptions(&options); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kDisabled, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); + } + + { + ScopedUnsetCrashpadInfoOptions unset(crashpad_info); + + crashpad_info->set_gather_indirectly_referenced_memory(TriState::kEnabled); + + process_snapshot.GetCrashpadOptions(&options); + EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); + EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kEnabled, options.gather_indirectly_referenced_memory); } } @@ -201,6 +216,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) { EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); // Get both CrashpadInfo structures. CrashpadInfo* local_crashpad_info = CrashpadInfo::GetCrashpadInfo(); @@ -219,6 +235,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) { process_snapshot.GetCrashpadOptions(&options); EXPECT_EQ(TriState::kEnabled, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); // When more than one module sets a value, the first one in the module list // applies to the process. The local module should appear before the remote @@ -228,6 +245,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) { process_snapshot.GetCrashpadOptions(&options); EXPECT_EQ(TriState::kDisabled, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); } { @@ -241,6 +259,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) { process_snapshot.GetCrashpadOptions(&options); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kDisabled, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); // When more than one module sets a value, the first one in the module list // applies to the process. The local module should appear before the remote @@ -251,6 +270,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) { process_snapshot.GetCrashpadOptions(&options); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kEnabled, options.system_crash_reporter_forwarding); + EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory); } } diff --git a/snapshot/mac/process_snapshot_mac.cc b/snapshot/mac/process_snapshot_mac.cc index b37123c8..0e4b3d3b 100644 --- a/snapshot/mac/process_snapshot_mac.cc +++ b/snapshot/mac/process_snapshot_mac.cc @@ -104,6 +104,10 @@ void ProcessSnapshotMac::GetCrashpadOptions( local_options.system_crash_reporter_forwarding = module_options.system_crash_reporter_forwarding; } + if (local_options.gather_indirectly_referenced_memory == TriState::kUnset) { + local_options.gather_indirectly_referenced_memory = + module_options.gather_indirectly_referenced_memory; + } // If non-default values have been found for all options, the loop can end // early. diff --git a/snapshot/win/module_snapshot_win.cc b/snapshot/win/module_snapshot_win.cc index 0553f35b..8948b2ab 100644 --- a/snapshot/win/module_snapshot_win.cc +++ b/snapshot/win/module_snapshot_win.cc @@ -202,6 +202,10 @@ void ModuleSnapshotWin::GetCrashpadOptionsInternal( options->system_crash_reporter_forwarding = CrashpadInfoClientOptions::TriStateFromCrashpadInfo( crashpad_info.system_crash_reporter_forwarding); + + options->gather_indirectly_referenced_memory = + CrashpadInfoClientOptions::TriStateFromCrashpadInfo( + crashpad_info.gather_indirectly_referenced_memory); } const VS_FIXEDFILEINFO* ModuleSnapshotWin::VSFixedFileInfo() const { diff --git a/snapshot/win/pe_image_reader.h b/snapshot/win/pe_image_reader.h index 4e9516b2..feffa8a8 100644 --- a/snapshot/win/pe_image_reader.h +++ b/snapshot/win/pe_image_reader.h @@ -41,7 +41,8 @@ struct CrashpadInfo { uint32_t version; uint8_t crashpad_handler_behavior; // TriState. uint8_t system_crash_reporter_forwarding; // TriState. - uint16_t padding_0; + uint8_t gather_indirectly_referenced_memory; // TriState. + uint8_t padding_0; typename Traits::Pointer simple_annotations; }; diff --git a/snapshot/win/process_snapshot_win.cc b/snapshot/win/process_snapshot_win.cc index 8c184c26..99e52937 100644 --- a/snapshot/win/process_snapshot_win.cc +++ b/snapshot/win/process_snapshot_win.cc @@ -119,6 +119,10 @@ void ProcessSnapshotWin::GetCrashpadOptions( local_options.system_crash_reporter_forwarding = module_options.system_crash_reporter_forwarding; } + if (local_options.gather_indirectly_referenced_memory == TriState::kUnset) { + local_options.gather_indirectly_referenced_memory = + module_options.gather_indirectly_referenced_memory; + } // If non-default values have been found for all options, the loop can end // early.