Created attachment 29080 [details] LD_DEBUG=all output of failure executable Hello All, I faced crash issue while opening one library dynamically using RTLD_DEEPBIND flag. Scenario: I have one library.so which is having un-initiliazed variable of data type 'std::string' and main file is also having another variable of same data type i.e. 'std::string'. Both files are written in C++ code. If I execute this code then it result in crash resulting in free() call of libc. crash log: *** glibc detected *** ./a.out: free(): invalid pointer: 0x00007f1229894140 *** ======= Backtrace: ========= /lib/libc.so.6(+0x77806)[0x7f1228ded806] /lib/libc.so.6(cfree+0x73)[0x7f1228df40d3] /usr/lib/libstdc++.so.6(_ZNSs9_M_mutateEmmm+0x1ae)[0x7f122963cb0e] /usr/lib/libstdc++.so.6(_ZNSs14_M_replace_auxEmmmc+0x4a)[0x7f122963cdaa] ./library.so(library_function+0x36)[0x7f1228b74a66] ./a.out[0x400a89] /lib/libc.so.6(__libc_start_main+0xfd)[0x7f1228d94c4d] ./a.out[0x400959] If I initiliazed std::string variable in library code like " std::string empty_lib=""; then no crash is obeserved. I have checked output of LD_DEBUG=all for both case executable and checked that there is binding issue in crash scenario wrt to std::string. Please find exact test code: =============================================================== cat main.cpp #include <dlfcn.h> #include <iostream> int main() { char const * const library_name = "./library.so"; void * handle = dlopen(library_name, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); std::string empty_main=""; typedef void (*library_function_type)(); void * function = dlsym(handle, "library_function"); reinterpret_cast<library_function_type>(function)(); dlclose(handle); return 0; } cat library.cpp #include <sstream> #include <iostream> extern "C" { void library_function() { std::string empty_lib; char c = '/'; empty_lib = c; } } =============================================================== ---------------------------------------------------------------- Compilation commands: g++ -g -O2 -rdynamic -c -Wall -Wextra -fPIC -o library.o library.cpp ; g++ -shared -Wl,-export-dynamic -o library.so library.o g++ -g -O2 -Wall -Wextra main.cpp -ldl ---------------------------------------------------------------- Can someone please help in this regard and let me know what went wrong and how to solve this issue. Please note that if I remove RTLD_DEEPBIND flag while opening this library then I didn't get any crash. If I write same code in .c file instead of .cpp then no issues observed. Thanks in advance. Attached LD_DEBUG=all output for both working and non-working case: -- Regards, Yogesh Gaur.
Created attachment 29081 [details] LD_DEBUG=all output of working executable
GCC 4.4 is no longer maintained or supported. Unles you can reproduce the problem with a current release of GCC (which I can't) then nothing is going to happen. N.B. compiling main.cpp with -fPIC seems to fix the problem anyway.
(In reply to comment #2) > GCC 4.4 is no longer maintained or supported. > > Unles you can reproduce the problem with a current release of GCC (which I > can't) then nothing is going to happen. > Hello Jonathan, I tried on GCC 4.6.4 also and still getting this issue on there, I didn't have any more latest copy of GCC with me. > N.B. compiling main.cpp with -fPIC seems to fix the problem anyway. Can you please explain that why it should work with -fPIE, I am able to work it using -fPIE while making my executable. Please note that we should never use -fPIC with executable it will break prelink, if Thread Local Storage is used.
Hello, Actually issue is combination of copy_relocation plus RTLD_DEEPBIND flag. If I didn't give -fPIE flag while compiling my executable and pass RTLD_DEEPBIND flag while opening library using dlopen(), then result is un-expected. I checked similar issue exist on gcc also: ------------------------------Source Code ----------------------------- $ cat main.c #include <dlfcn.h> extern int alpha; int main() { char const * const name = "./lib1.so"; void * handle = dlopen(name, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); typedef void (*library_function_type)(); library_function_type func1 = dlsym(handle, "func1"); alpha = 10; (*func1)(); func2(); dlclose(handle); return 0; } $ cat lib1.c #include <stdio.h> extern int alpha; void func1(){ printf("lib1: Addr=%p, value=%d\n", &alpha, alpha); } $ cat lib2.c #include <stdio.h> int alpha; void func2(){ printf("lib2: Addr=%p, value=%d\n", &alpha, alpha); } -------------------------------- END ---------------------------------- Compilation command and output: gcc -shared -fPIC lib2.c -o lib2.so gcc -shared -fPIC lib1.c lib2.so -o lib1.so gcc -ldl main.c lib2.so -o a.out LD_LIBRARY_PATH=$PWD ./a.out lib1: Addr=0x7f5a39663028, value=0 lib2: Addr=0x601038, value=10 ========================================= Thus for same symbol, alpha, we get two addresses values. If I remove RTLD_DEEPBIND while opening library, I didn't get this issue: lib1: Addr=0x601038, value=10 lib2: Addr=0x601038, value=10 Reason for this also I know that in case of RTLD_DEEPBIND scope of search for lib1.so is its internal library first and then only global library's being searched. I want to know that apart from usage of -fPIE flag at compilation time did any-other solution exist for this issue? As using -fPIE has it's own side-affect. -- Regards, Yogesh Gaur.