mirror of
https://github.com/chromium/crashpad.git
synced 2025-01-14 01:08:01 +08:00
Add MinidumpMiscInfoWriter::InitializeFromSnapshot() and its test.
TEST=minidump_test MinidumpMiscInfoWriter.InitializeFromSnapshot R=rsesek@chromium.org Review URL: https://codereview.chromium.org/701783004
This commit is contained in:
parent
8609cdb60d
commit
bdfd147a47
@ -14,14 +14,122 @@
|
||||
|
||||
#include "minidump/minidump_misc_info_writer.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
#include "minidump/minidump_writer_util.h"
|
||||
#include "package.h"
|
||||
#include "snapshot/process_snapshot.h"
|
||||
#include "snapshot/system_snapshot.h"
|
||||
#include "util/file/file_writer.h"
|
||||
#include "util/numeric/in_range_cast.h"
|
||||
#include "util/numeric/safe_assignment.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
namespace crashpad {
|
||||
namespace {
|
||||
|
||||
uint32_t TimevalToRoundedSeconds(const timeval& tv) {
|
||||
uint32_t seconds =
|
||||
InRangeCast<uint32_t>(tv.tv_sec, std::numeric_limits<uint32_t>::max());
|
||||
const int kMicrosecondsPerSecond = 1E6;
|
||||
if (tv.tv_usec >= kMicrosecondsPerSecond / 2 &&
|
||||
seconds != std::numeric_limits<uint32_t>::max()) {
|
||||
++seconds;
|
||||
}
|
||||
return seconds;
|
||||
}
|
||||
|
||||
// For MINIDUMP_MISC_INFO_4::BuildString. dbghelp only places OS version
|
||||
// information here, but if a machine description is also available, this is the
|
||||
// only reasonable place in a minidump file to put it.
|
||||
std::string BuildString(const SystemSnapshot* system_snapshot) {
|
||||
std::string os_version_full = system_snapshot->OSVersionFull();
|
||||
std::string machine_description = system_snapshot->MachineDescription();
|
||||
if (!os_version_full.empty()) {
|
||||
if (!machine_description.empty()) {
|
||||
return base::StringPrintf(
|
||||
"%s; %s", os_version_full.c_str(), machine_description.c_str());
|
||||
}
|
||||
return os_version_full;
|
||||
}
|
||||
return machine_description;
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Converts the value of the MAC_OS_VERSION_MIN_REQUIRED or
|
||||
// MAC_OS_X_VERSION_MAX_ALLOWED macro from <AvailabilityMacros.h> to a number
|
||||
// identifying the minor Mac OS X version that it represents. For example, with
|
||||
// an argument of MAC_OS_X_VERSION_10_6, this function will return 6.
|
||||
int AvailabilityVersionToMacOSXMinorVersion(int availability) {
|
||||
// Through MAC_OS_X_VERSION_10_9, the minor version is the tens digit.
|
||||
if (availability >= 1000 && availability <= 1099) {
|
||||
return (availability / 10) % 10;
|
||||
}
|
||||
|
||||
// After MAC_OS_X_VERSION_10_9, the older format was insufficient to represent
|
||||
// versions. Since then, the minor version is the thousands and hundreds
|
||||
// digits.
|
||||
if (availability >= 100000 && availability <= 109999) {
|
||||
return (availability / 100) % 100;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
// For MINIDUMP_MISC_INFO_4::DbgBldStr. dbghelp produces strings like
|
||||
// “dbghelp.i386,6.3.9600.16520” and “dbghelp.amd64,6.3.9600.16520”. Mimic that
|
||||
// format, and add the OS that wrote the minidump along with any relevant
|
||||
// platform-specific data describing the compilation environment.
|
||||
std::string MinidumpMiscInfoDebugBuildString() {
|
||||
// Caution: the minidump file format only has room for 39 UTF-16 code units
|
||||
// plus a UTF-16 NUL terminator. Don’t let strings get longer than this, or
|
||||
// they will be truncated and a message will be logged.
|
||||
#if defined(OS_MACOSX)
|
||||
const char kOS[] = "mac";
|
||||
#elif defined(OS_LINUX)
|
||||
const char kOS[] = "linux";
|
||||
#else
|
||||
#error define kOS for this operating system
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_CPU_X86)
|
||||
const char kCPU[] = "i386";
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
const char kCPU[] = "amd64";
|
||||
#else
|
||||
#error define kCPU for this CPU
|
||||
#endif
|
||||
|
||||
std::string debug_build_string = base::StringPrintf("%s.%s,%s,%s",
|
||||
PACKAGE_TARNAME,
|
||||
kCPU,
|
||||
PACKAGE_VERSION,
|
||||
kOS);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
debug_build_string += base::StringPrintf(
|
||||
",%d,%d",
|
||||
AvailabilityVersionToMacOSXMinorVersion(MAC_OS_X_VERSION_MIN_REQUIRED),
|
||||
AvailabilityVersionToMacOSXMinorVersion(MAC_OS_X_VERSION_MAX_ALLOWED));
|
||||
#endif
|
||||
|
||||
return debug_build_string;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
MinidumpMiscInfoWriter::MinidumpMiscInfoWriter()
|
||||
: MinidumpStreamWriter(), misc_info_() {
|
||||
@ -30,7 +138,78 @@ MinidumpMiscInfoWriter::MinidumpMiscInfoWriter()
|
||||
MinidumpMiscInfoWriter::~MinidumpMiscInfoWriter() {
|
||||
}
|
||||
|
||||
void MinidumpMiscInfoWriter::SetProcessId(uint32_t process_id) {
|
||||
void MinidumpMiscInfoWriter::InitializeFromSnapshot(
|
||||
const ProcessSnapshot* process_snapshot) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK_EQ(misc_info_.Flags1, 0u);
|
||||
|
||||
SetProcessID(InRangeCast<uint32_t>(process_snapshot->ProcessID(), 0));
|
||||
|
||||
const SystemSnapshot* system_snapshot = process_snapshot->System();
|
||||
|
||||
uint64_t current_mhz;
|
||||
uint64_t max_mhz;
|
||||
system_snapshot->CPUFrequency(¤t_mhz, &max_mhz);
|
||||
const uint32_t kHzPerMHz = 1E6;
|
||||
SetProcessorPowerInfo(
|
||||
InRangeCast<uint32_t>(current_mhz / kHzPerMHz,
|
||||
std::numeric_limits<uint32_t>::max()),
|
||||
InRangeCast<uint32_t>(max_mhz / kHzPerMHz,
|
||||
std::numeric_limits<uint32_t>::max()),
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
timeval start_time;
|
||||
process_snapshot->ProcessStartTime(&start_time);
|
||||
|
||||
timeval user_time;
|
||||
timeval system_time;
|
||||
process_snapshot->ProcessCPUTimes(&user_time, &system_time);
|
||||
|
||||
// Round the resource usage fields to the nearest second, because the minidump
|
||||
// format only has one-second resolution. The start_time field is truncated
|
||||
// instead of rounded so that the process uptime is reflected more accurately
|
||||
// when the start time is compared to the snapshot time in the
|
||||
// MINIDUMP_HEADER, which is also truncated, not rounded.
|
||||
uint32_t user_seconds = TimevalToRoundedSeconds(user_time);
|
||||
uint32_t system_seconds = TimevalToRoundedSeconds(system_time);
|
||||
|
||||
SetProcessTimes(start_time.tv_sec, user_seconds, system_seconds);
|
||||
|
||||
// This determines the system’s time zone, which may be different than the
|
||||
// process’ notion of the time zone.
|
||||
SystemSnapshot::DaylightSavingTimeStatus dst_status;
|
||||
int standard_offset_seconds;
|
||||
int daylight_offset_seconds;
|
||||
std::string standard_name;
|
||||
std::string daylight_name;
|
||||
system_snapshot->TimeZone(&dst_status,
|
||||
&standard_offset_seconds,
|
||||
&daylight_offset_seconds,
|
||||
&standard_name,
|
||||
&daylight_name);
|
||||
|
||||
// standard_offset_seconds is seconds east of UTC, but the minidump file wants
|
||||
// minutes west of UTC. daylight_offset_seconds is also seconds east of UTC,
|
||||
// but the minidump file wants minutes west of the standard offset. The empty
|
||||
// ({}) arguments are for the transition times in and out of daylight saving
|
||||
// time. These are not determined because no API exists to do so, and the
|
||||
// transition times may vary from year to year.
|
||||
SetTimeZone(dst_status,
|
||||
standard_offset_seconds / -60,
|
||||
standard_name,
|
||||
{},
|
||||
0,
|
||||
daylight_name,
|
||||
{},
|
||||
(standard_offset_seconds - daylight_offset_seconds) / 60);
|
||||
|
||||
SetBuildString(BuildString(system_snapshot),
|
||||
internal::MinidumpMiscInfoDebugBuildString());
|
||||
}
|
||||
|
||||
void MinidumpMiscInfoWriter::SetProcessID(uint32_t process_id) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
misc_info_.ProcessId = process_id;
|
||||
|
@ -28,6 +28,24 @@
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
class ProcessSnapshot;
|
||||
|
||||
namespace internal {
|
||||
|
||||
//! \brief Returns the string to set in MINIDUMP_MISC_INFO_4::DbgBldStr.
|
||||
//!
|
||||
//! dbghelp produces strings like `"dbghelp.i386,6.3.9600.16520"` and
|
||||
//! `"dbghelp.amd64,6.3.9600.16520"`. This function mimics that format, and adds
|
||||
//! the OS that wrote the minidump along with any relevant platform-specific
|
||||
//! data describing the compilation environment.
|
||||
//!
|
||||
//! This function is an implementation detail of
|
||||
//! MinidumpMiscInfoWriter::InitializeFromSnapshot() and is only exposed for
|
||||
//! testing purposes.
|
||||
std::string MinidumpMiscInfoDebugBuildString();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
//! \brief The writer for a stream in the MINIDUMP_MISC_INFO family in a
|
||||
//! minidump file.
|
||||
//!
|
||||
@ -41,8 +59,17 @@ class MinidumpMiscInfoWriter final : public internal::MinidumpStreamWriter {
|
||||
MinidumpMiscInfoWriter();
|
||||
~MinidumpMiscInfoWriter() override;
|
||||
|
||||
//! \brief Initializes MINIDUMP_MISC_INFO_N based on \a process_snapshot.
|
||||
//!
|
||||
//! \param[in] process_snapshot The process snapshot to use as source data.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable. No mutator methods may be called before
|
||||
//! this method, and it is not normally necessary to call any mutator
|
||||
//! methods after this method.
|
||||
void InitializeFromSnapshot(const ProcessSnapshot* process_snapshot);
|
||||
|
||||
//! \brief Sets the field referenced by #MINIDUMP_MISC1_PROCESS_ID.
|
||||
void SetProcessId(uint32_t process_id);
|
||||
void SetProcessID(uint32_t process_id);
|
||||
|
||||
//! \brief Sets the fields referenced by #MINIDUMP_MISC1_PROCESS_TIMES.
|
||||
void SetProcessTimes(time_t process_create_time,
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
#include "snapshot/test/test_process_snapshot.h"
|
||||
#include "snapshot/test/test_system_snapshot.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
#include "util/stdlib/strlcpy.h"
|
||||
|
||||
@ -177,7 +179,7 @@ TEST(MinidumpMiscInfoWriter, ProcessId) {
|
||||
|
||||
const uint32_t kProcessId = 12345;
|
||||
|
||||
misc_info_writer->SetProcessId(kProcessId);
|
||||
misc_info_writer->SetProcessID(kProcessId);
|
||||
|
||||
minidump_file_writer.AddStream(misc_info_writer.Pass());
|
||||
|
||||
@ -535,7 +537,7 @@ TEST(MinidumpMiscInfoWriter, Everything) {
|
||||
const char kBuildString[] = "build string";
|
||||
const char kDebugBuildString[] = "debug build string";
|
||||
|
||||
misc_info_writer->SetProcessId(kProcessId);
|
||||
misc_info_writer->SetProcessID(kProcessId);
|
||||
misc_info_writer->SetProcessTimes(
|
||||
kProcessCreateTime, kProcessUserTime, kProcessKernelTime);
|
||||
misc_info_writer->SetProcessorPowerInfo(kProcessorMaxMhz,
|
||||
@ -612,6 +614,94 @@ TEST(MinidumpMiscInfoWriter, Everything) {
|
||||
ExpectMiscInfoEqual(&expected, observed);
|
||||
}
|
||||
|
||||
TEST(MinidumpMiscInfoWriter, InitializeFromSnapshot) {
|
||||
MINIDUMP_MISC_INFO_4 expect_misc_info = {};
|
||||
|
||||
const char kStandardTimeName[] = "EST";
|
||||
const char kDaylightTimeName[] = "EDT";
|
||||
const char kOSVersionFull[] =
|
||||
"Mac OS X 10.9.5 (13F34); "
|
||||
"Darwin 13.4.0 Darwin Kernel Version 13.4.0: "
|
||||
"Sun Aug 17 19:50:11 PDT 2014; "
|
||||
"root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64";
|
||||
const char kMachineDescription[] = "MacBookPro11,3 (Mac-2BD1B31983FE1663)";
|
||||
string16 standard_time_name_utf16 = base::UTF8ToUTF16(kStandardTimeName);
|
||||
string16 daylight_time_name_utf16 = base::UTF8ToUTF16(kDaylightTimeName);
|
||||
string16 build_string_utf16 = base::UTF8ToUTF16(
|
||||
std::string(kOSVersionFull) + "; " + kMachineDescription);
|
||||
std::string debug_build_string = internal::MinidumpMiscInfoDebugBuildString();
|
||||
EXPECT_FALSE(debug_build_string.empty());
|
||||
string16 debug_build_string_utf16 = base::UTF8ToUTF16(debug_build_string);
|
||||
|
||||
expect_misc_info.SizeOfInfo = sizeof(expect_misc_info);
|
||||
expect_misc_info.Flags1 = MINIDUMP_MISC1_PROCESS_ID |
|
||||
MINIDUMP_MISC1_PROCESS_TIMES |
|
||||
MINIDUMP_MISC1_PROCESSOR_POWER_INFO |
|
||||
MINIDUMP_MISC3_TIMEZONE |
|
||||
MINIDUMP_MISC4_BUILDSTRING;
|
||||
expect_misc_info.ProcessId = 12345;
|
||||
expect_misc_info.ProcessCreateTime = 0x555c7740;
|
||||
expect_misc_info.ProcessUserTime = 60;
|
||||
expect_misc_info.ProcessKernelTime = 15;
|
||||
expect_misc_info.ProcessorCurrentMhz = 2800;
|
||||
expect_misc_info.ProcessorMaxMhz = 2800;
|
||||
expect_misc_info.TimeZoneId = 1;
|
||||
expect_misc_info.TimeZone.Bias = 300;
|
||||
c16lcpy(expect_misc_info.TimeZone.StandardName,
|
||||
standard_time_name_utf16.c_str(),
|
||||
arraysize(expect_misc_info.TimeZone.StandardName));
|
||||
expect_misc_info.TimeZone.StandardBias = 0;
|
||||
c16lcpy(expect_misc_info.TimeZone.DaylightName,
|
||||
daylight_time_name_utf16.c_str(),
|
||||
arraysize(expect_misc_info.TimeZone.DaylightName));
|
||||
expect_misc_info.TimeZone.DaylightBias = -60;
|
||||
c16lcpy(expect_misc_info.BuildString,
|
||||
build_string_utf16.c_str(),
|
||||
arraysize(expect_misc_info.BuildString));
|
||||
c16lcpy(expect_misc_info.DbgBldStr,
|
||||
debug_build_string_utf16.c_str(),
|
||||
arraysize(expect_misc_info.DbgBldStr));
|
||||
|
||||
const timeval kStartTime = { expect_misc_info.ProcessCreateTime, 0 };
|
||||
const timeval kUserCPUTime = { expect_misc_info.ProcessUserTime, 0 };
|
||||
const timeval kSystemCPUTime = { expect_misc_info.ProcessKernelTime, 0 };
|
||||
|
||||
TestProcessSnapshot process_snapshot;
|
||||
process_snapshot.SetProcessID(expect_misc_info.ProcessId);
|
||||
process_snapshot.SetProcessStartTime(kStartTime);
|
||||
process_snapshot.SetProcessCPUTimes(kUserCPUTime, kSystemCPUTime);
|
||||
|
||||
auto system_snapshot = make_scoped_ptr(new TestSystemSnapshot());
|
||||
const uint64_t kHzPerMHz = 1E6;
|
||||
system_snapshot->SetCPUFrequency(
|
||||
expect_misc_info.ProcessorCurrentMhz * kHzPerMHz,
|
||||
expect_misc_info.ProcessorMaxMhz * kHzPerMHz);
|
||||
system_snapshot->SetTimeZone(SystemSnapshot::kObservingStandardTime,
|
||||
expect_misc_info.TimeZone.Bias * -60,
|
||||
(expect_misc_info.TimeZone.Bias +
|
||||
expect_misc_info.TimeZone.DaylightBias) * -60,
|
||||
kStandardTimeName,
|
||||
kDaylightTimeName);
|
||||
system_snapshot->SetOSVersionFull(kOSVersionFull);
|
||||
system_snapshot->SetMachineDescription(kMachineDescription);
|
||||
|
||||
process_snapshot.SetSystem(system_snapshot.Pass());
|
||||
|
||||
auto misc_info_writer = make_scoped_ptr(new MinidumpMiscInfoWriter());
|
||||
misc_info_writer->InitializeFromSnapshot(&process_snapshot);
|
||||
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
minidump_file_writer.AddStream(misc_info_writer.Pass());
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MINIDUMP_MISC_INFO_4* misc_info;
|
||||
ASSERT_NO_FATAL_FAILURE(GetMiscInfoStream(file_writer.string(), &misc_info));
|
||||
|
||||
ExpectMiscInfoEqual(&expect_misc_info, misc_info);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
@ -339,7 +339,6 @@ TEST(MinidumpSystemInfoWriter, InitializeFromSnapshot_X86) {
|
||||
|
||||
const MINIDUMP_SYSTEM_INFO* system_info;
|
||||
const MINIDUMP_STRING* csd_version;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(GetSystemInfoStream(file_writer.string(),
|
||||
strlen(kOSVersionBuild),
|
||||
&system_info,
|
||||
|
@ -94,6 +94,8 @@
|
||||
'test/test_memory_snapshot.h',
|
||||
'test/test_module_snapshot.cc',
|
||||
'test/test_module_snapshot.h',
|
||||
'test/test_process_snapshot.cc',
|
||||
'test/test_process_snapshot.h',
|
||||
'test/test_system_snapshot.cc',
|
||||
'test/test_system_snapshot.h',
|
||||
'test/test_thread_snapshot.cc',
|
||||
|
87
snapshot/test/test_process_snapshot.cc
Normal file
87
snapshot/test/test_process_snapshot.cc
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/exception_snapshot.h"
|
||||
#include "snapshot/module_snapshot.h"
|
||||
#include "snapshot/system_snapshot.h"
|
||||
#include "snapshot/test/test_process_snapshot.h"
|
||||
#include "snapshot/thread_snapshot.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
TestProcessSnapshot::TestProcessSnapshot()
|
||||
: process_id_(0),
|
||||
parent_process_id_(0),
|
||||
snapshot_time_(),
|
||||
process_start_time_(),
|
||||
process_cpu_user_time_(),
|
||||
process_cpu_system_time_(),
|
||||
system_(),
|
||||
threads_(),
|
||||
modules_(),
|
||||
exception_() {
|
||||
}
|
||||
|
||||
TestProcessSnapshot::~TestProcessSnapshot() {
|
||||
}
|
||||
|
||||
pid_t TestProcessSnapshot::ProcessID() const {
|
||||
return process_id_;
|
||||
}
|
||||
|
||||
pid_t TestProcessSnapshot::ParentProcessID() const {
|
||||
return parent_process_id_;
|
||||
}
|
||||
|
||||
void TestProcessSnapshot::SnapshotTime(timeval* snapshot_time) const {
|
||||
*snapshot_time = snapshot_time_;
|
||||
}
|
||||
|
||||
void TestProcessSnapshot::ProcessStartTime(timeval* start_time) const {
|
||||
*start_time = process_start_time_;
|
||||
}
|
||||
|
||||
void TestProcessSnapshot::ProcessCPUTimes(timeval* user_time,
|
||||
timeval* system_time) const {
|
||||
*user_time = process_cpu_user_time_;
|
||||
*system_time = process_cpu_system_time_;
|
||||
}
|
||||
|
||||
const SystemSnapshot* TestProcessSnapshot::System() const {
|
||||
return system_.get();
|
||||
}
|
||||
|
||||
std::vector<const ThreadSnapshot*> TestProcessSnapshot::Threads() const {
|
||||
std::vector<const ThreadSnapshot*> threads;
|
||||
for (const ThreadSnapshot* thread : threads_) {
|
||||
threads.push_back(thread);
|
||||
}
|
||||
return threads;
|
||||
}
|
||||
|
||||
std::vector<const ModuleSnapshot*> TestProcessSnapshot::Modules() const {
|
||||
std::vector<const ModuleSnapshot*> modules;
|
||||
for (const ModuleSnapshot* module : modules_) {
|
||||
modules.push_back(module);
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
const ExceptionSnapshot* TestProcessSnapshot::Exception() const {
|
||||
return exception_.get();
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
121
snapshot/test/test_process_snapshot.h
Normal file
121
snapshot/test/test_process_snapshot.h
Normal file
@ -0,0 +1,121 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_TEST_TEST_PROCESS_SNAPSHOT_H_
|
||||
#define CRASHPAD_SNAPSHOT_TEST_TEST_PROCESS_SNAPSHOT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "snapshot/exception_snapshot.h"
|
||||
#include "snapshot/process_snapshot.h"
|
||||
#include "snapshot/system_snapshot.h"
|
||||
#include "util/stdlib/pointer_container.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
class ModuleSnapshot;
|
||||
class ThreadSnapshot;
|
||||
|
||||
namespace test {
|
||||
|
||||
//! \brief A test ProcessSnapshot that can carry arbitrary data for testing
|
||||
//! purposes.
|
||||
class TestProcessSnapshot final : public ProcessSnapshot {
|
||||
public:
|
||||
TestProcessSnapshot();
|
||||
~TestProcessSnapshot() override;
|
||||
|
||||
void SetProcessID(pid_t process_id) { process_id_ = process_id; }
|
||||
void SetParentProcessID(pid_t parent_process_id) {
|
||||
parent_process_id_ = parent_process_id;
|
||||
}
|
||||
void SetSnapshotTime(const timeval& snapshot_time) {
|
||||
snapshot_time_ = snapshot_time;
|
||||
}
|
||||
void SetProcessStartTime(const timeval& start_time) {
|
||||
process_start_time_ = start_time;
|
||||
}
|
||||
void SetProcessCPUTimes(const timeval& user_time,
|
||||
const timeval& system_time) {
|
||||
process_cpu_user_time_ = user_time;
|
||||
process_cpu_system_time_ = system_time;
|
||||
}
|
||||
|
||||
//! \brief Sets the system snapshot to be returned by System().
|
||||
//!
|
||||
//! \param[in] system The system snapshot that System() will return. The
|
||||
//! TestProcessSnapshot object takes ownership of \a system.
|
||||
void SetSystem(scoped_ptr<SystemSnapshot> system) { system_ = system.Pass(); }
|
||||
|
||||
//! \brief Adds a thread snapshot to be returned by Threads().
|
||||
//!
|
||||
//! \param[in] thread The thread snapshot that will be included in Threads().
|
||||
//! The TestProcessSnapshot object takes ownership of \a thread.
|
||||
void AddThread(scoped_ptr<ThreadSnapshot> thread) {
|
||||
threads_.push_back(thread.release());
|
||||
}
|
||||
|
||||
//! \brief Adds a module snapshot to be returned by Modules().
|
||||
//!
|
||||
//! \param[in] module The module snapshot that will be included in Modules().
|
||||
//! The TestProcessSnapshot object takes ownership of \a module.
|
||||
void AddModule(scoped_ptr<ModuleSnapshot> module) {
|
||||
modules_.push_back(module.release());
|
||||
}
|
||||
|
||||
//! \brief Sets the exception snapshot to be returned by Exception().
|
||||
//!
|
||||
//! \param[in] exception The exception snapshot that Exception() will return.
|
||||
//! The TestProcessSnapshot object takes ownership of \a exception.
|
||||
void SetException(scoped_ptr<ExceptionSnapshot> exception) {
|
||||
exception_ = exception.Pass();
|
||||
}
|
||||
|
||||
// ProcessSnapshot:
|
||||
|
||||
pid_t ProcessID() const override;
|
||||
pid_t ParentProcessID() const override;
|
||||
void SnapshotTime(timeval* snapshot_time) const override;
|
||||
void ProcessStartTime(timeval* start_time) const override;
|
||||
void ProcessCPUTimes(timeval* user_time, timeval* system_time) const override;
|
||||
const SystemSnapshot* System() const override;
|
||||
std::vector<const ThreadSnapshot*> Threads() const override;
|
||||
std::vector<const ModuleSnapshot*> Modules() const override;
|
||||
const ExceptionSnapshot* Exception() const override;
|
||||
|
||||
private:
|
||||
pid_t process_id_;
|
||||
pid_t parent_process_id_;
|
||||
timeval snapshot_time_;
|
||||
timeval process_start_time_;
|
||||
timeval process_cpu_user_time_;
|
||||
timeval process_cpu_system_time_;
|
||||
scoped_ptr<SystemSnapshot> system_;
|
||||
PointerVector<ThreadSnapshot> threads_;
|
||||
PointerVector<ModuleSnapshot> modules_;
|
||||
scoped_ptr<ExceptionSnapshot> exception_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TestProcessSnapshot);
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_TEST_TEST_PROCESS_SNAPSHOT_H_
|
Loading…
x
Reference in New Issue
Block a user