Add MinidumpSystemInfoWriter and its test.
TEST=minidump_test MinidumpSystemInfoWriter R=rsesek@chromium.org Review URL: https://codereview.chromium.org/435243002
This commit is contained in:
Родитель
293964f69b
Коммит
aa3adf2c5b
|
@ -209,7 +209,7 @@ union __attribute__((packed, aligned(4))) CPU_INFORMATION {
|
|||
//! 32-bit x86 processes.
|
||||
struct __attribute__((packed, aligned(4))) {
|
||||
//! \brief Bitfields containing supported CPU capabilities as identified by
|
||||
//! bits corresponding to `PF_*` values passed to
|
||||
//! bits corresponding to \ref PF_x "PF_*" values passed to
|
||||
//! `IsProcessorFeaturePresent()`.
|
||||
uint64_t ProcessorFeatures[2];
|
||||
} OtherCpuInfo;
|
||||
|
|
|
@ -69,8 +69,8 @@
|
|||
//! \anchor PF_x
|
||||
//! \name PF_*
|
||||
//!
|
||||
//! \brief CPU feature values for
|
||||
//! CPU_INFORMATION::OtherCpuInfo::ProcessorFeatures.
|
||||
//! \brief CPU feature values for \ref CPU_INFORMATION::ProcessorFeatures
|
||||
//! "CPU_INFORMATION::OtherCpuInfo::ProcessorFeatures".
|
||||
//!
|
||||
//! \{
|
||||
#define PF_FLOATING_POINT_PRECISION_ERRATA 0
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
'minidump_stream_writer.h',
|
||||
'minidump_string_writer.cc',
|
||||
'minidump_string_writer.h',
|
||||
'minidump_system_info_writer.cc',
|
||||
'minidump_system_info_writer.h',
|
||||
'minidump_writable.cc',
|
||||
'minidump_writable.h',
|
||||
'minidump_writer_util.cc',
|
||||
|
@ -57,6 +59,7 @@
|
|||
'../third_party/gtest/gtest/src/gtest_main.cc',
|
||||
'minidump_file_writer_test.cc',
|
||||
'minidump_string_writer_test.cc',
|
||||
'minidump_system_info_writer_test.cc',
|
||||
'minidump_writable_test.cc',
|
||||
],
|
||||
},
|
||||
|
|
|
@ -121,7 +121,13 @@ enum MinidumpCPUArchitecture : uint16_t {
|
|||
//! These systems identify their CPUs as “x86_64”, “amd64”, or “x64”.
|
||||
kMinidumpCPUArchitectureAMD64 = PROCESSOR_ARCHITECTURE_AMD64,
|
||||
|
||||
//! \brief A 32-bit x86 process running on IA-64 (Itanium).
|
||||
//!
|
||||
//! \note This value is not used in minidump files for 32-bit x86 processes
|
||||
//! running on a 64-bit-capable x86 CPU and operating system. In that
|
||||
//! configuration, #kMinidumpCPUArchitectureX86 is used instead.
|
||||
kMinidumpCPUArchitectureX86Win64 = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64,
|
||||
|
||||
kMinidumpCPUArchitectureNeutral = PROCESSOR_ARCHITECTURE_NEUTRAL,
|
||||
kMinidumpCPUArchitectureSPARC = 0x8001,
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
// 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 "minidump/minidump_system_info_writer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "minidump/minidump_string_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
MinidumpSystemInfoWriter::MinidumpSystemInfoWriter()
|
||||
: MinidumpStreamWriter(), system_info_(), csd_version_() {
|
||||
system_info_.ProcessorArchitecture = kMinidumpCPUArchitectureUnknown;
|
||||
}
|
||||
|
||||
MinidumpSystemInfoWriter::~MinidumpSystemInfoWriter() {
|
||||
}
|
||||
|
||||
void MinidumpSystemInfoWriter::SetCSDVersion(const std::string& csd_version) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
if (!csd_version_) {
|
||||
csd_version_.reset(new internal::MinidumpUTF16StringWriter());
|
||||
}
|
||||
|
||||
csd_version_->SetUTF8(csd_version);
|
||||
}
|
||||
|
||||
void MinidumpSystemInfoWriter::SetCPUX86Vendor(uint32_t ebx,
|
||||
uint32_t edx,
|
||||
uint32_t ecx) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(system_info_.ProcessorArchitecture == kMinidumpCPUArchitectureX86 ||
|
||||
system_info_.ProcessorArchitecture ==
|
||||
kMinidumpCPUArchitectureX86Win64);
|
||||
|
||||
COMPILE_ASSERT(arraysize(system_info_.Cpu.X86CpuInfo.VendorId) == 3,
|
||||
vendor_id_must_have_3_elements);
|
||||
|
||||
system_info_.Cpu.X86CpuInfo.VendorId[0] = ebx;
|
||||
system_info_.Cpu.X86CpuInfo.VendorId[1] = edx;
|
||||
system_info_.Cpu.X86CpuInfo.VendorId[2] = ecx;
|
||||
}
|
||||
|
||||
void MinidumpSystemInfoWriter::SetCPUX86VendorString(
|
||||
const std::string& vendor) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
CHECK_EQ(vendor.size(), sizeof(system_info_.Cpu.X86CpuInfo.VendorId));
|
||||
|
||||
uint32_t registers[3];
|
||||
COMPILE_ASSERT(
|
||||
sizeof(registers) == sizeof(system_info_.Cpu.X86CpuInfo.VendorId),
|
||||
vendor_id_sizes_must_be_equal);
|
||||
|
||||
for (size_t index = 0; index < arraysize(registers); ++index) {
|
||||
memcpy(®isters[index],
|
||||
&vendor[index * sizeof(*registers)],
|
||||
sizeof(*registers));
|
||||
}
|
||||
|
||||
SetCPUX86Vendor(registers[0], registers[1], registers[2]);
|
||||
}
|
||||
|
||||
void MinidumpSystemInfoWriter::SetCPUX86VersionAndFeatures(uint32_t version,
|
||||
uint32_t features) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(system_info_.ProcessorArchitecture == kMinidumpCPUArchitectureX86 ||
|
||||
system_info_.ProcessorArchitecture ==
|
||||
kMinidumpCPUArchitectureX86Win64);
|
||||
|
||||
system_info_.Cpu.X86CpuInfo.VersionInformation = version;
|
||||
system_info_.Cpu.X86CpuInfo.FeatureInformation = features;
|
||||
}
|
||||
|
||||
void MinidumpSystemInfoWriter::SetCPUX86AMDExtendedFeatures(
|
||||
uint32_t extended_features) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(system_info_.ProcessorArchitecture == kMinidumpCPUArchitectureX86 ||
|
||||
system_info_.ProcessorArchitecture ==
|
||||
kMinidumpCPUArchitectureX86Win64);
|
||||
DCHECK(system_info_.Cpu.X86CpuInfo.VendorId[0] == 'htuA' &&
|
||||
system_info_.Cpu.X86CpuInfo.VendorId[1] == 'itne' &&
|
||||
system_info_.Cpu.X86CpuInfo.VendorId[2] == 'DMAc');
|
||||
|
||||
system_info_.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = extended_features;
|
||||
}
|
||||
|
||||
void MinidumpSystemInfoWriter::SetCPUOtherFeatures(uint64_t features_0,
|
||||
uint64_t features_1) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(system_info_.ProcessorArchitecture != kMinidumpCPUArchitectureX86 &&
|
||||
system_info_.ProcessorArchitecture !=
|
||||
kMinidumpCPUArchitectureX86Win64);
|
||||
|
||||
COMPILE_ASSERT(
|
||||
arraysize(system_info_.Cpu.OtherCpuInfo.ProcessorFeatures) == 2,
|
||||
processor_features_must_have_2_elements);
|
||||
|
||||
system_info_.Cpu.OtherCpuInfo.ProcessorFeatures[0] = features_0;
|
||||
system_info_.Cpu.OtherCpuInfo.ProcessorFeatures[1] = features_1;
|
||||
}
|
||||
|
||||
bool MinidumpSystemInfoWriter::Freeze() {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
CHECK(csd_version_);
|
||||
|
||||
if (!MinidumpStreamWriter::Freeze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
csd_version_->RegisterRVA(&system_info_.CSDVersionRva);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t MinidumpSystemInfoWriter::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
return sizeof(system_info_);
|
||||
}
|
||||
|
||||
std::vector<internal::MinidumpWritable*> MinidumpSystemInfoWriter::Children() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
DCHECK(csd_version_);
|
||||
|
||||
std::vector<MinidumpWritable*> children(1, csd_version_.get());
|
||||
return children;
|
||||
}
|
||||
|
||||
bool MinidumpSystemInfoWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||
DCHECK_EQ(state(), kStateWritable);
|
||||
|
||||
return file_writer->Write(&system_info_, sizeof(system_info_));
|
||||
}
|
||||
|
||||
MinidumpStreamType MinidumpSystemInfoWriter::StreamType() const {
|
||||
return kMinidumpStreamTypeSystemInfo;
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
|
@ -0,0 +1,186 @@
|
|||
// 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_MINIDUMP_MINIDUMP_SYSTEM_INFO_WRITER_H_
|
||||
#define CRASHPAD_MINIDUMP_MINIDUMP_SYSTEM_INFO_WRITER_H_
|
||||
|
||||
#include <dbghelp.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_stream_writer.h"
|
||||
#include "minidump/minidump_writable.h"
|
||||
#include "util/file/file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
namespace internal {
|
||||
class MinidumpUTF16StringWriter;
|
||||
} // namespace internal
|
||||
|
||||
//! \brief The writer for a MINIDUMP_SYSTEM_INFO stream in a minidump file.
|
||||
class MinidumpSystemInfoWriter final : public internal::MinidumpStreamWriter {
|
||||
public:
|
||||
MinidumpSystemInfoWriter();
|
||||
~MinidumpSystemInfoWriter();
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::ProcessorArchitecture.
|
||||
void SetCPUArchitecture(MinidumpCPUArchitecture processor_architecture) {
|
||||
system_info_.ProcessorArchitecture = processor_architecture;
|
||||
}
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::ProcessorLevel and
|
||||
//! MINIDUMP_SYSTEM_INFO::ProcessorRevision.
|
||||
void SetCPULevelAndRevision(uint16_t processor_level,
|
||||
uint16_t processor_revision) {
|
||||
system_info_.ProcessorLevel = processor_level;
|
||||
system_info_.ProcessorRevision = processor_revision;
|
||||
}
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::NumberOfProcessors.
|
||||
void SetCPUCount(uint8_t number_of_processors) {
|
||||
system_info_.NumberOfProcessors = number_of_processors;
|
||||
}
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::PlatformId.
|
||||
void SetOS(MinidumpOS platform_id) { system_info_.PlatformId = platform_id; }
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::ProductType.
|
||||
void SetOSType(MinidumpOSType product_type) {
|
||||
system_info_.ProductType = product_type;
|
||||
}
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::MajorVersion,
|
||||
//! MINIDUMP_SYSTEM_INFO::MinorVersion, and
|
||||
//! MINIDUMP_SYSTEM_INFO::BuildNumber.
|
||||
void SetOSVersion(uint32_t major_version,
|
||||
uint32_t minor_version,
|
||||
uint32_t build_number) {
|
||||
system_info_.MajorVersion = major_version;
|
||||
system_info_.MinorVersion = minor_version;
|
||||
system_info_.BuildNumber = build_number;
|
||||
}
|
||||
|
||||
//! \brief Arranges for MINIDUMP_SYSTEM_INFO::CSDVersionRva to point to a
|
||||
//! MINIDUMP_STRING containing the supplied string.
|
||||
//!
|
||||
//! This method must be called prior to Freeze(). A CSD version is required
|
||||
//! in all MINIDUMP_SYSTEM_INFO streams. An empty string is an acceptable
|
||||
//! value.
|
||||
void SetCSDVersion(const std::string& csd_version);
|
||||
|
||||
//! \brief Sets MINIDUMP_SYSTEM_INFO::SuiteMask.
|
||||
void SetSuiteMask(uint16_t suite_mask) {
|
||||
system_info_.SuiteMask = suite_mask;
|
||||
}
|
||||
|
||||
//! \brief Sets \ref CPU_INFORMATION::VendorId
|
||||
//! "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::VendorId".
|
||||
//!
|
||||
//! This is only valid if SetCPUArchitecture() has been used to set the CPU
|
||||
//! architecture to #kMinidumpCPUArchitectureX86 or
|
||||
//! #kMinidumpCPUArchitectureX86Win64.
|
||||
//!
|
||||
//! \param[in] ebx The first 4 bytes of the CPU vendor string, the value
|
||||
//! reported in `cpuid 0` `ebx`.
|
||||
//! \param[in] edx The middle 4 bytes of the CPU vendor string, the value
|
||||
//! reported in `cpuid 0` `edx`.
|
||||
//! \param[in] ecx The last 4 bytes of the CPU vendor string, the value
|
||||
//! reported by `cpuid 0` `ecx`.
|
||||
//!
|
||||
//! \note Do not call this method if SetCPUArchitecture() has been used to set
|
||||
//! the CPU architecture to #kMinidumpCPUArchitectureAMD64.
|
||||
//!
|
||||
//! \sa SetCPUX86VendorString()
|
||||
void SetCPUX86Vendor(uint32_t ebx, uint32_t edx, uint32_t ecx);
|
||||
|
||||
//! \brief Sets \ref CPU_INFORMATION::VendorId
|
||||
//! "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::VendorId".
|
||||
//!
|
||||
//! This is only valid if SetCPUArchitecture() has been used to set the CPU
|
||||
//! architecture to #kMinidumpCPUArchitectureX86 or
|
||||
//! #kMinidumpCPUArchitectureX86Win64.
|
||||
//!
|
||||
//! \param[in] vendor The entire CPU vendor string, which must be exactly 12
|
||||
//! bytes long.
|
||||
//!
|
||||
//! \note Do not call this method if SetCPUArchitecture() has been used to set
|
||||
//! the CPU architecture to #kMinidumpCPUArchitectureAMD64.
|
||||
//!
|
||||
//! \sa SetCPUX86Vendor()
|
||||
void SetCPUX86VendorString(const std::string& vendor);
|
||||
|
||||
//! \brief Sets \ref CPU_INFORMATION::VersionInformation
|
||||
//! "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::VersionInformation" and
|
||||
//! \ref CPU_INFORMATION::FeatureInformation
|
||||
//! "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::FeatureInformation".
|
||||
//!
|
||||
//! This is only valid if SetCPUArchitecture() has been used to set the CPU
|
||||
//! architecture to #kMinidumpCPUArchitectureX86 or
|
||||
//! #kMinidumpCPUArchitectureX86Win64.
|
||||
//!
|
||||
//! \note Do not call this method if SetCPUArchitecture() has been used to set
|
||||
//! the CPU architecture to #kMinidumpCPUArchitectureAMD64.
|
||||
void SetCPUX86VersionAndFeatures(uint32_t version, uint32_t features);
|
||||
|
||||
//! \brief Sets \ref CPU_INFORMATION::AMDExtendedCpuFeatures
|
||||
//! "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::AMDExtendedCPUFeatures".
|
||||
//!
|
||||
//! This is only valid if SetCPUArchitecture() has been used to set the CPU
|
||||
//! architecture to #kMinidumpCPUArchitectureX86 or
|
||||
//! #kMinidumpCPUArchitectureX86Win64, and if SetCPUX86Vendor() or
|
||||
//! SetCPUX86VendorString() has been used to set the CPU vendor to
|
||||
//! “AuthenticAMD”.
|
||||
//!
|
||||
//! \note Do not call this method if SetCPUArchitecture() has been used to set
|
||||
//! the CPU architecture to #kMinidumpCPUArchitectureAMD64.
|
||||
void SetCPUX86AMDExtendedFeatures(uint32_t extended_features);
|
||||
|
||||
//! \brief Sets \ref CPU_INFORMATION::ProcessorFeatures
|
||||
//! "MINIDUMP_SYSTEM_INFO::Cpu::OtherCpuInfo::ProcessorFeatures".
|
||||
//!
|
||||
//! This is only valid if SetCPUArchitecture() has been used to set the CPU
|
||||
//! architecture to an architecture other than #kMinidumpCPUArchitectureX86
|
||||
//! or #kMinidumpCPUArchitectureX86Win64.
|
||||
//!
|
||||
//! \note This method may be called if SetCPUArchitecture() has been used to
|
||||
//! set the CPU architecture to #kMinidumpCPUArchitectureAMD64.
|
||||
void SetCPUOtherFeatures(uint64_t features_0, uint64_t features_1);
|
||||
|
||||
protected:
|
||||
// MinidumpWritable:
|
||||
virtual bool Freeze() override;
|
||||
virtual size_t SizeOfObject() override;
|
||||
virtual std::vector<MinidumpWritable*> Children() override;
|
||||
virtual bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
// MinidumpStreamWriter:
|
||||
virtual MinidumpStreamType StreamType() const override;
|
||||
|
||||
private:
|
||||
MINIDUMP_SYSTEM_INFO system_info_;
|
||||
scoped_ptr<internal::MinidumpUTF16StringWriter> csd_version_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpSystemInfoWriter);
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_MINIDUMP_SYSTEM_INFO_WRITER_H_
|
|
@ -0,0 +1,286 @@
|
|||
// 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 "minidump/minidump_system_info_writer.h"
|
||||
|
||||
#include <dbghelp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace crashpad;
|
||||
|
||||
void GetSystemInfoStream(const std::string& file_contents,
|
||||
size_t csd_version_length,
|
||||
const MINIDUMP_SYSTEM_INFO** system_info,
|
||||
const MINIDUMP_STRING** csd_version) {
|
||||
// The expected number of bytes for the CSD version’s MINIDUMP_STRING::Buffer.
|
||||
const size_t kCSDVersionBytes =
|
||||
csd_version_length * sizeof(MINIDUMP_STRING::Buffer[0]);
|
||||
const size_t kCSDVersionBytesWithNUL =
|
||||
kCSDVersionBytes + sizeof(MINIDUMP_STRING::Buffer[0]);
|
||||
|
||||
const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
|
||||
const size_t kSystemInfoStreamOffset =
|
||||
kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
|
||||
const size_t kCSDVersionOffset =
|
||||
kSystemInfoStreamOffset + sizeof(MINIDUMP_SYSTEM_INFO);
|
||||
const size_t kFileSize =
|
||||
kCSDVersionOffset + sizeof(MINIDUMP_STRING) + kCSDVersionBytesWithNUL;
|
||||
|
||||
ASSERT_EQ(kFileSize, file_contents.size());
|
||||
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
EXPECT_EQ(static_cast<uint32_t>(MINIDUMP_SIGNATURE), header->Signature);
|
||||
EXPECT_EQ(static_cast<uint32_t>(MINIDUMP_VERSION), header->Version);
|
||||
ASSERT_EQ(1u, header->NumberOfStreams);
|
||||
ASSERT_EQ(kDirectoryOffset, header->StreamDirectoryRva);
|
||||
EXPECT_EQ(0u, header->CheckSum);
|
||||
EXPECT_EQ(0u, header->TimeDateStamp);
|
||||
EXPECT_EQ(MiniDumpNormal, header->Flags);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeSystemInfo, directory->StreamType);
|
||||
ASSERT_EQ(sizeof(MINIDUMP_SYSTEM_INFO), directory->Location.DataSize);
|
||||
ASSERT_EQ(kSystemInfoStreamOffset, directory->Location.Rva);
|
||||
|
||||
*system_info = reinterpret_cast<const MINIDUMP_SYSTEM_INFO*>(
|
||||
&file_contents[kSystemInfoStreamOffset]);
|
||||
|
||||
ASSERT_EQ(kCSDVersionOffset, (*system_info)->CSDVersionRva);
|
||||
|
||||
*csd_version = reinterpret_cast<const MINIDUMP_STRING*>(
|
||||
&file_contents[kCSDVersionOffset]);
|
||||
|
||||
ASSERT_EQ(kCSDVersionBytes, (*csd_version)->Length);
|
||||
}
|
||||
|
||||
TEST(MinidumpSystemInfoWriter, Empty) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpSystemInfoWriter system_info_writer;
|
||||
|
||||
system_info_writer.SetCSDVersion(std::string());
|
||||
|
||||
minidump_file_writer.AddStream(&system_info_writer);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MINIDUMP_SYSTEM_INFO* system_info;
|
||||
const MINIDUMP_STRING* csd_version;
|
||||
|
||||
GetSystemInfoStream(file_writer.string(), 0, &system_info, &csd_version);
|
||||
|
||||
EXPECT_EQ(kMinidumpCPUArchitectureUnknown,
|
||||
system_info->ProcessorArchitecture);
|
||||
EXPECT_EQ(0u, system_info->ProcessorLevel);
|
||||
EXPECT_EQ(0u, system_info->ProcessorRevision);
|
||||
EXPECT_EQ(0u, system_info->NumberOfProcessors);
|
||||
EXPECT_EQ(0u, system_info->ProductType);
|
||||
EXPECT_EQ(0u, system_info->MajorVersion);
|
||||
EXPECT_EQ(0u, system_info->MinorVersion);
|
||||
EXPECT_EQ(0u, system_info->BuildNumber);
|
||||
EXPECT_EQ(0u, system_info->PlatformId);
|
||||
EXPECT_EQ(0u, system_info->SuiteMask);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.VendorId[0]);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.VendorId[1]);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.VendorId[2]);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.VersionInformation);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.FeatureInformation);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.AMDExtendedCpuFeatures);
|
||||
EXPECT_EQ(0u, system_info->Cpu.OtherCpuInfo.ProcessorFeatures[0]);
|
||||
EXPECT_EQ(0u, system_info->Cpu.OtherCpuInfo.ProcessorFeatures[1]);
|
||||
|
||||
EXPECT_EQ('\0', csd_version->Buffer[0]);
|
||||
}
|
||||
|
||||
TEST(MinidumpSystemInfoWriter, X86_Win) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpSystemInfoWriter system_info_writer;
|
||||
|
||||
const MinidumpCPUArchitecture kCPUArchitecture = kMinidumpCPUArchitectureX86;
|
||||
const uint16_t kCPULevel = 0x0010;
|
||||
const uint16_t kCPURevision = 0x0602;
|
||||
const uint8_t kCPUCount = 1;
|
||||
const MinidumpOS kOS = kMinidumpOSWin32NT;
|
||||
const MinidumpOSType kOSType = kMinidumpOSTypeWorkstation;
|
||||
const uint32_t kOSVersionMajor = 6;
|
||||
const uint32_t kOSVersionMinor = 1;
|
||||
const uint32_t kOSVersionBuild = 7601;
|
||||
const char kCSDVersion[] = "Service Pack 1";
|
||||
const uint16_t kSuiteMask = VER_SUITE_SINGLEUSERTS;
|
||||
const char kCPUVendor[] = "AuthenticAMD";
|
||||
const uint32_t kCPUVersion = 0x00100f62;
|
||||
const uint32_t kCPUFeatures = 0x078bfbff;
|
||||
const uint32_t kAMDFeatures = 0xefd3fbff;
|
||||
|
||||
uint32_t cpu_vendor_registers[3];
|
||||
ASSERT_EQ(sizeof(cpu_vendor_registers), strlen(kCPUVendor));
|
||||
memcpy(cpu_vendor_registers, kCPUVendor, sizeof(cpu_vendor_registers));
|
||||
|
||||
system_info_writer.SetCPUArchitecture(kCPUArchitecture);
|
||||
system_info_writer.SetCPULevelAndRevision(kCPULevel, kCPURevision);
|
||||
system_info_writer.SetCPUCount(kCPUCount);
|
||||
system_info_writer.SetOS(kOS);
|
||||
system_info_writer.SetOSType(kMinidumpOSTypeWorkstation);
|
||||
system_info_writer.SetOSVersion(
|
||||
kOSVersionMajor, kOSVersionMinor, kOSVersionBuild);
|
||||
system_info_writer.SetCSDVersion(kCSDVersion);
|
||||
system_info_writer.SetSuiteMask(kSuiteMask);
|
||||
system_info_writer.SetCPUX86VendorString(kCPUVendor);
|
||||
system_info_writer.SetCPUX86VersionAndFeatures(kCPUVersion, kCPUFeatures);
|
||||
system_info_writer.SetCPUX86AMDExtendedFeatures(kAMDFeatures);
|
||||
|
||||
minidump_file_writer.AddStream(&system_info_writer);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MINIDUMP_SYSTEM_INFO* system_info;
|
||||
const MINIDUMP_STRING* csd_version;
|
||||
|
||||
GetSystemInfoStream(
|
||||
file_writer.string(), strlen(kCSDVersion), &system_info, &csd_version);
|
||||
|
||||
EXPECT_EQ(kCPUArchitecture, system_info->ProcessorArchitecture);
|
||||
EXPECT_EQ(kCPULevel, system_info->ProcessorLevel);
|
||||
EXPECT_EQ(kCPURevision, system_info->ProcessorRevision);
|
||||
EXPECT_EQ(kCPUCount, system_info->NumberOfProcessors);
|
||||
EXPECT_EQ(kOSType, system_info->ProductType);
|
||||
EXPECT_EQ(kOSVersionMajor, system_info->MajorVersion);
|
||||
EXPECT_EQ(kOSVersionMinor, system_info->MinorVersion);
|
||||
EXPECT_EQ(kOSVersionBuild, system_info->BuildNumber);
|
||||
EXPECT_EQ(kOS, system_info->PlatformId);
|
||||
EXPECT_EQ(kSuiteMask, system_info->SuiteMask);
|
||||
EXPECT_EQ(cpu_vendor_registers[0], system_info->Cpu.X86CpuInfo.VendorId[0]);
|
||||
EXPECT_EQ(cpu_vendor_registers[1], system_info->Cpu.X86CpuInfo.VendorId[1]);
|
||||
EXPECT_EQ(cpu_vendor_registers[2], system_info->Cpu.X86CpuInfo.VendorId[2]);
|
||||
EXPECT_EQ(kCPUVersion, system_info->Cpu.X86CpuInfo.VersionInformation);
|
||||
EXPECT_EQ(kCPUFeatures, system_info->Cpu.X86CpuInfo.FeatureInformation);
|
||||
EXPECT_EQ(kAMDFeatures, system_info->Cpu.X86CpuInfo.AMDExtendedCpuFeatures);
|
||||
|
||||
for (size_t index = 0; index < strlen(kCSDVersion); ++index) {
|
||||
EXPECT_EQ(kCSDVersion[index], csd_version->Buffer[index]) << index;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MinidumpSystemInfoWriter, X86_64_Mac) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpSystemInfoWriter system_info_writer;
|
||||
|
||||
const MinidumpCPUArchitecture kCPUArchitecture =
|
||||
kMinidumpCPUArchitectureAMD64;
|
||||
const uint16_t kCPULevel = 0x0006;
|
||||
const uint16_t kCPURevision = 0x3a09;
|
||||
const uint8_t kCPUCount = 8;
|
||||
const MinidumpOS kOS = kMinidumpOSMacOSX;
|
||||
const MinidumpOSType kOSType = kMinidumpOSTypeWorkstation;
|
||||
const uint32_t kOSVersionMajor = 10;
|
||||
const uint32_t kOSVersionMinor = 9;
|
||||
const uint32_t kOSVersionBuild = 4;
|
||||
const char kCSDVersion[] = "13E28";
|
||||
const uint64_t kCPUFeatures[2] = {0x10427f4c, 0x00000000};
|
||||
|
||||
system_info_writer.SetCPUArchitecture(kCPUArchitecture);
|
||||
system_info_writer.SetCPULevelAndRevision(kCPULevel, kCPURevision);
|
||||
system_info_writer.SetCPUCount(kCPUCount);
|
||||
system_info_writer.SetOS(kOS);
|
||||
system_info_writer.SetOSType(kMinidumpOSTypeWorkstation);
|
||||
system_info_writer.SetOSVersion(
|
||||
kOSVersionMajor, kOSVersionMinor, kOSVersionBuild);
|
||||
system_info_writer.SetCSDVersion(kCSDVersion);
|
||||
system_info_writer.SetCPUOtherFeatures(kCPUFeatures[0], kCPUFeatures[1]);
|
||||
|
||||
minidump_file_writer.AddStream(&system_info_writer);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MINIDUMP_SYSTEM_INFO* system_info;
|
||||
const MINIDUMP_STRING* csd_version;
|
||||
|
||||
GetSystemInfoStream(
|
||||
file_writer.string(), strlen(kCSDVersion), &system_info, &csd_version);
|
||||
|
||||
EXPECT_EQ(kCPUArchitecture, system_info->ProcessorArchitecture);
|
||||
EXPECT_EQ(kCPULevel, system_info->ProcessorLevel);
|
||||
EXPECT_EQ(kCPURevision, system_info->ProcessorRevision);
|
||||
EXPECT_EQ(kCPUCount, system_info->NumberOfProcessors);
|
||||
EXPECT_EQ(kOSType, system_info->ProductType);
|
||||
EXPECT_EQ(kOSVersionMajor, system_info->MajorVersion);
|
||||
EXPECT_EQ(kOSVersionMinor, system_info->MinorVersion);
|
||||
EXPECT_EQ(kOSVersionBuild, system_info->BuildNumber);
|
||||
EXPECT_EQ(kOS, system_info->PlatformId);
|
||||
EXPECT_EQ(0u, system_info->SuiteMask);
|
||||
EXPECT_EQ(kCPUFeatures[0],
|
||||
system_info->Cpu.OtherCpuInfo.ProcessorFeatures[0]);
|
||||
EXPECT_EQ(kCPUFeatures[1],
|
||||
system_info->Cpu.OtherCpuInfo.ProcessorFeatures[1]);
|
||||
}
|
||||
|
||||
TEST(MinidumpSystemInfoWriter, X86_CPUVendorFromRegisters) {
|
||||
// MinidumpSystemInfoWriter.X86_Win already tested SetCPUX86VendorString().
|
||||
// This test exercises SetCPUX86Vendor() to set the vendor from register
|
||||
// values.
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpSystemInfoWriter system_info_writer;
|
||||
|
||||
const MinidumpCPUArchitecture kCPUArchitecture = kMinidumpCPUArchitectureX86;
|
||||
const uint32_t kCPUVendor[] = {'uneG', 'Ieni', 'letn'};
|
||||
|
||||
system_info_writer.SetCPUArchitecture(kCPUArchitecture);
|
||||
system_info_writer.SetCPUX86Vendor(
|
||||
kCPUVendor[0], kCPUVendor[1], kCPUVendor[2]);
|
||||
system_info_writer.SetCSDVersion(std::string());
|
||||
|
||||
minidump_file_writer.AddStream(&system_info_writer);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MINIDUMP_SYSTEM_INFO* system_info;
|
||||
const MINIDUMP_STRING* csd_version;
|
||||
|
||||
GetSystemInfoStream(file_writer.string(), 0, &system_info, &csd_version);
|
||||
|
||||
EXPECT_EQ(kCPUArchitecture, system_info->ProcessorArchitecture);
|
||||
EXPECT_EQ(0u, system_info->ProcessorLevel);
|
||||
EXPECT_EQ(kCPUVendor[0], system_info->Cpu.X86CpuInfo.VendorId[0]);
|
||||
EXPECT_EQ(kCPUVendor[1], system_info->Cpu.X86CpuInfo.VendorId[1]);
|
||||
EXPECT_EQ(kCPUVendor[2], system_info->Cpu.X86CpuInfo.VendorId[2]);
|
||||
EXPECT_EQ(0u, system_info->Cpu.X86CpuInfo.VersionInformation);
|
||||
}
|
||||
|
||||
TEST(MinidumpSystemInfoWriterDeathTest, NoCSDVersion) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpSystemInfoWriter system_info_writer;
|
||||
minidump_file_writer.AddStream(&system_info_writer);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_DEATH(minidump_file_writer.WriteEverything(&file_writer),
|
||||
"csd_version_");
|
||||
}
|
||||
|
||||
} // namespace
|
Загрузка…
Ссылка в новой задаче