Reputation: 455
I have a sefault in a big program under Mingw but not under Linux. I managed to reduce it to the following code:
#include <iostream>
#include <string>
#include <map>
using namespace std;
const std::string& getConfiguration(const std::string& key, std::map<std::string, std::string> configuration)
{
map<string, string>::const_iterator it = configuration.find(key);
return it->second;
}
int main() {
map<string, string> testmap;
testmap["key"] = "value";
map<string, string>::const_iterator it;
it = testmap.find("key");
const string& value = it->second;
cout << value << endl;
cout << "ok!" << endl;
const string& valuebis = getConfiguration("key", testmap);
cout << valuebis << endl;
cout << "Mingw segfaults before here" << endl;
return 0;
}
I compile it with mxe, with the following options
/path/to/mxe/usr/bin/i686-w64-mingw32.static-g++ -ggdb3 -O0 -o test.exe test.cpp -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
(but I get the same result with i686-pc-mingw32.static) and I get the following error in gdb:
Starting program: Z:\test-conv.exe
[New Thread 17328.0x43b4]
value
ok!
Program received signal SIGSEGV, Segmentation fault.
std::operator<< <char, std::char_traits<char>, std::allocator<char> > (__os=warning: RTTI symbol not found for class 'std::ostream'
..., __str=<error reading variable: Cannot access memory at address 0xfeeefee2>)
at /home/eroux/softs/mxe-64/tmp-gcc-i686-w64-mingw32.static/gcc-4.9.1.build/i686-w64-mingw32.static/libstdc++-v3/include/bits/basic_string.h:2777
2777 /home/eroux/softs/mxe-64/tmp-gcc-i686-w64-mingw32.static/gcc-4.9.1.build/i686-w64-mingw32.static/libstdc++-v3/include/bits/basic_string.h: No such file or directory.
(gdb) bt
#0 std::operator<< <char, std::char_traits<char>, std::allocator<char> > (__os=warning: RTTI symbol not found for class 'std::ostream'
..., __str=<error reading variable: Cannot access memory at address 0xfeeefee2>)
at /home/eroux/softs/mxe-64/tmp-gcc-i686-w64-mingw32.static/gcc-4.9.1.build/i686-w64-mingw32.static/libstdc++-v3/include/bits/basic_string.h:2777
#1 0x0040181a in main () at ConventionTest.cpp:22
My guess is that somehow the iterator in getConfiguation gets freed by mingw but not by usual linux gcc...
But as it works fine under Linux and as gcc issues no warning at all (even with -Wextra
), I wonder if there is a bad practice somewhere (I'm no C++ expert) or if it's a bug in mingw optimizations...
Thank you,
Upvotes: 2
Views: 861
Reputation: 409166
It's because of undefined behavior. The reason is that in the getConfiguration
function you pass the map by value, and then you return a reference to an entry in this map, which will be destructed when the function returns.
Upvotes: 5
Reputation: 217235
getConfiguration
returns a reference to a local object (and so invoke UB), pass configuration
as const reference (or return a copy of the string).
Upvotes: 5