From f5f0aa4a8e843d08736eded813832f7d14a38ece Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Tue, 10 Apr 2018 15:34:33 -0700 Subject: [PATCH] fuchsia: Implementation of system snapshot Mostly sensible implementation for x64 via cpuid. It's too early for Fuchsia to have a version number, so nothing is reported for those fields. ARM64 isn't implemented at all and would hit a lot of NOTREACHED()s. Bug: crashpad:196 Change-Id: I6ca8b12e16fe0cf773a17c88ca9d407b028a501c Reviewed-on: https://chromium-review.googlesource.com/1005906 Commit-Queue: Scott Graham Reviewed-by: Joshua Peraza --- minidump/minidump_extensions.h | 3 + minidump/minidump_system_info_writer.cc | 3 + snapshot/BUILD.gn | 2 + snapshot/fuchsia/process_snapshot_fuchsia.cc | 5 +- snapshot/fuchsia/process_snapshot_fuchsia.h | 2 + snapshot/fuchsia/system_snapshot_fuchsia.cc | 207 +++++++++++++++++++ snapshot/fuchsia/system_snapshot_fuchsia.h | 87 ++++++++ snapshot/system_snapshot.h | 3 + 8 files changed, 310 insertions(+), 2 deletions(-) create mode 100644 snapshot/fuchsia/system_snapshot_fuchsia.cc create mode 100644 snapshot/fuchsia/system_snapshot_fuchsia.h diff --git a/minidump/minidump_extensions.h b/minidump/minidump_extensions.h index fbaa6ee5..f3701dc2 100644 --- a/minidump/minidump_extensions.h +++ b/minidump/minidump_extensions.h @@ -248,6 +248,9 @@ enum MinidumpOS : uint32_t { //! \brief Native Client (NaCl). kMinidumpOSNaCl = 0x8205, + //! \brief Fuchsia. + kMinidumpOSFuchsia = 0x8206, + //! \brief Unknown operating system. kMinidumpOSUnknown = 0xffffffff, }; diff --git a/minidump/minidump_system_info_writer.cc b/minidump/minidump_system_info_writer.cc index 4a22b436..cc87d242 100644 --- a/minidump/minidump_system_info_writer.cc +++ b/minidump/minidump_system_info_writer.cc @@ -172,6 +172,9 @@ void MinidumpSystemInfoWriter::InitializeFromSnapshot( case SystemSnapshot::kOperatingSystemAndroid: operating_system = kMinidumpOSAndroid; break; + case SystemSnapshot::kOperatingSystemFuchsia: + operating_system = kMinidumpOSFuchsia; + break; default: NOTREACHED(); operating_system = kMinidumpOSUnknown; diff --git a/snapshot/BUILD.gn b/snapshot/BUILD.gn index 44bb53f6..9f559e8e 100644 --- a/snapshot/BUILD.gn +++ b/snapshot/BUILD.gn @@ -180,6 +180,8 @@ static_library("snapshot") { "fuchsia/process_reader_fuchsia.h", "fuchsia/process_snapshot_fuchsia.cc", "fuchsia/process_snapshot_fuchsia.h", + "fuchsia/system_snapshot_fuchsia.cc", + "fuchsia/system_snapshot_fuchsia.h", "fuchsia/thread_snapshot_fuchsia.cc", "fuchsia/thread_snapshot_fuchsia.h", ] diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.cc b/snapshot/fuchsia/process_snapshot_fuchsia.cc index 8211df83..64d839c3 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/process_snapshot_fuchsia.cc @@ -34,6 +34,8 @@ bool ProcessSnapshotFuchsia::Initialize(zx_handle_t process) { return false; } + system_.Initialize(&snapshot_time_); + InitializeThreads(); InitializeModules(); @@ -125,8 +127,7 @@ ProcessSnapshotFuchsia::AnnotationsSimpleMap() const { const SystemSnapshot* ProcessSnapshotFuchsia::System() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196 - return nullptr; + return &system_; } std::vector ProcessSnapshotFuchsia::Threads() const { diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.h b/snapshot/fuchsia/process_snapshot_fuchsia.h index f7eda4e3..0f14404d 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.h +++ b/snapshot/fuchsia/process_snapshot_fuchsia.h @@ -26,6 +26,7 @@ #include "snapshot/elf/elf_image_reader.h" #include "snapshot/elf/module_snapshot_elf.h" #include "snapshot/fuchsia/process_reader_fuchsia.h" +#include "snapshot/fuchsia/system_snapshot_fuchsia.h" #include "snapshot/fuchsia/thread_snapshot_fuchsia.h" #include "snapshot/process_snapshot.h" #include "snapshot/unloaded_module_snapshot.h" @@ -81,6 +82,7 @@ class ProcessSnapshotFuchsia : public ProcessSnapshot { // Initializes modules_ on behalf of Initialize(). void InitializeModules(); + internal::SystemSnapshotFuchsia system_; std::vector> threads_; std::vector> modules_; ProcessReaderFuchsia process_reader_; diff --git a/snapshot/fuchsia/system_snapshot_fuchsia.cc b/snapshot/fuchsia/system_snapshot_fuchsia.cc new file mode 100644 index 00000000..f42b50fe --- /dev/null +++ b/snapshot/fuchsia/system_snapshot_fuchsia.cc @@ -0,0 +1,207 @@ +// Copyright 2018 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/fuchsia/system_snapshot_fuchsia.h" + +#include +#include + +#include "base/logging.h" +#include "base/numerics/safe_conversions.h" +#include "base/strings/stringprintf.h" +#include "snapshot/posix/timezone.h" + +namespace crashpad { +namespace internal { + +SystemSnapshotFuchsia::SystemSnapshotFuchsia() = default; + +SystemSnapshotFuchsia::~SystemSnapshotFuchsia() = default; + +void SystemSnapshotFuchsia::Initialize(const timeval* snapshot_time) { + INITIALIZATION_STATE_SET_INITIALIZING(initialized_); + + snapshot_time_ = snapshot_time; + + std::string uname_string; + utsname uts; + if (uname(&uts) != 0) { + PLOG(WARNING) << "uname"; + } else { + uname_string = base::StringPrintf("%s %s", uts.sysname, uts.machine); + } + + // TODO(scottmg): There's no version available to be reported yet. + + os_version_full_ = uname_string; + + INITIALIZATION_STATE_SET_VALID(initialized_); +} + +CPUArchitecture SystemSnapshotFuchsia::GetCPUArchitecture() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + +#if defined(ARCH_CPU_X86_64) + return kCPUArchitectureX86_64; +#elif defined(ARCH_CPU_ARM64) + return kCPUArchitectureARM64; +#else +#error Port +#endif +} + +uint32_t SystemSnapshotFuchsia::CPURevision() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.Revision(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return 0; +#endif +} + +uint8_t SystemSnapshotFuchsia::CPUCount() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return base::saturated_cast(zx_system_get_num_cpus()); +} + +std::string SystemSnapshotFuchsia::CPUVendor() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.Vendor(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return std::string(); +#endif +} + +void SystemSnapshotFuchsia::CPUFrequency(uint64_t* current_hz, + uint64_t* max_hz) const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + // TODO(scottmg): https://crashpad.chromium.org/bug/196. + *current_hz = 0; + *max_hz = 0; +} + +uint32_t SystemSnapshotFuchsia::CPUX86Signature() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.Signature(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return 0; +#endif +} + +uint64_t SystemSnapshotFuchsia::CPUX86Features() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.Features(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return 0; +#endif +} + +uint64_t SystemSnapshotFuchsia::CPUX86ExtendedFeatures() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.ExtendedFeatures(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return 0; +#endif +} + +uint32_t SystemSnapshotFuchsia::CPUX86Leaf7Features() const { +#if defined(ARCH_CPU_X86_64) + return cpuid_.Leaf7Features(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return 0; +#endif +} + +bool SystemSnapshotFuchsia::CPUX86SupportsDAZ() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.SupportsDAZ(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return false; +#endif +} + +SystemSnapshot::OperatingSystem SystemSnapshotFuchsia::GetOperatingSystem() + const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return kOperatingSystemFuchsia; +} + +bool SystemSnapshotFuchsia::OSServer() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return false; +} + +void SystemSnapshotFuchsia::OSVersion(int* major, + int* minor, + int* bugfix, + std::string* build) const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + // TODO(scottmg): https://crashpad.chromium.org/bug/196. There's no version + // available to be reported yet. + *major = 0; + *minor = 0; + *bugfix = 0; + *build = std::string(); +} + +std::string SystemSnapshotFuchsia::OSVersionFull() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return os_version_full_; +} + +std::string SystemSnapshotFuchsia::MachineDescription() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return std::string(); +} + +bool SystemSnapshotFuchsia::NXEnabled() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); +#if defined(ARCH_CPU_X86_64) + return cpuid_.NXEnabled(); +#else + NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196. + return false; +#endif +} + +void SystemSnapshotFuchsia::TimeZone(DaylightSavingTimeStatus* dst_status, + int* standard_offset_seconds, + int* daylight_offset_seconds, + std::string* standard_name, + std::string* daylight_name) const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + + internal::TimeZone(*snapshot_time_, + dst_status, + standard_offset_seconds, + daylight_offset_seconds, + standard_name, + daylight_name); +} + +} // namespace internal +} // namespace crashpad diff --git a/snapshot/fuchsia/system_snapshot_fuchsia.h b/snapshot/fuchsia/system_snapshot_fuchsia.h new file mode 100644 index 00000000..c7cd35dc --- /dev/null +++ b/snapshot/fuchsia/system_snapshot_fuchsia.h @@ -0,0 +1,87 @@ +// Copyright 2018 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_FUCHSIA_SYSTEM_SNAPSHOT_FUCHSIA_H_ +#define CRASHPAD_SNAPSHOT_FUCHSIA_SYSTEM_SNAPSHOT_FUCHSIA_H_ + +#include + +#include "base/macros.h" +#include "build/build_config.h" +#include "snapshot/system_snapshot.h" +#include "util/misc/initialization_state_dcheck.h" + +#if defined(ARCH_CPU_X86_FAMILY) +#include "snapshot/x86/cpuid_reader.h" +#endif + +namespace crashpad { +namespace internal { + +//! \brief A SystemSnapshot of the running system, when the system runs Fuchsia. +class SystemSnapshotFuchsia final : public SystemSnapshot { + public: + SystemSnapshotFuchsia(); + ~SystemSnapshotFuchsia() override; + + //! \brief Initializes the object. + //! + //! \param[in] snapshot_time The time of the snapshot being taken. + //! + //! This parameter is necessary for TimeZone() to determine whether daylight + //! saving time was in effect at the time the snapshot was taken. Otherwise, + //! it would need to base its determination on the current time, which may be + //! different than the snapshot time for snapshots generated around the + //! daylight saving transition time. + void Initialize(const timeval* snapshot_time); + + // SystemSnapshot: + + CPUArchitecture GetCPUArchitecture() const override; + uint32_t CPURevision() const override; + uint8_t CPUCount() const override; + std::string CPUVendor() const override; + void CPUFrequency(uint64_t* current_hz, uint64_t* max_hz) const override; + uint32_t CPUX86Signature() const override; + uint64_t CPUX86Features() const override; + uint64_t CPUX86ExtendedFeatures() const override; + uint32_t CPUX86Leaf7Features() const override; + bool CPUX86SupportsDAZ() const override; + OperatingSystem GetOperatingSystem() const override; + bool OSServer() const override; + void OSVersion( + int* major, int* minor, int* bugfix, std::string* build) const override; + std::string OSVersionFull() const override; + bool NXEnabled() const override; + std::string MachineDescription() const override; + void TimeZone(DaylightSavingTimeStatus* dst_status, + int* standard_offset_seconds, + int* daylight_offset_seconds, + std::string* standard_name, + std::string* daylight_name) const override; + private: + std::string os_version_full_; + const timeval* snapshot_time_; // weak +#if defined(ARCH_CPU_X86_FAMILY) + CpuidReader cpuid_; +#endif // ARCH_CPU_X86_FAMILY + InitializationStateDcheck initialized_; + + DISALLOW_COPY_AND_ASSIGN(SystemSnapshotFuchsia); +}; + +} // namespace internal +} // namespace crashpad + +#endif // CRASHPAD_SNAPSHOT_FUCHSIA_SYSTEM_SNAPSHOT_FUCHSIA_H_ diff --git a/snapshot/system_snapshot.h b/snapshot/system_snapshot.h index 6da3d376..a363c0c8 100644 --- a/snapshot/system_snapshot.h +++ b/snapshot/system_snapshot.h @@ -47,6 +47,9 @@ class SystemSnapshot { //! \brief Android. kOperatingSystemAndroid, + + //! \brief Fuchsia. + kOperatingSystemFuchsia, }; //! \brief A system’s daylight saving time status.