Add a field to CrashpadInfo to control indirect memory capture

Change-Id: I6467aafba5d20f8a199bab0e2476f98a5318f84a
Reviewed-on: https://chromium-review.googlesource.com/322245
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Scott Graham 2016-01-14 15:12:28 -08:00
parent e18f6a6e66
commit af3dc54f2a
9 changed files with 58 additions and 3 deletions

View File

@ -98,6 +98,7 @@ CrashpadInfo::CrashpadInfo()
version_(kCrashpadInfoVersion), version_(kCrashpadInfoVersion),
crashpad_handler_behavior_(TriState::kUnset), crashpad_handler_behavior_(TriState::kUnset),
system_crash_reporter_forwarding_(TriState::kUnset), system_crash_reporter_forwarding_(TriState::kUnset),
gather_indirectly_referenced_memory_(TriState::kUnset),
padding_0_(0), padding_0_(0),
simple_annotations_(nullptr) simple_annotations_(nullptr)
#if !defined(NDEBUG) && defined(OS_WIN) #if !defined(NDEBUG) && defined(OS_WIN)

View File

@ -97,6 +97,22 @@ struct CrashpadInfo {
system_crash_reporter_forwarding_ = system_crash_reporter_forwarding; 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 { enum : uint32_t {
kSignature = 'CPad', kSignature = 'CPad',
}; };
@ -117,7 +133,8 @@ struct CrashpadInfo {
uint32_t version_; // kVersion uint32_t version_; // kVersion
TriState crashpad_handler_behavior_; TriState crashpad_handler_behavior_;
TriState system_crash_reporter_forwarding_; TriState system_crash_reporter_forwarding_;
uint16_t padding_0_; TriState gather_indirectly_referenced_memory_;
uint8_t padding_0_;
SimpleStringDictionary* simple_annotations_; // weak SimpleStringDictionary* simple_annotations_; // weak
#if !defined(NDEBUG) && defined(OS_WIN) #if !defined(NDEBUG) && defined(OS_WIN)

View File

@ -38,7 +38,8 @@ TriState CrashpadInfoClientOptions::TriStateFromCrashpadInfo(
CrashpadInfoClientOptions::CrashpadInfoClientOptions() CrashpadInfoClientOptions::CrashpadInfoClientOptions()
: crashpad_handler_behavior(TriState::kUnset), : 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 } // namespace crashpad

View File

@ -59,6 +59,9 @@ struct CrashpadInfoClientOptions {
//! \sa CrashpadInfo::set_system_crash_reporter_forwarding() //! \sa CrashpadInfo::set_system_crash_reporter_forwarding()
TriState system_crash_reporter_forwarding; TriState system_crash_reporter_forwarding;
//! \sa CrashpadInfo::set_gather_indirectly_referenced_memory()
TriState gather_indirectly_referenced_memory;
}; };
} // namespace crashpad } // namespace crashpad

View File

@ -61,6 +61,7 @@ class ScopedUnsetCrashpadInfoOptions {
~ScopedUnsetCrashpadInfoOptions() { ~ScopedUnsetCrashpadInfoOptions() {
crashpad_info_->set_crashpad_handler_behavior(TriState::kUnset); crashpad_info_->set_crashpad_handler_behavior(TriState::kUnset);
crashpad_info_->set_system_crash_reporter_forwarding(TriState::kUnset); crashpad_info_->set_system_crash_reporter_forwarding(TriState::kUnset);
crashpad_info_->set_gather_indirectly_referenced_memory(TriState::kUnset);
} }
private: private:
@ -87,6 +88,7 @@ TEST(CrashpadInfoClientOptions, OneModule) {
EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding);
EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory);
CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo(); CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo();
ASSERT_TRUE(crashpad_info); ASSERT_TRUE(crashpad_info);
@ -99,6 +101,7 @@ TEST(CrashpadInfoClientOptions, OneModule) {
process_snapshot.GetCrashpadOptions(&options); process_snapshot.GetCrashpadOptions(&options);
EXPECT_EQ(TriState::kEnabled, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kEnabled, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); 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); process_snapshot.GetCrashpadOptions(&options);
EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kDisabled, options.system_crash_reporter_forwarding); 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.crashpad_handler_behavior);
EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding);
EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory);
// Get both CrashpadInfo structures. // Get both CrashpadInfo structures.
CrashpadInfo* local_crashpad_info = CrashpadInfo::GetCrashpadInfo(); CrashpadInfo* local_crashpad_info = CrashpadInfo::GetCrashpadInfo();
@ -219,6 +235,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) {
process_snapshot.GetCrashpadOptions(&options); process_snapshot.GetCrashpadOptions(&options);
EXPECT_EQ(TriState::kEnabled, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kEnabled, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); 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 // 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 // applies to the process. The local module should appear before the remote
@ -228,6 +245,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) {
process_snapshot.GetCrashpadOptions(&options); process_snapshot.GetCrashpadOptions(&options);
EXPECT_EQ(TriState::kDisabled, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kDisabled, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kUnset, options.system_crash_reporter_forwarding); 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); process_snapshot.GetCrashpadOptions(&options);
EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kDisabled, options.system_crash_reporter_forwarding); 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 // 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 // applies to the process. The local module should appear before the remote
@ -251,6 +270,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) {
process_snapshot.GetCrashpadOptions(&options); process_snapshot.GetCrashpadOptions(&options);
EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior); EXPECT_EQ(TriState::kUnset, options.crashpad_handler_behavior);
EXPECT_EQ(TriState::kEnabled, options.system_crash_reporter_forwarding); EXPECT_EQ(TriState::kEnabled, options.system_crash_reporter_forwarding);
EXPECT_EQ(TriState::kUnset, options.gather_indirectly_referenced_memory);
} }
} }

View File

@ -104,6 +104,10 @@ void ProcessSnapshotMac::GetCrashpadOptions(
local_options.system_crash_reporter_forwarding = local_options.system_crash_reporter_forwarding =
module_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 // If non-default values have been found for all options, the loop can end
// early. // early.

View File

@ -202,6 +202,10 @@ void ModuleSnapshotWin::GetCrashpadOptionsInternal(
options->system_crash_reporter_forwarding = options->system_crash_reporter_forwarding =
CrashpadInfoClientOptions::TriStateFromCrashpadInfo( CrashpadInfoClientOptions::TriStateFromCrashpadInfo(
crashpad_info.system_crash_reporter_forwarding); 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 { const VS_FIXEDFILEINFO* ModuleSnapshotWin::VSFixedFileInfo() const {

View File

@ -41,7 +41,8 @@ struct CrashpadInfo {
uint32_t version; uint32_t version;
uint8_t crashpad_handler_behavior; // TriState. uint8_t crashpad_handler_behavior; // TriState.
uint8_t system_crash_reporter_forwarding; // 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; typename Traits::Pointer simple_annotations;
}; };

View File

@ -119,6 +119,10 @@ void ProcessSnapshotWin::GetCrashpadOptions(
local_options.system_crash_reporter_forwarding = local_options.system_crash_reporter_forwarding =
module_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 // If non-default values have been found for all options, the loop can end
// early. // early.