Skip to content

Commit 684e6f5

Browse files
committed
add os and hardware reporting to abortlog
1 parent aa0103e commit 684e6f5

File tree

2 files changed

+147
-5
lines changed

2 files changed

+147
-5
lines changed

Source/System/RTEError.cpp

Lines changed: 138 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@
2020
#include <utility>
2121
#include <vector>
2222

23+
24+
#ifdef __MSVC__
25+
#include <intrin.h>
26+
#else
27+
#include <cpuid.h>
28+
#endif
29+
#ifdef __linux__
30+
#include <sys/utsname.h>
31+
#include <fstream>
32+
#include <filesystem>
33+
#elif defined(__APPLE__) && defined(__MACH__)
34+
#include <sys/sysctl.h>
35+
#endif
36+
2337
using namespace RTE;
2438

2539
bool RTEError::s_CurrentlyAborting = false;
@@ -326,6 +340,8 @@ void RTEError::AbortFunc(const std::string& description, const std::source_locat
326340

327341
g_ConsoleMan.PrintString(abortMessage);
328342

343+
DumpHardwareInfo();
344+
329345
std::string callstack = "";
330346

331347
#ifdef _WIN32
@@ -386,8 +402,8 @@ void RTEError::AssertFunc(const std::string& description, const std::source_loca
386402

387403
if (!s_IgnoreAllAsserts) {
388404
std::string assertMessage =
389-
"Assertion in file '" + fileName + "', line " + lineNum + ",\nin function '" + funcName + "'\nbecause:\n\n" + description + "\n\n"
390-
"You may choose to ignore this and crash immediately\nor at some unexpected point later on.\n\nProceed at your own risk!";
405+
"Assertion in file '" + fileName + "', line " + lineNum + ",\nin function '" + funcName + "'\nbecause:\n\n" + description + "\n\n" +
406+
"You may choose to ignore this and crash immediately\nor at some unexpected point later on.\n\nProceed at your own risk!";
391407

392408
if (ShowAssertMessageBox(assertMessage)) {
393409
AbortFunc(description, srcLocation);
@@ -404,6 +420,122 @@ void RTEError::AssertFunc(const std::string& description, const std::source_loca
404420
}
405421
}
406422

423+
void RTEError::DumpHardwareInfo() {
424+
std::string glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
425+
std::string glVendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
426+
std::string glRenderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
427+
std::string hwInfo = "GL Version: " + glVersion + "\n" +
428+
"GL Vendor: " + glVendor + "\n" +
429+
"GL Renderer: " + glRenderer + "\n";
430+
431+
unsigned int vendorRegs[4] = {0};
432+
#if defined(_MSC_VER) || defined(__linux__)
433+
#ifdef _MSC_VER
434+
__cpuid(reinterpret_cast<int*>(cpuInfo), 0);
435+
#else
436+
__cpuid(0, vendorRegs[0], vendorRegs[1], vendorRegs[2], vendorRegs[3]);
437+
#endif
438+
439+
std::string cpuVendor(reinterpret_cast<const char*>(&vendorRegs[1]), 4);
440+
cpuVendor += std::string(reinterpret_cast<const char*>(&vendorRegs[3]), 4);
441+
cpuVendor += std::string(reinterpret_cast<const char*>(&vendorRegs[2]), 4);
442+
443+
hwInfo += "CPU Manufacturer ID: " + cpuVendor + "\n";
444+
445+
std::string cpuModel;
446+
unsigned int modelRegs[12];
447+
#ifdef _MSC_VER
448+
__cpuid(cpuInfo, 0x80000000);
449+
#else
450+
__cpuid(0x80000000, modelRegs[0], modelRegs[1], modelRegs[2], modelRegs[3]);
451+
#endif
452+
if (modelRegs[0] >= 0x80000004) {
453+
for (size_t i = 0; i <= 2; ++i) {
454+
#ifdef _MSC_VER
455+
__cpuid(&modelRegs[0] + i * 4, i + 0x80000002);
456+
#else
457+
__cpuid(i + 0x80000002, modelRegs[0 + i * 4], modelRegs[1 + i * 4], modelRegs[2 + i * 4], modelRegs[3 + i * 4]);
458+
#endif
459+
}
460+
for (size_t i = 0; i < 12; ++i) {
461+
cpuModel += std::string(reinterpret_cast<const char*>(&modelRegs[i]), 4);
462+
}
463+
464+
hwInfo += "CPU Model: " + cpuModel + "\n";
465+
}
466+
#elif defined(__APPLE__) && defined(__MACH__)
467+
char vendor[1024];
468+
size_t vendorSize = sizeof(vendor);
469+
int error = sysctlbyname("machdep.cpu.vendor", &vendor, &vendorSize, nullptr, 0);
470+
if (!error) {
471+
hwInfo += "CPU Vendor: " + std::string(vendor) + "\n";
472+
}
473+
char brand[1024];
474+
size_t brandSize = sizeof(brand);
475+
error = sysctlbyname("machdep.cpu.brand_string", &brand, &brandSize, nullptr, 0);
476+
if (!error) {
477+
hwInfo += "CPU Model: " + std::string(brand) + "\n";
478+
}
479+
#endif
480+
481+
g_ConsoleMan.PrintString(hwInfo);
482+
483+
#ifdef __unix__
484+
struct utsname unameData;
485+
if (uname(&unameData) == 0) {
486+
std::string osInfo = "uname: " + std::string(unameData.sysname) + " " + std::string(unameData.release) + " " + std::string(unameData.version);
487+
g_ConsoleMan.PrintString(osInfo);
488+
}
489+
#endif
490+
491+
#ifdef _MSC_VER
492+
g_ConsoleMan.PrintString("OS: Windows");
493+
#endif
494+
495+
#ifdef __linux__
496+
// Read distribution info from /etc/os-release
497+
if (std::filesystem::exists("/etc/os-release")) {
498+
std::ifstream osReleaseFile("/etc/os-release");
499+
if (osReleaseFile.is_open()) {
500+
std::string line;
501+
while (std::getline(osReleaseFile, line)) {
502+
if (line.find("PRETTY_NAME") != std::string::npos) {
503+
g_ConsoleMan.PrintString("OS: " + line.substr(line.find_first_of('"') + 1, line.find_last_of('"') - line.find_first_of('"') - 1));
504+
break;
505+
}
506+
}
507+
osReleaseFile.close();
508+
}
509+
} else {
510+
g_ConsoleMan.PrintString("OS: Unknown Linux (/etc/os-release not found)");
511+
}
512+
#endif
513+
514+
#if defined(__APPLE__) && defined(__MACH__)
515+
char osType[1024];
516+
size_t osTypeSize = sizeof(osType);
517+
error = sysctlbyname("kern.ostype", &osType, &osTypeSize, nullptr, 0);
518+
if (!error) {
519+
g_ConsoleMan.PrintString("OS Type: " + std::string(osType));
520+
}
521+
522+
char osRelease[1024];
523+
size_t osReleaseSize = sizeof(osRelease);
524+
error = sysctlbyname("kern.osrelease", &osRelease, &osReleaseSize, nullptr, 0);
525+
if (!error) {
526+
g_ConsoleMan.PrintString("OS Release: " + std::string(osRelease));
527+
}
528+
529+
char osVersion[1024];
530+
size_t osVersionSize = sizeof(osVersion);
531+
error = sysctlbyname("kern.osversion", &osVersion, &osVersionSize, nullptr, 0);
532+
if (!error) {
533+
g_ConsoleMan.PrintString("OS Version: " + std::string(osVersion));
534+
}
535+
#endif
536+
537+
}
538+
407539
bool RTEError::DumpAbortScreen() {
408540
int success = -1;
409541
if (glReadPixels != nullptr) {
@@ -442,9 +574,10 @@ bool RTEError::DumpAbortSave() {
442574

443575
void RTEError::FormatFunctionSignature(std::string& symbolName) {
444576
// TODO: Expand this with more dumb signatures, or make something that makes more sense.
445-
static const std::array<std::pair<std::regex, std::string>, 3> stlSigs{{{std::regex("( >)"), ">"},
446-
{std::regex("(std::basic_string<char,std::char_traits<char>,std::allocator<char>>)"), "std::string"},
447-
{std::regex("(class ?std::basic_string<char,struct ?std::char_traits<char>,class ?std::allocator<char>>)"), "std::string"}}};
577+
static const std::array<std::pair<std::regex, std::string>, 3> stlSigs{
578+
{{std::regex("( >)"), ">"},
579+
{std::regex("(std::basic_string<char,std::char_traits<char>,std::allocator<char>>)"), "std::string"},
580+
{std::regex("(class ?std::basic_string<char,struct ?std::char_traits<char>,class ?std::allocator<char>>)"), "std::string"}}};
448581
for (const auto& [fullSig, simpleSig]: stlSigs) {
449582
symbolName = std::regex_replace(symbolName, fullSig, simpleSig);
450583
}

Source/System/RTEError.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ namespace RTE {
6666
/// @return Whether to abort, or ignore the assert and continue execution.
6767
static bool ShowAssertMessageBox(const std::string& message);
6868

69+
/// Prints details on the user hardware to the abort log.
70+
/// @remark
71+
/// Included details:
72+
/// OpenGL version string, OpenGL GPU vendor string, OpenGL Renderer string.
73+
/// CPU vendor and brand string (as reported by cpuid on windows and linux or sysctl on macos).
74+
/// linux: uname sysname, release, version.
75+
/// macos: sysctl kern.osrelease, kern.ostype, kern.osversion.
76+
static void DumpHardwareInfo();
77+
6978
/// Saves the current frame to a file.
7079
/// @return Whether the file was saved successfully.@return
7180
static bool DumpAbortScreen();

0 commit comments

Comments
 (0)