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:
Mark Mentovai 2014-08-07 14:58:26 -04:00
Родитель 293964f69b
Коммит aa3adf2c5b
7 изменённых файлов: 637 добавлений и 3 удалений

Просмотреть файл

@ -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(&registers[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 versions 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