When using clang 3.5.0 with -flto and connecting to a shared library, it seems that the operator delete calls in the shared library do not correspond to the same character resolution order as the operator new calls from the main objects, Example:
shared.cpp
void deleteIt(int* ptr) { delete ptr; }
main.cpp
#include <cstdlib> #include <new> void* operator new(size_t size) { void* result = std::malloc(size); if (result == nullptr) { throw std::bad_alloc(); } return result; } void operator delete(void* ptr) noexcept { std::free(ptr); } void deleteIt(int* ptr); int main() { deleteIt(new int); return 0; }
This is what happens when I create it and run it through valgrind:
$ clang++ -std=c++11 -g -O3 -flto -fuse-ld=gold -fPIC -shared shared.cpp -o libshared.so $ clang++ -std=c++11 -g -O3 -flto -fuse-ld=gold main.cpp -L. -lshared -o main $ LD_LIBRARY_PATH=. valgrind --quiet ./main ==20557== Mismatched free() / delete / delete [] ==20557== at 0x4C2B6D0: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==20557== by 0x4009F7: main (main.cpp:19) ==20557== Address 0x5a03040 is 0 bytes inside a block of size 4 alloc'd ==20557== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==20557== by 0x4009EA: operator new (main.cpp:5) ==20557== by 0x4009EA: main (main.cpp:19) ==20557==
You can see that it finds valgrind operator delete , but uses operator new from main.cpp . In contrast, the same build with gcc (just replace clang++ with g++ ) is fine. Any ideas why, or how to get around this?
EDIT: Import and export symbol for @Deduplicator.
$ objdump -T main | c++filt | grep operator 0000000000400990 g DF .text 0000000000000033 Base operator new(unsigned long) 0000000000000000 DF *UND* 0000000000000000 Base operator delete(void*) $ objdump -T libshared.so | c++filt | grep operator 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 operator delete(void*)
c ++ clang valgrind lto
Tavian barnes
source share