Trouble understanding crash when class is returned by value from C++
Andrej Mitrovic
andrej.mitrovich at gmail.com
Sun Sep 2 17:38:41 PDT 2012
I'm trying to add at least *some* type of pass-by-value support for
C++ classes when wrapping C++ libraries to D. I figured I could fake a
value class by using a D struct with a thunk field which matches the
size of the C++ object.
Returning a C++ object by value works in this plain C++ example (using
g++ on win32):
test.cpp: http://codepad.org/55pttk3I
$ g++ -m32 -g test.cpp -o main.exe -lstdc++
$ main.exe
If I take the same code but remove main and instead use a D driver app like so:
test.cpp: http://codepad.org/ZqieSXrb
main.d: http://codepad.org/6E5sbc7e
I compile it:
$ g++ -m32 -g -c ./test.cpp -o test.obj
$ gdc -m32 -g main.d test.obj -o main.exe -lstdc++
$ main.exe
and then I get a crash:
The instruction at "0x6fc8ea39" referenced memory at "0x006f6f62". The
memory could not be "read".
GDB tells me:
Program received signal SIGSEGV, Segmentation fault.
0x6fc8ea39 in libstdc++-6!_ZNSsC1ERKSs ()
from C:\MinGW\bin\libstdc++-6.dll
If I replace the std::string field with an ordinary 'char*' the crash
is gone, so my wild guess is the crash happens in one of std::string's
special member functions (ctor/dtor/etc..).
C++ sizeof() tells me FileName is 4 bytes long, so I've matched that
in the fake D struct. If I increase the 'thunk' field to 9 bytes the
crash disappears. I have a hunch stack corruption might be to blame.
I can notice some difference in the ASM listings:
C++ plain sample: http://pastebin.com/xw3BhwwR
D driver sample: http://pastebin.com/TLa8k5A3
The suspicious thing there is the missing LEA instruction in the D
listing. If I change the thunk field to 9 bytes the LEA instruction
appears again (and this is when the crash disappears).
My ASM-foo is really weak though, so I don't know what any of this
means. Anyone know what's going on?
More information about the D.gnu
mailing list