From f4a6da7fb0e74766fbdc404c2ff388dce776910c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 19:13:56 +0100 Subject: [PATCH 1/5] Try to detect if compiling with a 32bit or 64bit compiler. --- src/LibraryInfo.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/LibraryInfo.cc b/src/LibraryInfo.cc index 83f3875c..71e36971 100644 --- a/src/LibraryInfo.cc +++ b/src/LibraryInfo.cc @@ -29,12 +29,20 @@ std::string LibraryInfo::info() { std::stringstream s; +#if defined(__x86_64__) || defined(_M_X64) + std::string bits(" 64bit"); +#elif defined(__i386) || defined(_M_IX86) + std::string bits(" 32bit"); +#else + std::string bits(""); +#endif + #if defined(__GNUG__) && !defined(__clang__) - std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) ); + std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) + bits); #elif defined(_MSC_VER) - std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) ); + std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) + bits); #elif defined(__clang__) - std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) ); + std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) + bits); #else std::string compiler_info( "unknown compiler" ); #endif From f7816e02cd720b95cac4b415706c5d8ade94d87f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 19:14:43 +0100 Subject: [PATCH 2/5] Add system info (OS / CPUs/ RAM / Distribution (when on Linux)). --- src/LibraryInfo.cc | 1 + src/PlatformUtils-mac.mm | 42 +++++++++++++++ src/PlatformUtils-posix.cc | 102 +++++++++++++++++++++++++++++++++++++ src/PlatformUtils-win.cc | 90 ++++++++++++++++++++++++++++++++ src/PlatformUtils.cc | 23 +++++++++ src/PlatformUtils.h | 20 ++++++++ 6 files changed, 278 insertions(+) diff --git a/src/LibraryInfo.cc b/src/LibraryInfo.cc index 71e36971..52facbb1 100644 --- a/src/LibraryInfo.cc +++ b/src/LibraryInfo.cc @@ -88,6 +88,7 @@ std::string LibraryInfo::info() const char *env_font_path = getenv("OPENSCAD_FONT_PATH"); s << "OpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION) + << "\nSystem information: " << PlatformUtils::sysinfo() << "\nCompiler, build date: " << compiler_info << ", " << __DATE__ << "\nBoost version: " << BOOST_LIB_VERSION << "\nEigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index cb93e522..20e72321 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -35,5 +35,47 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +std::string PlatformUtils::sysinfo() +{ + std::string result; + +#if 0 + struct utsname osinfo; + if (uname(&osinfo) == 0) { + result += osinfo.sysname; + result += " "; + result += osinfo.release; + result += " "; + result += osinfo.version; + result += " "; + result += osinfo.machine; + } else { +#endif + result += "Unknown MacOS"; +#if 0 + } + + long numcpu = sysconf(_SC_NPROCESSORS_ONLN); + if (numcpu > 0) { + result += " "; + result += boost::lexical_cast(numcpu); + result += " CPU"; + if (numcpu > 1) { + result += "s"; + } + } + + long pages = sysconf(_SC_PHYS_PAGES); + long pagesize = sysconf(_SC_PAGE_SIZE); + if ((pages > 0) && (pagesize > 0)) { + result += " "; + result += PlatformUtils::toMemorySizeString(pages * pagesize, 2); + result += " RAM"; + } +#endif + + return result; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index 3854a5e7..dbeaa411 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -1,4 +1,13 @@ +#include +#include +#include +#include #include +#include + +#include +#include +#include #include "PlatformUtils.h" #include "boosty.h" @@ -60,5 +69,98 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +/** + * Check /etc/os-release as defined by systemd. + * @see http://0pointer.de/blog/projects/os-release.html + * @see http://www.freedesktop.org/software/systemd/man/os-release.html + * @return the PRETTY_NAME from the os-release file or an empty string. + */ +static std::string checkOsRelease() +{ + std::ifstream os_release_stream("/etc/os-release"); + std::string os_release((std::istreambuf_iterator(os_release_stream)), std::istreambuf_iterator()); + + boost::smatch results; + boost::regex pretty_name("^PRETTY_NAME=\"([^\"]+)\""); + if (boost::regex_search(os_release, results, pretty_name)) { + return results[1]; + } + + return ""; +} + +static std::string checkEtcIssue() +{ + std::ifstream issue_stream("/etc/issue"); + std::string issue((std::istreambuf_iterator(issue_stream)), std::istreambuf_iterator()); + + boost::regex nl("\n.*$"); + issue = boost::regex_replace(issue, nl, ""); + boost::regex esc("\\\\."); + issue = boost::regex_replace(issue, esc, ""); + boost::algorithm::trim(issue); + + return issue; +} + +static std::string detectDistribution() +{ + std::string osrelease = checkOsRelease(); + if (!osrelease.empty()) { + return osrelease; + } + + std::string etcissue = checkEtcIssue(); + if (!etcissue.empty()) { + return etcissue; + } + + return ""; +} + +std::string PlatformUtils::sysinfo() +{ + std::string result; + + struct utsname osinfo; + if (uname(&osinfo) == 0) { + result += osinfo.sysname; + result += " "; + result += osinfo.release; + result += " "; + result += osinfo.version; + result += " "; + result += osinfo.machine; + } else { + result += "Unknown Linux"; + } + + long numcpu = sysconf(_SC_NPROCESSORS_ONLN); + if (numcpu > 0) { + result += " "; + result += boost::lexical_cast(numcpu); + result += " CPU"; + if (numcpu > 1) { + result += "s"; + } + } + + long pages = sysconf(_SC_PHYS_PAGES); + long pagesize = sysconf(_SC_PAGE_SIZE); + if ((pages > 0) && (pagesize > 0)) { + result += " "; + result += PlatformUtils::toMemorySizeString(pages * pagesize, 2); + result += " RAM"; + } + + std::string distribution = detectDistribution(); + if (!distribution.empty()) { + result += " "; + result += distribution; + } + + return result; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index c83855d0..1f07b683 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -98,6 +98,96 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + +// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx +static BOOL IsWow64() +{ + BOOL bIsWow64 = FALSE; + + //IsWow64Process is not available on all supported versions of Windows. + //Use GetModuleHandle to get a handle to the DLL that contains the function + //and GetProcAddress to get a pointer to the function if available. + LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + + if (NULL != fnIsWow64Process) { + if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) + { + return false; + } + } + return bIsWow64; +} + +std::string PlatformUtils::sysinfo() +{ + std::string result; + + OSVERSIONINFOEX osinfo; + osinfo.dwOSVersionInfoSize = sizeof(osinfo); + if (GetVersionEx((OSVERSIONINFO*)&osinfo) == 0) { + result += "Unknown Windows"; + } else { + unsigned int version = osinfo.dwMajorVersion * 1000 + osinfo.dwMinorVersion; + if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { + switch (version) { + case 5000: + result += "Windows 2000"; + break; + case 5001: + result += "Windows XP"; + break; + case 5002: + result += "Windows Server 2003"; + break; + case 6000: + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008"); + break; + case 6001: + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2"); + break; + case 6002: + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012"); + break; + case 6003: + // For applications that have been manifested for Windows 8.1. + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2"); + break; + } + boost::format fmt(" (v%d.%d)"); + fmt % osinfo.dwMajorVersion % osinfo.dwMinorVersion; + result += fmt.str(); + } else { + boost::format fmt("Unknown Windows (dwPlatformId = %d, dwMajorVersion = %d, dwMinorVersion = %d"); + fmt % osinfo.dwPlatformId % osinfo.dwMajorVersion % osinfo.dwMinorVersion; + result += fmt.str(); + } + } + + SYSTEM_INFO systeminfo; + bool isWow64 = IsWow64(); + if (isWow64) { + GetNativeSystemInfo(&systeminfo); + } else { + GetSystemInfo(&systeminfo); + } + + int numcpu = systeminfo.dwNumberOfProcessors; + boost::format fmt(" %d CPU%s%s"); + fmt % numcpu % (numcpu > 1 ? "s" : "") % (isWow64 ? " WOW64" : ""); + result += fmt.str(); + + MEMORYSTATUSEX memoryinfo; + memoryinfo.dwLength = sizeof(memoryinfo); + if (GlobalMemoryStatusEx(&memoryinfo) != 0) { + result += " "; + result += PlatformUtils::toMemorySizeString(memoryinfo.ullTotalPhys, 2); + result += " RAM"; + } + + return result; +} + #include #include #include diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 2ebc9950..a15a0a3c 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -1,4 +1,5 @@ #include +#include #include "PlatformUtils.h" @@ -190,3 +191,25 @@ int PlatformUtils::setenv(const char *name, const char *value, int overwrite) return ::setenv(name, value, overwrite); #endif } + +std::string PlatformUtils::toMemorySizeString(unsigned long bytes, int digits) +{ + static const char *units[] = { "B", "kB", "MB", "GB", "TB", NULL }; + + int idx = 0; + double val = bytes; + while (true) { + if (val < 1024.0) { + break; + } + if (units[idx + 1] == NULL) { + break; + } + idx++; + val /= 1024.0; + } + + boost::format fmt("%f %s"); + fmt % boost::io::group(std::setprecision(digits), val) % units[idx]; + return fmt.str(); +} diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index a5c2ec91..5210dc85 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -34,6 +34,20 @@ namespace PlatformUtils { std::string backupPath(); bool createBackupPath(); + /** + * Return a human readable text describing the operating system + * the application is currently running on. This is mainly intended + * to provide information for bug reports (e.g. to be included in + * the LibraryInfoDialog). + * + * If there is some error to retrieve the details, at least the + * OS type is reported based on what platform the application was + * built for. + * + * @return system information. + */ + std::string sysinfo(); + /** * Platform abstraction to set environment variables. Windows/MinGW * does not support setenv(), but needs _putenv(). @@ -65,4 +79,10 @@ namespace PlatformUtils { * Currently limited to MS Windows GUI application console only. */ void ensureStdIO(void); + + /** + * Convert the number of bytes to a human readable string with + * a given number of digits. + */ + std::string toMemorySizeString(unsigned long bytes, int digits); } From ba8446e8bfbf770926a13b2d312187077adcb368 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 22:06:06 +0100 Subject: [PATCH 3/5] Remove qtaccessiblewidgets as QTPLUGIN. MXE now ships Qt-5.4.0-rc which has accessibility built-in. All other platforms did not have it enabled so far. --- openscad.pro | 3 --- 1 file changed, 3 deletions(-) diff --git a/openscad.pro b/openscad.pro index cf374a44..d745c708 100644 --- a/openscad.pro +++ b/openscad.pro @@ -116,7 +116,6 @@ macx { win* { RC_FILE = openscad_win32.rc - QTPLUGIN += qtaccessiblewidgets } CONFIG += qt @@ -130,8 +129,6 @@ unix:!macx { QMAKE_LIBS_OPENGL *= -lX11 } -#QTPLUGIN += qtaccessiblewidgets - netbsd* { QMAKE_LFLAGS += -L/usr/X11R7/lib QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib From 845bd5706efa877e2cf5c0cb912ee3bfe934d7b3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 22:46:09 +0100 Subject: [PATCH 4/5] Guard against reading huge files. --- src/PlatformUtils-posix.cc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index dbeaa411..c3767fa7 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -69,6 +69,19 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +static std::string readText(const std::string &path) +{ + std::ifstream s(path.c_str()); + s.seekg(0, std::ios::end); + if (s.fail() || s.tellg() > 4096) { + return ""; + } + s.seekg(0, std::ios::beg); + + std::string text((std::istreambuf_iterator(s)), std::istreambuf_iterator()); + return text; +} + /** * Check /etc/os-release as defined by systemd. * @see http://0pointer.de/blog/projects/os-release.html @@ -77,8 +90,7 @@ unsigned long PlatformUtils::stackLimit() */ static std::string checkOsRelease() { - std::ifstream os_release_stream("/etc/os-release"); - std::string os_release((std::istreambuf_iterator(os_release_stream)), std::istreambuf_iterator()); + std::string os_release(readText("/etc/os-release")); boost::smatch results; boost::regex pretty_name("^PRETTY_NAME=\"([^\"]+)\""); @@ -91,8 +103,7 @@ static std::string checkOsRelease() static std::string checkEtcIssue() { - std::ifstream issue_stream("/etc/issue"); - std::string issue((std::istreambuf_iterator(issue_stream)), std::istreambuf_iterator()); + std::string issue(readText("/etc/issue")); boost::regex nl("\n.*$"); issue = boost::regex_replace(issue, nl, ""); From 39612397fa12c590594703c6d9c062458748c6d6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 10 Dec 2014 22:44:39 -0500 Subject: [PATCH 5/5] #1057 Sysinfo for Mac OS X --- src/PlatformUtils-mac.mm | 65 +++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index 20e72321..45157921 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -1,5 +1,8 @@ #include "PlatformUtils.h" #import +#include +#include +#include std::string PlatformUtils::pathSeparatorChar() { @@ -37,44 +40,30 @@ unsigned long PlatformUtils::stackLimit() std::string PlatformUtils::sysinfo() { - std::string result; - -#if 0 - struct utsname osinfo; - if (uname(&osinfo) == 0) { - result += osinfo.sysname; - result += " "; - result += osinfo.release; - result += " "; - result += osinfo.version; - result += " "; - result += osinfo.machine; - } else { -#endif - result += "Unknown MacOS"; -#if 0 - } - - long numcpu = sysconf(_SC_NPROCESSORS_ONLN); - if (numcpu > 0) { - result += " "; - result += boost::lexical_cast(numcpu); - result += " CPU"; - if (numcpu > 1) { - result += "s"; - } - } - - long pages = sysconf(_SC_PHYS_PAGES); - long pagesize = sysconf(_SC_PAGE_SIZE); - if ((pages > 0) && (pagesize > 0)) { - result += " "; - result += PlatformUtils::toMemorySizeString(pages * pagesize, 2); - result += " RAM"; - } -#endif - - return result; + std::string result; + + result += "Mac OS X "; + result += [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String]; + + int mib[2]; + int64_t physical_memory; + int32_t numcpu; + size_t length64 = sizeof(int64_t); + size_t length32 = sizeof(int32_t);; + + sysctlbyname("hw.memsize", &physical_memory, &length64, NULL, 0); + sysctlbyname("hw.physicalcpu", &numcpu, &length32, NULL, 0); + + result += " "; + result += boost::lexical_cast(numcpu); + result += " CPU"; + if (numcpu > 1) result += "s"; + + result += " "; + result += PlatformUtils::toMemorySizeString(physical_memory, 2); + result += " RAM"; + + return result; } void PlatformUtils::ensureStdIO(void) {}