libumem.so aborts due to invalid free of basic_string __nullref member
807575Nov 23 2006 — edited Nov 26 2006Hi,
I'm fairly new to Solaris development and I've been trying to debug a problem for the last few days and I'm at my wits end. I've been trying, unsucessfully, to use libumem to track down a memory corruption issue, however I've had trouble just getting started. I don't know if it's a problem with the compiler or the version of the STL included with Sun Studio 11.
When I run my application using LD_PRELOAD to interpose the libumem library, the application immediately aborts with the following stack trace:
libc.so.1`_lwp_kill+8(6, 0, 20f90, ff36b7cc, ff38a000, ff38abc4)
libumem.so.1`umem_do_abort+0x1c(8, ffbfec78, 6, 20ecc, ff37680c, 0)
libumem.so.1`umem_err_recoverable+0x7c(ff377818, a, 20dc4, ff3cca0c, ff38d0d0, ff377823)
libumem.so.1`process_free+0x114(ff351660, 1, 0, 3e3a1000, 1ee5c, ff3b3904)
libCrun.so.1`void operator delete+4(ff351660, fffb, 4, ffffffff, 3fee8, fc00)
libCstd_isa.so.1`char*std::basic_string<char,std::char_traits<char>,std::allocator<char> >::replace+
0x3c4(55fc8, 3ff10, 0, ff351688, 0, ff351688)
libCstd_isa.so.1`std::basic_string<char,std::char_traits<char>,std::allocator<char> >&std::basic_str
ing<char,std::char_traits<char>,std::allocator<char> >::operator=+0xe4(55fc8, ff341434, 0, 1cf6c,
ff16a780, ff351688)
libtestlib.so`void print+0x254(ffbff6c8, 1530c, 55fc8, ff156dfc, 55fc8, 55fd8)
main+0x1c(1, ffbff734, ffbff73c, 25400, feee0000, feee0040)
It looks like what is happening is that there are multiple version of the __nullref symbol present, when I believe there should only be one. I believe these multiple symbols cause comparison failures inside the STL, which ultimately lead to the application crashing.
I've managed to create a testcase that demonstrates the problem (code attached inline).
I'm using the following compiler:
CC: Sun C++ 5.8 2005/10/13
=====START testlib.cpp ==========================================
#include <string>
#include <iostream>
using namespace std;
void print(const string &s)
{
string l;
string *p = new string();
string *q = new string();
*p = "foo";
*q = "bar";
cout << p << q << endl;
}
=====END testlib.cpp ============================================
=====START testlib.map ==========================================
VERSION {
global:
__1cFprint6FrknDstdMbasic_string4Ccn0ALchar_traits4Cc__n0AJallocator4Cc_____v_ ;
local:
* ;
};
=====END testlib.map ============================================
I compiled testlib.cpp with the following command line:
CC -G -Qoption ld "-M,testlib.map" -o libtestlib.so testlib.cpp
I then compiled the following test program that uses the libtestlib.so library:
=====START test.cpp =============================================
#include <iostream>
#include <string>
using namespace std;
extern void print(const string &s);
int main(void)
{
print("foo");
return 0;
}
=====END test.cpp ===============================================
CC -o test test.cpp -KPIC -Bdynamic -L"." -l"testlib" "-xarch=v8plus"
This works successfully when I use the 5.3 version of the compiler (Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-02 2001/09/18). One difference I've noticed between these two compilers is that the two version of the STL define the __nullref member differently. The newer compiler adds a __SUNW_GLOBAL modifier to the declaration, which seems to be completely undocumented (Google yields no useful information).
Any help is greatly appreciated.
Scott