Merge pull request #7482 from huffman/extra-logging

Add system information to log file
This commit is contained in:
Brad Hefta-Gaub 2016-04-01 09:10:21 -07:00
commit 5a665f9aef
7 changed files with 400 additions and 0 deletions

View file

@ -106,6 +106,13 @@ elseif(WIN32)
# add an executable that also has the icon itself and the configured rc file as resources
add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT})
add_custom_command(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND "mt.exe" -manifest "${CMAKE_CURRENT_SOURCE_DIR}/interface.exe.manifest" -inputresource:"$<TARGET_FILE:${TARGET_NAME}>"\;\#1 -outputresource:"$<TARGET_FILE:${TARGET_NAME}>"\;\#1
COMMENT "Adding OS version support manifest to exe"
)
else()
add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM})
endif()

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--This Id value indicates the application supports Windows 7 functionality-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--This Id value indicates the application supports Windows 8 functionality-->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--This Id value indicates the application supports Windows 8.1 functionality-->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!--This Id value indicates the application supports Windows 10 functionality-->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>

View file

@ -31,6 +31,7 @@
#include <BugSplat.h>
#endif
int main(int argc, const char* argv[]) {
disableQtBearerPoll(); // Fixes wifi ping spikes
@ -180,6 +181,8 @@ int main(int argc, const char* argv[]) {
mpSender.sendAdditionalFile(qPrintable(logPath));
#endif
printSystemInformation();
QTranslator translator;
translator.load("i18n/interface_en");
app.installTranslator(&translator);

View file

@ -0,0 +1,75 @@
//
// CPUID.cpp
//
// Created by Ryan Huffman on 3/25/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "CPUID.h"
#ifdef Q_OS_WIN
const CPUID::CPUID_Internal CPUID::CPU_Rep;
std::vector<CPUID::Feature> CPUID::getAllFeatures() {
std::vector<CPUID::Feature> features;
features.push_back({ "3DNOW", CPUID::_3DNOW() });
features.push_back({ "3DNOWEXT", CPUID::_3DNOWEXT() });
features.push_back({ "ABM", CPUID::ABM() });
features.push_back({ "ADX", CPUID::ADX() });
features.push_back({ "AES", CPUID::AES() });
features.push_back({ "AVX", CPUID::AVX() });
features.push_back({ "AVX2", CPUID::AVX2() });
features.push_back({ "AVX512CD", CPUID::AVX512CD() });
features.push_back({ "AVX512ER", CPUID::AVX512ER() });
features.push_back({ "AVX512F", CPUID::AVX512F() });
features.push_back({ "AVX512PF", CPUID::AVX512PF() });
features.push_back({ "BMI1", CPUID::BMI1() });
features.push_back({ "BMI2", CPUID::BMI2() });
features.push_back({ "CLFSH", CPUID::CLFSH() });
features.push_back({ "CMPXCHG16B", CPUID::CMPXCHG16B() });
features.push_back({ "CX8", CPUID::CX8() });
features.push_back({ "ERMS", CPUID::ERMS() });
features.push_back({ "F16C", CPUID::F16C() });
features.push_back({ "FMA", CPUID::FMA() });
features.push_back({ "FSGSBASE", CPUID::FSGSBASE() });
features.push_back({ "FXSR", CPUID::FXSR() });
features.push_back({ "HLE", CPUID::HLE() });
features.push_back({ "INVPCID", CPUID::INVPCID() });
features.push_back({ "LAHF", CPUID::LAHF() });
features.push_back({ "LZCNT", CPUID::LZCNT() });
features.push_back({ "MMX", CPUID::MMX() });
features.push_back({ "MMXEXT", CPUID::MMXEXT() });
features.push_back({ "MONITOR", CPUID::MONITOR() });
features.push_back({ "MOVBE", CPUID::MOVBE() });
features.push_back({ "MSR", CPUID::MSR() });
features.push_back({ "OSXSAVE", CPUID::OSXSAVE() });
features.push_back({ "PCLMULQDQ", CPUID::PCLMULQDQ() });
features.push_back({ "POPCNT", CPUID::POPCNT() });
features.push_back({ "PREFETCHWT1", CPUID::PREFETCHWT1() });
features.push_back({ "RDRAND", CPUID::RDRAND() });
features.push_back({ "RDSEED", CPUID::RDSEED() });
features.push_back({ "RDTSCP", CPUID::RDTSCP() });
features.push_back({ "RTM", CPUID::RTM() });
features.push_back({ "SEP", CPUID::SEP() });
features.push_back({ "SHA", CPUID::SHA() });
features.push_back({ "SSE", CPUID::SSE() });
features.push_back({ "SSE2", CPUID::SSE2() });
features.push_back({ "SSE3", CPUID::SSE3() });
features.push_back({ "SSE4.1", CPUID::SSE41() });
features.push_back({ "SSE4.2", CPUID::SSE42() });
features.push_back({ "SSE4a", CPUID::SSE4a() });
features.push_back({ "SSSE3", CPUID::SSSE3() });
features.push_back({ "SYSCALL", CPUID::SYSCALL() });
features.push_back({ "TBM", CPUID::TBM() });
features.push_back({ "XOP", CPUID::XOP() });
features.push_back({ "XSAVE", CPUID::XSAVE() });
return features;
};
#endif

View file

@ -0,0 +1,212 @@
//
// CPUID.h
//
// Adapted from Microsoft's example for using the cpuid intrinsic,
// found at https://msdn.microsoft.com/en-us/library/hskdteyh.aspx
//
// Provides acccess to information provided by the CPUID opcode
//
// TODO: Generalize to work outside of Windows.
//
// Created by Ryan Huffman on 3/25/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_CPUID_h
#define hifi_CPUID_h
#include <QtCore/QtGlobal>
#include <vector>
#include <bitset>
#include <array>
#include <string>
#ifdef Q_OS_WIN
#include <intrin.h>
class CPUID
{
// forward declarations
class CPUID_Internal;
public:
struct Feature {
std::string name;
bool supported;
};
static std::vector<Feature> getAllFeatures();
static std::string Vendor(void) { return CPU_Rep.vendor_; }
static std::string Brand(void) { return CPU_Rep.brand_; }
static bool SSE3(void) { return CPU_Rep.f_1_ECX_[0]; }
static bool PCLMULQDQ(void) { return CPU_Rep.f_1_ECX_[1]; }
static bool MONITOR(void) { return CPU_Rep.f_1_ECX_[3]; }
static bool SSSE3(void) { return CPU_Rep.f_1_ECX_[9]; }
static bool FMA(void) { return CPU_Rep.f_1_ECX_[12]; }
static bool CMPXCHG16B(void) { return CPU_Rep.f_1_ECX_[13]; }
static bool SSE41(void) { return CPU_Rep.f_1_ECX_[19]; }
static bool SSE42(void) { return CPU_Rep.f_1_ECX_[20]; }
static bool MOVBE(void) { return CPU_Rep.f_1_ECX_[22]; }
static bool POPCNT(void) { return CPU_Rep.f_1_ECX_[23]; }
static bool AES(void) { return CPU_Rep.f_1_ECX_[25]; }
static bool XSAVE(void) { return CPU_Rep.f_1_ECX_[26]; }
static bool OSXSAVE(void) { return CPU_Rep.f_1_ECX_[27]; }
static bool AVX(void) { return CPU_Rep.f_1_ECX_[28]; }
static bool F16C(void) { return CPU_Rep.f_1_ECX_[29]; }
static bool RDRAND(void) { return CPU_Rep.f_1_ECX_[30]; }
static bool MSR(void) { return CPU_Rep.f_1_EDX_[5]; }
static bool CX8(void) { return CPU_Rep.f_1_EDX_[8]; }
static bool SEP(void) { return CPU_Rep.f_1_EDX_[11]; }
static bool CMOV(void) { return CPU_Rep.f_1_EDX_[15]; }
static bool CLFSH(void) { return CPU_Rep.f_1_EDX_[19]; }
static bool MMX(void) { return CPU_Rep.f_1_EDX_[23]; }
static bool FXSR(void) { return CPU_Rep.f_1_EDX_[24]; }
static bool SSE(void) { return CPU_Rep.f_1_EDX_[25]; }
static bool SSE2(void) { return CPU_Rep.f_1_EDX_[26]; }
static bool FSGSBASE(void) { return CPU_Rep.f_7_EBX_[0]; }
static bool BMI1(void) { return CPU_Rep.f_7_EBX_[3]; }
static bool HLE(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[4]; }
static bool AVX2(void) { return CPU_Rep.f_7_EBX_[5]; }
static bool BMI2(void) { return CPU_Rep.f_7_EBX_[8]; }
static bool ERMS(void) { return CPU_Rep.f_7_EBX_[9]; }
static bool INVPCID(void) { return CPU_Rep.f_7_EBX_[10]; }
static bool RTM(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[11]; }
static bool AVX512F(void) { return CPU_Rep.f_7_EBX_[16]; }
static bool RDSEED(void) { return CPU_Rep.f_7_EBX_[18]; }
static bool ADX(void) { return CPU_Rep.f_7_EBX_[19]; }
static bool AVX512PF(void) { return CPU_Rep.f_7_EBX_[26]; }
static bool AVX512ER(void) { return CPU_Rep.f_7_EBX_[27]; }
static bool AVX512CD(void) { return CPU_Rep.f_7_EBX_[28]; }
static bool SHA(void) { return CPU_Rep.f_7_EBX_[29]; }
static bool PREFETCHWT1(void) { return CPU_Rep.f_7_ECX_[0]; }
static bool LAHF(void) { return CPU_Rep.f_81_ECX_[0]; }
static bool LZCNT(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_ECX_[5]; }
static bool ABM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[5]; }
static bool SSE4a(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[6]; }
static bool XOP(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[11]; }
static bool TBM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[21]; }
static bool SYSCALL(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[11]; }
static bool MMXEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[22]; }
static bool RDTSCP(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[27]; }
static bool _3DNOWEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[30]; }
static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }
private:
static const CPUID_Internal CPU_Rep;
class CPUID_Internal
{
public:
CPUID_Internal()
: nIds_ { 0 },
nExIds_ { 0 },
isIntel_ { false },
isAMD_ { false },
f_1_ECX_ { 0 },
f_1_EDX_ { 0 },
f_7_EBX_ { 0 },
f_7_ECX_ { 0 },
f_81_ECX_ { 0 },
f_81_EDX_ { 0 },
data_ {},
extdata_ {}
{
//int cpuInfo[4] = {-1};
std::array<int, 4> cpui;
// Calling __cpuid with 0x0 as the function_id argument
// gets the number of the highest valid function ID.
__cpuid(cpui.data(), 0);
nIds_ = cpui[0];
for (int i = 0; i <= nIds_; ++i) {
__cpuidex(cpui.data(), i, 0);
data_.push_back(cpui);
}
// Capture vendor string
char vendor[0x20];
memset(vendor, 0, sizeof(vendor));
*reinterpret_cast<int*>(vendor) = data_[0][1];
*reinterpret_cast<int*>(vendor + 4) = data_[0][3];
*reinterpret_cast<int*>(vendor + 8) = data_[0][2];
vendor_ = vendor;
if (vendor_ == "GenuineIntel") {
isIntel_ = true;
} else if (vendor_ == "AuthenticAMD") {
isAMD_ = true;
}
// load bitset with flags for function 0x00000001
if (nIds_ >= 1) {
f_1_ECX_ = data_[1][2];
f_1_EDX_ = data_[1][3];
}
// load bitset with flags for function 0x00000007
if (nIds_ >= 7) {
f_7_EBX_ = data_[7][1];
f_7_ECX_ = data_[7][2];
}
// Calling __cpuid with 0x80000000 as the function_id argument
// gets the number of the highest valid extended ID.
__cpuid(cpui.data(), 0x80000000);
nExIds_ = cpui[0];
char brand[0x40];
memset(brand, 0, sizeof(brand));
for (int i = 0x80000000; i <= nExIds_; ++i) {
__cpuidex(cpui.data(), i, 0);
extdata_.push_back(cpui);
}
// load bitset with flags for function 0x80000001
if (nExIds_ >= 0x80000001) {
f_81_ECX_ = extdata_[1][2];
f_81_EDX_ = extdata_[1][3];
}
// Interpret CPU brand string if reported
if (nExIds_ >= 0x80000004) {
memcpy(brand, extdata_[2].data(), sizeof(cpui));
memcpy(brand + 16, extdata_[3].data(), sizeof(cpui));
memcpy(brand + 32, extdata_[4].data(), sizeof(cpui));
brand_ = brand;
}
};
int nIds_;
int nExIds_;
std::string vendor_;
std::string brand_;
bool isIntel_;
bool isAMD_;
std::bitset<32> f_1_ECX_;
std::bitset<32> f_1_EDX_;
std::bitset<32> f_7_EBX_;
std::bitset<32> f_7_ECX_;
std::bitset<32> f_81_ECX_;
std::bitset<32> f_81_EDX_;
std::vector<std::array<int, 4>> data_;
std::vector<std::array<int, 4>> extdata_;
};
};
#endif
#endif // hifi_CPUID_h

View file

@ -23,6 +23,11 @@
#include <windows.h>
#endif
#ifdef Q_OS_WIN
#include "CPUID.h"
#endif
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
@ -30,6 +35,8 @@
#include <QtCore/QDebug>
#include <QDateTime>
#include <QElapsedTimer>
#include <QProcess>
#include <QSysInfo>
#include <QThread>
#include "NumericalConstants.h"
@ -692,3 +699,82 @@ void disableQtBearerPoll() {
qputenv("QT_BEARER_POLL_TIMEOUT", EXTREME_BEARER_POLL_TIMEOUT);
}
void printSystemInformation() {
// Write system information to log
qDebug() << "Build Information";
qDebug().noquote() << "\tBuild ABI: " << QSysInfo::buildAbi();
qDebug().noquote() << "\tBuild CPU Architecture: " << QSysInfo::buildCpuArchitecture();
qDebug().noquote() << "System Information";
qDebug().noquote() << "\tProduct Name: " << QSysInfo::prettyProductName();
qDebug().noquote() << "\tCPU Architecture: " << QSysInfo::currentCpuArchitecture();
qDebug().noquote() << "\tKernel Type: " << QSysInfo::kernelType();
qDebug().noquote() << "\tKernel Version: " << QSysInfo::kernelVersion();
auto macVersion = QSysInfo::macVersion();
if (macVersion != QSysInfo::MV_None) {
qDebug() << "\tMac Version: " << macVersion;
}
auto windowsVersion = QSysInfo::windowsVersion();
if (windowsVersion != QSysInfo::WV_None) {
qDebug() << "\tWindows Version: " << windowsVersion;
}
#ifdef Q_OS_WIN
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
qDebug() << "SYSTEM_INFO";
qDebug().noquote() << "\tOEM ID: " << si.dwOemId;
qDebug().noquote() << "\tProcessor Architecture: " << si.wProcessorArchitecture;
qDebug().noquote() << "\tProcessor Type: " << si.dwProcessorType;
qDebug().noquote() << "\tProcessor Level: " << si.wProcessorLevel;
qDebug().noquote() << "\tProcessor Revision: "
<< QString("0x%1").arg(si.wProcessorRevision, 4, 16, QChar('0'));
qDebug().noquote() << "\tNumber of Processors: " << si.dwNumberOfProcessors;
qDebug().noquote() << "\tPage size: " << si.dwPageSize << " Bytes";
qDebug().noquote() << "\tMin Application Address: "
<< QString("0x%1").arg(qulonglong(si.lpMinimumApplicationAddress), 16, 16, QChar('0'));
qDebug().noquote() << "\tMax Application Address: "
<< QString("0x%1").arg(qulonglong(si.lpMaximumApplicationAddress), 16, 16, QChar('0'));
const double BYTES_TO_MEGABYTE = 1.0 / (1024 * 1024);
qDebug() << "MEMORYSTATUSEX";
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(ms);
if (GlobalMemoryStatusEx(&ms)) {
qDebug().noquote() << QString("\tCurrent System Memory Usage: %1%").arg(ms.dwMemoryLoad);
qDebug().noquote() << QString("\tAvail Physical Memory: %1 MB").arg(ms.ullAvailPhys * BYTES_TO_MEGABYTE, 20, 'f', 2);
qDebug().noquote() << QString("\tTotal Physical Memory: %1 MB").arg(ms.ullTotalPhys * BYTES_TO_MEGABYTE, 20, 'f', 2);
qDebug().noquote() << QString("\tAvail in Page File: %1 MB").arg(ms.ullAvailPageFile * BYTES_TO_MEGABYTE, 20, 'f', 2);
qDebug().noquote() << QString("\tTotal in Page File: %1 MB").arg(ms.ullTotalPageFile * BYTES_TO_MEGABYTE, 20, 'f', 2);
qDebug().noquote() << QString("\tAvail Virtual Memory: %1 MB").arg(ms.ullAvailVirtual * BYTES_TO_MEGABYTE, 20, 'f', 2);
qDebug().noquote() << QString("\tTotal Virtual Memory: %1 MB").arg(ms.ullTotalVirtual * BYTES_TO_MEGABYTE, 20, 'f', 2);
} else {
qDebug() << "\tFailed to retrieve memory status: " << GetLastError();
}
qDebug() << "CPUID";
qDebug() << "\tCPU Vendor: " << CPUID::Vendor().c_str();
qDebug() << "\tCPU Brand: " << CPUID::Brand().c_str();
for (auto& feature : CPUID::getAllFeatures()) {
qDebug().nospace().noquote() << "\t[" << (feature.supported ? "x" : " ") << "] " << feature.name.c_str();
}
#endif
qDebug() << "Environment Variables";
// List of env variables to include in the log. For privacy reasons we don't send all env variables.
const QStringList envWhitelist = {
"QTWEBENGINE_REMOTE_DEBUGGING"
};
auto envVariables = QProcessEnvironment::systemEnvironment();
for (auto& env : envWhitelist)
{
qDebug().noquote().nospace() << "\t" <<
(envVariables.contains(env) ? " = " + envVariables.value(env) : " NOT FOUND");
}
}

View file

@ -198,4 +198,6 @@ uint qHash(const std::shared_ptr<T>& ptr, uint seed = 0)
void disableQtBearerPoll();
void printSystemInformation();
#endif // hifi_SharedUtil_h