jrfonseca / drmingw

Postmortem debugging tools for MinGW.
GNU Lesser General Public License v2.1
279 stars 56 forks source link

Wrong a crash report after compiler optimizations. #25

Closed dismine closed 9 years ago

dismine commented 9 years ago

Hi.

I use exchndl.dll for catching crashes in my project. When i tried the last version DrMingw 0.7.6, i got strange behavior. Seems like, now compiler optimizations change crash reports. This never happens in older versions.

I can repeat the issue with test program:

#include <Windows.h>
#include <string>
class Test
{
public:
    Test();
    int length() const;
private:
    int size;
};
Test::Test() 
    :size(0)
{}
inline int Test::length() const
{ 
    return size; 
}
int main()
{
    LoadLibraryA("exchndl.dll");
    std::string *a;
    a = NULL;
    *a += "pi is " + std::to_string(3.1415926);
    return(0);
} 

I always strip with

objcopy --only-keep-debug test.exe test.dbg
objcopy --strip-debug test.exe
objcopy --add-gnu-debuglink="test.dbg" test.exe

Build with

g++ -O0 -g -std=c++0x main.cpp -o test.exe
Report is:
-------------------

Error occured on Sunday, September 13, 2015 at 10:04:19.

test.exe caused an Access Violation at location 6FC8AAA6 in module libstdc++-6.dll Reading from location 00000000.

Registers:
eax=00000000 ebx=00000000 ecx=003e4ea4 edx=0022fed4 esi=0022fed4 edi=00000011
eip=6fc8aaa6 esp=0022fe90 ebp=0000000e iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010202

AddrPC   Params
6FC8AAA6 0022FED8 00409078 00000000  libstdc++-6.dll!ZNSs6appendERKSs
0040788C 0022FED4 00409078 0022FED8  test.exe!operator+<char, std::char_traits<char>, std::allocator<char> >  [C:/Qt/Qt5.4.1/Tools/mingw491_32/i686-w64-mingw32/include/c++/bits/basic_string.h @ 2475]
  2473:     operator+(const _CharT* __lhs,
  2474:       basic_string<_CharT, _Traits, _Alloc>&& __rhs)
> 2475:     { return std::move(__rhs.insert(0, __lhs)); }
  2476: 
  2477:   template<typename _CharT, typename _Traits, typename _Alloc>
004016BA 003E3998 00000011 00000001  test.exe!main  [C:\test/main.cpp @ 27]
    25: std::string *a;
    26: a = NULL;
>   27: *a += "pi is " + std::to_string(3.1415926);
    28: return(0);
    29: }
004013DE 00380039 00340034 7FFDE000  test.exe!__tmainCRTStartup
7C817077 004014E0 00000000 78746341  kernel32.dll!BaseProcessStart

test.exe
ntdll.dll       5.1.2600.5755
kernel32.dll    5.1.2600.5781
libgcc_s_dw2-1.dll
msvcrt.dll      7.0.2600.5512
libwinpthread-1.dll 1.0.0.0
libstdc++-6.dll
USER32.dll      5.1.2600.5512
GDI32.dll       5.1.2600.5698
prio.dll        1.9.8.0
exchndl.dll     0.7.6.0
mgwhelp.dll     0.7.6.0
dbghelp.dll     6.3.9600.17029
ADVAPI32.dll    5.1.2600.5755
RPCRT4.dll      5.1.2600.5795
Secur32.dll     5.1.2600.5834
PSAPI.DLL       5.1.2600.5512
SHELL32.DLL     6.0.2900.5686
SHLWAPI.dll     6.0.2900.5512
VERSION.dll     5.1.2600.5512
comctl32.dll    6.0.2900.5512
comctl32.dll    5.82.2900.5512

Windows 5.1.2600
DrMingw 0.7.6

But if i use optimization O1 or O2 get the same broken result:

g++ -O2 -g -std=c++0x main.cpp -o test.exe
-------------------

Error occured on Sunday, September 13, 2015 at 10:00:44.

test.exe caused an Access Violation at location 6FC8AAA6 in module libstdc++-6.dll Reading from location 00000000.

Registers:
eax=003e2574 ebx=00000000 ecx=003e4ea4 edx=00020002 esi=0022fecc edi=00000011
eip=6fc8aaa6 esp=0022fe70 ebp=0000000e iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010202

AddrPC   Params
6FC8AAA6 00409068 00000000 0022FECC  libstdc++-6.dll!ZNSs6appendERKSs
7C801DA8 0022FECC 00000000 0022FEC7  kernel32.dll!LoadLibraryA
004075F7 003E3998 00000011 00000001  test.exe!main  [C:/Qt/Qt5.4.1/Tools/mingw491_32/i686-w64-mingw32/include/c++/bits/basic_string.h @ 950]
   948:       basic_string&
   949:       operator+=(const basic_string& __str)
>  950:       { return this->append(__str); }
   951: 
   952:       /**
004013DE 00380039 00340034 7FFDE000  test.exe!__tmainCRTStartup
7C817077 004014E0 00000000 78746341  kernel32.dll!BaseProcessStart

test.exe
ntdll.dll       5.1.2600.5755
kernel32.dll    5.1.2600.5781
libgcc_s_dw2-1.dll
msvcrt.dll      7.0.2600.5512
libwinpthread-1.dll 1.0.0.0
libstdc++-6.dll
USER32.dll      5.1.2600.5512
GDI32.dll       5.1.2600.5698
prio.dll        1.9.8.0
exchndl.dll     0.7.6.0
mgwhelp.dll     0.7.6.0
dbghelp.dll     6.3.9600.17029
ADVAPI32.dll    5.1.2600.5755
RPCRT4.dll      5.1.2600.5795
Secur32.dll     5.1.2600.5834
PSAPI.DLL       5.1.2600.5512
SHELL32.DLL     6.0.2900.5686
SHLWAPI.dll     6.0.2900.5512
VERSION.dll     5.1.2600.5512
comctl32.dll    6.0.2900.5512
comctl32.dll    5.82.2900.5512
WS2_32.dll      5.1.2600.5512
WS2HELP.dll     5.1.2600.5512
WININET.dll     6.0.2900.5835
CRYPT32.dll     5.131.2600.5512
MSASN1.dll      5.1.2600.5512
OLEAUT32.dll    5.1.2600.5512
ole32.dll       5.1.2600.5512
wsock32.dll     5.1.2600.5512
RASAPI32.DLL    5.1.2600.5512
rasman.dll      5.1.2600.5512
NETAPI32.dll    5.1.2600.5694
TAPI32.dll      5.1.2600.5512
rtutils.dll     5.1.2600.5512
WINMM.dll       5.1.2600.5512
sensapi.dll     5.1.2600.5512
USERENV.dll     5.1.2600.5512
urlmon.dll      6.0.2900.5835
mswsock.dll     5.1.2600.5625
DNSAPI.dll      5.1.2600.5797
iphlpapi.dll    5.1.2600.5512
rasadhlp.dll    5.1.2600.5512
hnetcfg.dll     5.1.2600.5589
wshtcpip.dll    5.1.2600.5512

Windows 5.1.2600
DrMingw 0.7.6
dismine commented 9 years ago

I made a little research and seems like DrMingw always behaves like this. This is a bad news for me.

jrfonseca commented 9 years ago

Sorry for the delay replying.

Yes, this sounds similar to the issue you described to me in private email with the subject "Changes in crash report output", in Feb/Apr this year.

The compiler decided to inline the += operator, and the crash happens inside the inlined code.

It's unavoidable -- whenever one call gets inlined, the stack trace shrinks by one call too. Which call gets reported depends on many factors.

004075F7 003E3998 00000011 00000001  test.exe!main  [C:/Qt/Qt5.4.1/Tools/mingw491_32/i686-w64-mingw32/include/c++/bits/basic_string.h @ 950]

The right wayt to interpret this is that the crash is inside function "main", but the code was inlined from operator+=.

DWARF debugging info stores the information about which functions are inlined where, and this could be used to report both functions together. But I don't have the time to pursue such enhancement.