From 503cb0b93e5f1f454c79032996b2d72a7a161f1c Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 00:16:44 +0200 Subject: [PATCH 1/7] update GLCheck to be more informative and enable in release Also disable GLCheck unconditionally aborting, now it just prints the error to console. --- Source/System/GLCheck.cpp | 75 +++++++++++++++++++++++++++++++++++---- Source/System/GLCheck.h | 4 --- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/Source/System/GLCheck.cpp b/Source/System/GLCheck.cpp index b10453836c..7e7f8e7aea 100644 --- a/Source/System/GLCheck.cpp +++ b/Source/System/GLCheck.cpp @@ -1,13 +1,74 @@ #include "GLCheck.h" #include "glad/gl.h" -#include -#include +#include +#include +#include "ConsoleMan.h" void CheckOpenGLError(const char* stmt, const char* fname, int line) { - GLenum err = glGetError(); - if (err != GL_NO_ERROR) { - printf("OpenGL error %08x, at %s:%i - for %s\n", err, fname, line, stmt); - abort(); + GLenum errorCode = glGetError(); + + if (errorCode != GL_NO_ERROR) { + std::string fileString = fname; + std::string error = "Unknown error"; + std::string description = "No description"; + + // Decode the error code + switch (errorCode) { + case GL_INVALID_ENUM: { + error = "GL_INVALID_ENUM"; + description = "An unacceptable value has been specified for an enumerated argument."; + break; + } + + case GL_INVALID_VALUE: { + error = "GL_INVALID_VALUE"; + description = "A numeric argument is out of range."; + break; + } + + case GL_INVALID_OPERATION: { + error = "GL_INVALID_OPERATION"; + description = "The specified operation is not allowed in the current state."; + break; + } + + case GL_STACK_OVERFLOW: { + error = "GL_STACK_OVERFLOW"; + description = "This command would cause a stack overflow."; + break; + } + + case GL_STACK_UNDERFLOW: { + error = "GL_STACK_UNDERFLOW"; + description = "This command would cause a stack underflow."; + break; + } + + case GL_OUT_OF_MEMORY: { + error = "GL_OUT_OF_MEMORY"; + description = "There is not enough memory left to execute the command."; + break; + } + + case GL_INVALID_FRAMEBUFFER_OPERATION: { + error = "GL_INVALID_FRAMEBUFFER_OPERATION"; + description = "The object bound to FRAMEBUFFER_BINDING is not \"framebuffer complete\"."; + break; + } + + default: { + error = "Unknown Error: " + std::to_string(errorCode); + description = ""; + } + } + + // Log the error + std::stringstream errorMessage; + errorMessage << "ERROR: An internal OpenGL call failed in " + << fileString.substr(fileString.find_last_of("\\/") + 1) << "(" << line << ")." + << "\nExpression:\n " << stmt + << "\nError description:\n " << error << "\n " << description << "\n"; + g_ConsoleMan.PrintString(errorMessage.str()); } -} +} \ No newline at end of file diff --git a/Source/System/GLCheck.h b/Source/System/GLCheck.h index 260b20ce20..8a92522be7 100644 --- a/Source/System/GLCheck.h +++ b/Source/System/GLCheck.h @@ -5,12 +5,8 @@ void CheckOpenGLError(const char* stmt, const char* fname, int line); /// Debug macro to be used for all GL calls. -#ifdef DEBUG #define GL_CHECK(stmt) \ do { \ stmt; \ CheckOpenGLError(#stmt, __FILE__, __LINE__); \ } while (0) -#else -#define GL_CHECK(stmt) stmt -#endif From aa0103e18bcb6738b48a3ae21ee737dfdddc8ee1 Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 00:46:46 +0200 Subject: [PATCH 2/7] fix namespace --- Source/System/GLCheck.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/System/GLCheck.cpp b/Source/System/GLCheck.cpp index 7e7f8e7aea..168406fa83 100644 --- a/Source/System/GLCheck.cpp +++ b/Source/System/GLCheck.cpp @@ -4,6 +4,7 @@ #include #include #include "ConsoleMan.h" +using namespace RTE; void CheckOpenGLError(const char* stmt, const char* fname, int line) { GLenum errorCode = glGetError(); @@ -58,7 +59,7 @@ void CheckOpenGLError(const char* stmt, const char* fname, int line) { } default: { - error = "Unknown Error: " + std::to_string(errorCode); + error = "Unknown Error" + std::to_string(errorCode); description = ""; } } From 684e6f5882999b1c108e944765e6ce22bd6b60cb Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 22:04:48 +0200 Subject: [PATCH 3/7] add os and hardware reporting to abortlog --- Source/System/RTEError.cpp | 143 +++++++++++++++++++++++++++++++++++-- Source/System/RTEError.h | 9 +++ 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/Source/System/RTEError.cpp b/Source/System/RTEError.cpp index dd5cb5e5c5..247bc2c533 100644 --- a/Source/System/RTEError.cpp +++ b/Source/System/RTEError.cpp @@ -20,6 +20,20 @@ #include #include + +#ifdef __MSVC__ +#include +#else +#include +#endif +#ifdef __linux__ +#include +#include +#include +#elif defined(__APPLE__) && defined(__MACH__) +#include +#endif + using namespace RTE; bool RTEError::s_CurrentlyAborting = false; @@ -326,6 +340,8 @@ void RTEError::AbortFunc(const std::string& description, const std::source_locat g_ConsoleMan.PrintString(abortMessage); + DumpHardwareInfo(); + std::string callstack = ""; #ifdef _WIN32 @@ -386,8 +402,8 @@ void RTEError::AssertFunc(const std::string& description, const std::source_loca if (!s_IgnoreAllAsserts) { std::string assertMessage = - "Assertion in file '" + fileName + "', line " + lineNum + ",\nin function '" + funcName + "'\nbecause:\n\n" + description + "\n\n" - "You may choose to ignore this and crash immediately\nor at some unexpected point later on.\n\nProceed at your own risk!"; + "Assertion in file '" + fileName + "', line " + lineNum + ",\nin function '" + funcName + "'\nbecause:\n\n" + description + "\n\n" + + "You may choose to ignore this and crash immediately\nor at some unexpected point later on.\n\nProceed at your own risk!"; if (ShowAssertMessageBox(assertMessage)) { AbortFunc(description, srcLocation); @@ -404,6 +420,122 @@ void RTEError::AssertFunc(const std::string& description, const std::source_loca } } +void RTEError::DumpHardwareInfo() { + std::string glVersion = reinterpret_cast(glGetString(GL_VERSION)); + std::string glVendor = reinterpret_cast(glGetString(GL_VENDOR)); + std::string glRenderer = reinterpret_cast(glGetString(GL_RENDERER)); + std::string hwInfo = "GL Version: " + glVersion + "\n" + + "GL Vendor: " + glVendor + "\n" + + "GL Renderer: " + glRenderer + "\n"; + + unsigned int vendorRegs[4] = {0}; +#if defined(_MSC_VER) || defined(__linux__) +#ifdef _MSC_VER + __cpuid(reinterpret_cast(cpuInfo), 0); +#else + __cpuid(0, vendorRegs[0], vendorRegs[1], vendorRegs[2], vendorRegs[3]); +#endif + + std::string cpuVendor(reinterpret_cast(&vendorRegs[1]), 4); + cpuVendor += std::string(reinterpret_cast(&vendorRegs[3]), 4); + cpuVendor += std::string(reinterpret_cast(&vendorRegs[2]), 4); + + hwInfo += "CPU Manufacturer ID: " + cpuVendor + "\n"; + + std::string cpuModel; + unsigned int modelRegs[12]; +#ifdef _MSC_VER + __cpuid(cpuInfo, 0x80000000); +#else + __cpuid(0x80000000, modelRegs[0], modelRegs[1], modelRegs[2], modelRegs[3]); +#endif + if (modelRegs[0] >= 0x80000004) { + for (size_t i = 0; i <= 2; ++i) { +#ifdef _MSC_VER + __cpuid(&modelRegs[0] + i * 4, i + 0x80000002); +#else + __cpuid(i + 0x80000002, modelRegs[0 + i * 4], modelRegs[1 + i * 4], modelRegs[2 + i * 4], modelRegs[3 + i * 4]); +#endif + } + for (size_t i = 0; i < 12; ++i) { + cpuModel += std::string(reinterpret_cast(&modelRegs[i]), 4); + } + + hwInfo += "CPU Model: " + cpuModel + "\n"; + } +#elif defined(__APPLE__) && defined(__MACH__) + char vendor[1024]; + size_t vendorSize = sizeof(vendor); + int error = sysctlbyname("machdep.cpu.vendor", &vendor, &vendorSize, nullptr, 0); + if (!error) { + hwInfo += "CPU Vendor: " + std::string(vendor) + "\n"; + } + char brand[1024]; + size_t brandSize = sizeof(brand); + error = sysctlbyname("machdep.cpu.brand_string", &brand, &brandSize, nullptr, 0); + if (!error) { + hwInfo += "CPU Model: " + std::string(brand) + "\n"; + } +#endif + + g_ConsoleMan.PrintString(hwInfo); + +#ifdef __unix__ + struct utsname unameData; + if (uname(&unameData) == 0) { + std::string osInfo = "uname: " + std::string(unameData.sysname) + " " + std::string(unameData.release) + " " + std::string(unameData.version); + g_ConsoleMan.PrintString(osInfo); + } +#endif + +#ifdef _MSC_VER + g_ConsoleMan.PrintString("OS: Windows"); +#endif + +#ifdef __linux__ + // Read distribution info from /etc/os-release + if (std::filesystem::exists("/etc/os-release")) { + std::ifstream osReleaseFile("/etc/os-release"); + if (osReleaseFile.is_open()) { + std::string line; + while (std::getline(osReleaseFile, line)) { + if (line.find("PRETTY_NAME") != std::string::npos) { + g_ConsoleMan.PrintString("OS: " + line.substr(line.find_first_of('"') + 1, line.find_last_of('"') - line.find_first_of('"') - 1)); + break; + } + } + osReleaseFile.close(); + } + } else { + g_ConsoleMan.PrintString("OS: Unknown Linux (/etc/os-release not found)"); + } +#endif + +#if defined(__APPLE__) && defined(__MACH__) + char osType[1024]; + size_t osTypeSize = sizeof(osType); + error = sysctlbyname("kern.ostype", &osType, &osTypeSize, nullptr, 0); + if (!error) { + g_ConsoleMan.PrintString("OS Type: " + std::string(osType)); + } + + char osRelease[1024]; + size_t osReleaseSize = sizeof(osRelease); + error = sysctlbyname("kern.osrelease", &osRelease, &osReleaseSize, nullptr, 0); + if (!error) { + g_ConsoleMan.PrintString("OS Release: " + std::string(osRelease)); + } + + char osVersion[1024]; + size_t osVersionSize = sizeof(osVersion); + error = sysctlbyname("kern.osversion", &osVersion, &osVersionSize, nullptr, 0); + if (!error) { + g_ConsoleMan.PrintString("OS Version: " + std::string(osVersion)); + } +#endif + +} + bool RTEError::DumpAbortScreen() { int success = -1; if (glReadPixels != nullptr) { @@ -442,9 +574,10 @@ bool RTEError::DumpAbortSave() { void RTEError::FormatFunctionSignature(std::string& symbolName) { // TODO: Expand this with more dumb signatures, or make something that makes more sense. - static const std::array, 3> stlSigs{{{std::regex("( >)"), ">"}, - {std::regex("(std::basic_string,std::allocator>)"), "std::string"}, - {std::regex("(class ?std::basic_string,class ?std::allocator>)"), "std::string"}}}; + static const std::array, 3> stlSigs{ + {{std::regex("( >)"), ">"}, + {std::regex("(std::basic_string,std::allocator>)"), "std::string"}, + {std::regex("(class ?std::basic_string,class ?std::allocator>)"), "std::string"}}}; for (const auto& [fullSig, simpleSig]: stlSigs) { symbolName = std::regex_replace(symbolName, fullSig, simpleSig); } diff --git a/Source/System/RTEError.h b/Source/System/RTEError.h index 30a4c0d48d..d06c8b49be 100644 --- a/Source/System/RTEError.h +++ b/Source/System/RTEError.h @@ -66,6 +66,15 @@ namespace RTE { /// @return Whether to abort, or ignore the assert and continue execution. static bool ShowAssertMessageBox(const std::string& message); + /// Prints details on the user hardware to the abort log. + /// @remark + /// Included details: + /// OpenGL version string, OpenGL GPU vendor string, OpenGL Renderer string. + /// CPU vendor and brand string (as reported by cpuid on windows and linux or sysctl on macos). + /// linux: uname sysname, release, version. + /// macos: sysctl kern.osrelease, kern.ostype, kern.osversion. + static void DumpHardwareInfo(); + /// Saves the current frame to a file. /// @return Whether the file was saved successfully.@return static bool DumpAbortScreen(); From 324df91cda5d33481b64333483f67be31e75fabd Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 22:22:15 +0200 Subject: [PATCH 4/7] fix windows compile --- Source/System/RTEError.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/System/RTEError.cpp b/Source/System/RTEError.cpp index 247bc2c533..467d3bd11c 100644 --- a/Source/System/RTEError.cpp +++ b/Source/System/RTEError.cpp @@ -20,12 +20,12 @@ #include #include - -#ifdef __MSVC__ +#ifdef _MSC_VER #include -#else +#elif defined(__linux__) #include #endif + #ifdef __linux__ #include #include @@ -431,7 +431,7 @@ void RTEError::DumpHardwareInfo() { unsigned int vendorRegs[4] = {0}; #if defined(_MSC_VER) || defined(__linux__) #ifdef _MSC_VER - __cpuid(reinterpret_cast(cpuInfo), 0); + __cpuid(reinterpret_cast(vendorRegs), 0); #else __cpuid(0, vendorRegs[0], vendorRegs[1], vendorRegs[2], vendorRegs[3]); #endif @@ -445,7 +445,7 @@ void RTEError::DumpHardwareInfo() { std::string cpuModel; unsigned int modelRegs[12]; #ifdef _MSC_VER - __cpuid(cpuInfo, 0x80000000); + __cpuid(reinterpret_cast(modelRegs), 0x80000000); #else __cpuid(0x80000000, modelRegs[0], modelRegs[1], modelRegs[2], modelRegs[3]); #endif From 0c86e06f6fdf9622411aae3ab36a0294b9c72396 Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 22:24:50 +0200 Subject: [PATCH 5/7] formatting --- Source/System/GLCheck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/System/GLCheck.cpp b/Source/System/GLCheck.cpp index 168406fa83..2d09008cf9 100644 --- a/Source/System/GLCheck.cpp +++ b/Source/System/GLCheck.cpp @@ -67,9 +67,9 @@ void CheckOpenGLError(const char* stmt, const char* fname, int line) { // Log the error std::stringstream errorMessage; errorMessage << "ERROR: An internal OpenGL call failed in " - << fileString.substr(fileString.find_last_of("\\/") + 1) << "(" << line << ")." - << "\nExpression:\n " << stmt - << "\nError description:\n " << error << "\n " << description << "\n"; + << fileString.substr(fileString.find_last_of("\\/") + 1) << "(" << line << ")." + << "\nExpression:\n " << stmt + << "\nError description:\n " << error << "\n " << description << "\n"; g_ConsoleMan.PrintString(errorMessage.str()); } } \ No newline at end of file From 82f419e41f47e2292d449e7aef3734b37a1977cd Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 22:32:46 +0200 Subject: [PATCH 6/7] read msvc cpuid docs --- Source/System/RTEError.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/System/RTEError.cpp b/Source/System/RTEError.cpp index 467d3bd11c..cf0f736c77 100644 --- a/Source/System/RTEError.cpp +++ b/Source/System/RTEError.cpp @@ -428,10 +428,10 @@ void RTEError::DumpHardwareInfo() { "GL Vendor: " + glVendor + "\n" + "GL Renderer: " + glRenderer + "\n"; - unsigned int vendorRegs[4] = {0}; #if defined(_MSC_VER) || defined(__linux__) + int vendorRegs[4] = {0}; #ifdef _MSC_VER - __cpuid(reinterpret_cast(vendorRegs), 0); + __cpuid(vendorRegs, 0); #else __cpuid(0, vendorRegs[0], vendorRegs[1], vendorRegs[2], vendorRegs[3]); #endif @@ -443,9 +443,9 @@ void RTEError::DumpHardwareInfo() { hwInfo += "CPU Manufacturer ID: " + cpuVendor + "\n"; std::string cpuModel; - unsigned int modelRegs[12]; + int modelRegs[12]; #ifdef _MSC_VER - __cpuid(reinterpret_cast(modelRegs), 0x80000000); + __cpuid(modelRegs, 0x80000000); #else __cpuid(0x80000000, modelRegs[0], modelRegs[1], modelRegs[2], modelRegs[3]); #endif From dd786081932ada78018b7b56b56f107d4a4f65c3 Mon Sep 17 00:00:00 2001 From: HeliumAnt Date: Tue, 9 Apr 2024 22:47:34 +0200 Subject: [PATCH 7/7] formatting --- Source/System/GLCheck.cpp | 2 +- Source/System/RTEError.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/System/GLCheck.cpp b/Source/System/GLCheck.cpp index 2d09008cf9..93d7d0bc91 100644 --- a/Source/System/GLCheck.cpp +++ b/Source/System/GLCheck.cpp @@ -72,4 +72,4 @@ void CheckOpenGLError(const char* stmt, const char* fname, int line) { << "\nError description:\n " << error << "\n " << description << "\n"; g_ConsoleMan.PrintString(errorMessage.str()); } -} \ No newline at end of file +} diff --git a/Source/System/RTEError.cpp b/Source/System/RTEError.cpp index cf0f736c77..14ff3b27fa 100644 --- a/Source/System/RTEError.cpp +++ b/Source/System/RTEError.cpp @@ -533,7 +533,6 @@ void RTEError::DumpHardwareInfo() { g_ConsoleMan.PrintString("OS Version: " + std::string(osVersion)); } #endif - } bool RTEError::DumpAbortScreen() {