Improve stack-trace for ecode symbols.

Fix demangling in stack-trace for mingw builds.
Fix all stat calls in windows mingw builds that fail to detect files / dirs when the path ends with a path separator (this is an old bug, as old as I can remember, I thought it was fixed on mingw side but it seems only works for the cross compiled build, windows mingw build was failing catastrophically and never saw it).
There was also a very old minor bug in Sys::getProcessPath.
This commit is contained in:
Martín Lucas Golini
2026-03-22 18:41:47 -03:00
parent 05d6d3e2a3
commit dd039fc233
6 changed files with 56 additions and 32 deletions

View File

@@ -1738,6 +1738,7 @@ solution "eepp"
linkoptions { "../../bin/assets/icon/ecode.res" }
end
buildoptions{ "-Wa,-mbig-obj" }
linkoptions { "-Wl,--export-all-symbols" }
end
build_link_configuration( "ecode", false )
configuration { "release", "windows" }

View File

@@ -1593,6 +1593,7 @@ workspace "eepp"
build_link_configuration( "ecode", false )
filter { "system:windows", "action:not vs*" }
buildoptions{ "-Wa,-mbig-obj" }
linkoptions { "-Wl,--export-all-symbols" }
filter { "system:windows", "action:vs*" }
files { "bin/assets/icon/ecode.rc", "bin/assets/icon/ecode.ico" }
vpaths { ['Resources/*'] = { "ecode.rc", "ecode.ico" } }

View File

@@ -115,8 +115,11 @@ void FileInfo::getInfo() {
struct stat st;
int res = stat( mFilepath.c_str(), &st );
#else
struct _stat st;
int res = _wstat( String::fromUtf8( mFilepath ).toWideString().c_str(), &st );
std::string_view fp( mFilepath );
if ( fp.size() > 3 && ( fp.back() == '/' || fp.back() == '\\' ) )
fp.remove_suffix( 1 );
struct __stat64 st;
int res = _wstat64( String( fp ).toWideString().c_str(), &st );
#endif
if ( 0 == res ) {
@@ -261,8 +264,11 @@ bool FileInfo::exists() const {
struct stat st;
int res = stat( mFilepath.c_str(), &st );
#else
struct _stat st;
int res = _wstat( String::fromUtf8( mFilepath ).toWideString().c_str(), &st );
std::string_view fp( mFilepath );
if ( fp.size() > 3 && ( fp.back() == '/' || fp.back() == '\\' ) )
fp.remove_suffix( 1 );
struct __stat64 st;
int res = _wstat64( String( fp ).toWideString().c_str(), &st );
#endif
if ( isDirectory() )

View File

@@ -211,8 +211,11 @@ bool FileSystem::fileHide( const std::string& filepath ) {
Uint32 FileSystem::fileGetModificationDate( const std::string& filepath ) {
#if EE_PLATFORM == EE_PLATFORM_WIN
struct _stat st;
int res = _wstat( String( filepath ).toWideString().c_str(), &st );
std::string_view fp( filepath );
if ( fp.size() > 3 && ( fp.back() == '/' || fp.back() == '\\' ) )
fp.remove_suffix( 1 );
struct __stat64 st;
int res = _wstat64( String( fp ).toWideString().c_str(), &st );
#else
struct stat st;
int res = stat( filepath.c_str(), &st );
@@ -540,8 +543,11 @@ std::vector<std::string> FileSystem::filesGetInPath( const std::string& path,
Uint64 FileSystem::fileSize( const std::string& Filepath ) {
#if EE_PLATFORM == EE_PLATFORM_WIN
struct _stat st;
int res = _wstat( String( Filepath ).toWideString().c_str(), &st );
std::string_view fp( Filepath );
if ( fp.size() > 3 && ( fp.back() == '/' || fp.back() == '\\' ) )
fp.remove_suffix( 1 );
struct __stat64 st;
int res = _wstat64( String( fp ).toWideString().c_str(), &st );
#else
struct stat st;
int res = stat( Filepath.c_str(), &st );
@@ -555,8 +561,11 @@ Uint64 FileSystem::fileSize( const std::string& Filepath ) {
bool FileSystem::fileExists( const std::string& Filepath ) {
#if EE_PLATFORM == EE_PLATFORM_WIN
struct _stat st;
return ( _wstat( String( Filepath ).toWideString().c_str(), &st ) == 0 );
std::string_view fp( Filepath );
if ( fp.size() > 3 && ( fp.back() == '/' || fp.back() == '\\' ) )
fp.remove_suffix( 1 );
struct __stat64 st;
return ( _wstat64( String( fp ).toWideString().c_str(), &st ) == 0 );
#else
struct stat st;
return ( stat( Filepath.c_str(), &st ) == 0 );

View File

@@ -643,7 +643,7 @@ static std::string sGetProcessPath() {
_splitpath_s( dllstrName.c_str(), szDrive, _MAX_DRIVE, szDir, _MAX_DIR, szFilename, _MAX_DIR,
szExt, _MAX_DIR );
#else
_splitpath( szDllName, szDrive, szDir, szFilename, szExt );
_splitpath( dllstrName.c_str(), szDrive, szDir, szFilename, szExt );
#endif
return std::string( szDrive ) + std::string( szDir );

View File

@@ -332,6 +332,10 @@
#if defined(BACKWARD_SYSTEM_WINDOWS)
#ifdef __GNUC__
#include <cxxabi.h>
#endif
#include <condition_variable>
#include <mutex>
#include <thread>
@@ -612,14 +616,20 @@ template <typename TAG> struct demangler_impl {
static std::string demangle(const char *funcname) { return funcname; }
};
#if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_DARWIN)
#if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_DARWIN) || (defined(BACKWARD_SYSTEM_WINDOWS) && defined(__GNUC__))
template <> struct demangler_impl<system_tag::current_tag> {
demangler_impl() : _demangle_buffer_length(0) {}
std::string demangle(const char *funcname) {
using namespace details;
char *result = abi::__cxa_demangle(funcname, _demangle_buffer.get(),
const char* target = funcname;
std::string mangled;
if (target && target[0] == 'Z') {
mangled = "_" + std::string(target);
target = mangled.c_str();
}
char *result = abi::__cxa_demangle(target, _demangle_buffer.get(),
&_demangle_buffer_length, nullptr);
if (result) {
_demangle_buffer.update(result);
@@ -3674,41 +3684,38 @@ public:
ResolvedTrace resolve(ResolvedTrace t) override {
HANDLE process = GetCurrentProcess();
char name[256];
memset(&sym, 0, sizeof(sym));
sym.sym.SizeOfStruct = sizeof(SYMBOL_INFO);
sym.sym.MaxNameLen = max_sym_len;
if (!SymFromAddr(process, (ULONG64)t.addr, &displacement, &sym.sym)) {
// TODO: error handling everywhere
char* lpMsgBuf;
DWORD dw = GetLastError();
if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(char*)&lpMsgBuf, 0, NULL)) {
std::fprintf(stderr, "%s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
}
// abort();
t.object_function = "??";
return t;
}
std::string name = demangle(sym.sym.Name);
if (name == sym.sym.Name) {
char undecorated[256];
if (UnDecorateSymbolName(sym.sym.Name, undecorated, 256, UNDNAME_COMPLETE)) {
name = undecorated;
}
}
UnDecorateSymbolName(sym.sym.Name, (PSTR)name, 256, UNDNAME_COMPLETE);
DWORD offset = 0;
IMAGEHLP_LINE line;
if (SymGetLineFromAddr(process, (ULONG64)t.addr, &offset, &line)) {
t.object_filename = line.FileName;
t.source.filename = line.FileName;
t.source.line = line.LineNumber;
t.source.col = offset;
}
IMAGEHLP_MODULE64 module;
memset(&module, 0, sizeof(module));
module.SizeOfStruct = sizeof(module);
if (SymGetModuleInfo64(process, (ULONG64)t.addr, &module)) {
t.object_filename = module.ModuleName;
}
t.source.function = name;
t.object_filename = "";
t.object_function = name;
return t;