Generated crashlogs are missing all trace information when DC++ is compiled with any post-2020 built MinGW-w64 toolchain

Bug #2039677 reported by eMTee
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
DC++
Fix Released
Undecided
Unassigned

Bug Description

The last known mingw-w64 version where it is working is <https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/>
The first known mingw-w64 version where it is NOT working is <https://github.com/niXman/mingw-builds-binaries/releases/tag/8.5.0-rt_v10-rev0>
Also tried some more mingw-w64 compilers based on gcc 9.x and 11.x with the same negative result.

The documentation of <https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc//Debugging-Options.html> <https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc//Debugging-Options.html> is identical so no changes of defaults or no new options introduced/documented between these two versions.

I tried with different options such as -glevel -gdwarf32/64 or set to produce DWARF4 info with -gdwarf-4 (see the attached diff of the doc versions of the above gcc manual page between gcc 8.1 and 11.2) without success.

The size of the .pdb file generated using the single -g option keeps growing with every new gcc version from 6.x to 11.2 (gcc 11.2 produces ~6 times larger .pdb file than the size produced by 6.x if -g specified only).

We use a 10 year old libdwarf version, patched in a couple of places for our CrashLogger. Trying a libdwarf update may be useful if it is a file format problem. But maybe it is not a format change in the .pdb file at all but in the way how the call stack needs to be processed in Crashlogger, etc..

Revision history for this message
eMTee (realprogger) wrote :
eMTee (realprogger)
description: updated
Revision history for this message
eMTee (realprogger) wrote :

It doesn't work either in case of a long, deep callstacks or in a simple crash in main.cpp.

Test case:

Added

*((unsigned int*)0) = 0xDEAD;

to line 134 of main.cpp.
See the crashlogs attached that is generated with gcc 8.1 (expected result) and 8.5 (actual result).

Revision history for this message
eMTee (realprogger) wrote :
Revision history for this message
eMTee (realprogger) wrote :

More findings:
- It's not due to any change in binutils' strip.
- Using a .pdb file generated by an old, working compiler with a newer DC++ build results the same error.
- The problem is not gcc version related, either as the error happens when compiled with wide variety of toolchains from WinLibs, built on gcc 7.x...9.x. The only similarity in mingw-w64 commpiler tools tried and failed is that they all having mingw-w64 crt version 7 or later.
 The last known working mingw-w64 toolchain (link in the OP) is on crt v6. I couldn't find any other toolchains with crt v6 that would produce any chashlog file at all so for now it is just an observation and not something conclusive.

Revision history for this message
eMTee (realprogger) wrote (last edit ):

The error in libdwarf happens at https://sourceforge.net/p/dcplusplus/code/ci/43196df8283bc3dfadc8eebd665c55804cef8954/tree/win32/CrashLogger.cpp#l292 being unable to find the address coming from the stack walk.

One problem is that the addr param in getDebugInfo function is a DWORD so < 4GiB 64-bit addresses are getting truncated there. But this doesn't tell why it fails on 32-bit as well.

https://sourceware.org/bugzilla/show_bug.cgi?id=19011 shows what's changed in image base and ASLR defaults in the mingw-w64 build system to comply with today's security standards. These changes applied at around 2020.08 and any build tried and the issue manifests with are after this date.

Reverting the changes this bug entry describes using

'-Wl,--no-undefined,--nxcompat,--disable-reloc-section,--disable-dynamicbase,--disable-high-entropy-va,--disable-auto-image-base,--image-base=0x400000', '-time'

and specifying -gdwarf-4 (since our old libdwarf complaining/doesn't know about DWARF5) the crash log is generated fine again.

Revision history for this message
eMTee (realprogger) wrote :

The issue is that the code is not capable of handling randomized address spaces.

Even though --dynamicbase has been enabled for 10+ years no real ASLR happened at all in the former DC++ executables due to bad linker defaults described in the attached sourceware bug link so crash logging worked up until we moved to a post-2020 MinGW-w64 toolchain.

A fix that is taking account of the offset of the randomized address space has been applied.

summary: Generated crashlogs are missing all trace information when DC++ is
- compiled with a gcc 8.5 and later based MinGW-w64
+ compiled with any post-2020 built MinGW-w64 toolchains
Changed in dcplusplus:
status: New → Fix Committed
summary: Generated crashlogs are missing all trace information when DC++ is
- compiled with any post-2020 built MinGW-w64 toolchains
+ compiled with any post-2020 built MinGW-w64 toolchain
Revision history for this message
eMTee (realprogger) wrote :

Fixed in DC++ 0.881

Changed in dcplusplus:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.