Main application dynamically loads shared library and uses function from
library to fill out string. If basic_string<char> or basic_string<wchar_t> are
used then no problem observed. In case of basic_string<unsigned short>
application aborts (MALLOC_CHECK_=2) with message 

*** glibc detected *** free(): invalid pointer: 0x00000000005015c0 ***
Aborted

gdb shows stack trace:

#0  0x0000003a79d2e2ed in raise () from /lib64/tls/libc.so.6
#1  0x0000003a79d2fa3e in abort () from /lib64/tls/libc.so.6
#2  0x0000003a79d62db1 in __libc_message () from /lib64/tls/libc.so.6
#3  0x0000003a79d6888e in _int_free () from /lib64/tls/libc.so.6
#4  0x0000003a79d68bd6 in free () from /lib64/tls/libc.so.6
#5  0x0000003a7ceae19e in operator delete () from /usr/lib64/libstdc++.so.6
#6  0x0000002a95579665 in __gnu_cxx::new_allocator<char>::deallocate () from
./libloader.so
#7  0x0000002a9557954b in std::basic_string<unsigned short,
std::char_traits<unsigned short>, std::allocator<unsigned short>
>::_Rep::_M_destroy () from ./libloader.so
#8  0x0000002a9557908c in std::basic_string<unsigned short,
std::char_traits<unsigned short>, std::allocator<unsigned short>
>::_Rep::_M_dispose () from ./libloader.so
#9  0x0000002a95578e3e in std::basic_string<unsigned short,
std::char_traits<unsigned short>, std::allocator<unsigned short> >::reserve ()
   from ./libloader.so
#10 0x0000002a95578cef in std::basic_string<unsigned short,
std::char_traits<unsigned short>, std::allocator<unsigned short> >::append ()
   from ./libloader.so
#11 0x0000002a95578c63 in std::basic_string<unsigned short,
std::char_traits<unsigned short>, std::allocator<unsigned short> >::append ()
   from ./libloader.so
#12 0x0000002a95578c38 in read_string () from ./libloader.so
#13 0x0000000000400860 in main ()

The "workaround" is to add reserve(1) before passing string to function. In
this case there is no abort. 

Why the behavior is different? Where is the problem?

Source code:

main.cpp
//---------------------------------------------------------
#include <dlfcn.h>
#include <string>
#include "loader.h"

typedef void *pfLoader(std::ustring&);

int main(int argc, char* argv[])
{
        void * libHandle = dlopen("libloader.so", RTLD_NOW|RTLD_GLOBAL);
        pfLoader* pF = (pfLoader*)dlsym(libHandle, "read_string");

        std::ustring s;
//      s.reserve(1);   // uncomment this line to prevent abort
        pF(s);
        return 0;
}
//---------------------------------------------------------

loader.h
//---------------------------------------------------------
#ifndef _LOADER_INCLUDED_
#define _LOADER_INCLUDED_

typedef unsigned short USHORT;

namespace std
{
        typedef std::basic_string<USHORT, std::char_traits<USHORT>,
std::allocator<USHORT> > ustring;
}

extern "C" void read_string(std::ustring& sValue);

#endif // _RUNNER_INCLUDED_
//---------------------------------------------------------

loader.cpp
//---------------------------------------------------------
#include <string>
#include "loader.h"

const USHORT _sV [] = {'T','e','s','t','\0'};

void read_string(std::ustring& sValue)
{
        sValue.append(_sV);
}
//---------------------------------------------------------

Build commands:
main:  g++ -o main -I. -ldl main.cpp
lib:   g++ -Wl,-E -fPIC -I. -shared -o libloader.so loader.cpp

Version infos:
OS: 
Red Hat Enterprise Linux AS release 4 (Nahant Update 3)
Kernel \r on an \m

g++:
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.5/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)

glibc: 3.4


-- 
           Summary: basic_string and unsigned short leads to memory fault
           Product: gcc
           Version: 3.4.5
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: gregoryk at edifecs dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31368

Reply via email to