-flto와 함께 3.5.0을 사용하고 공유 라이브러리와 링크 할 때 공유 라이브러리에서 operator delete
을 호출하면 주 개체에서 operator new
에 대한 호출과 동일한 기호 확인 순서를 따르십시오.대체 된 연산자를 사용한 Clang 링크 시간 최적화가 valgrind에서 free()/delete가 일치하지 않음
$ 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==
: 예 :
shared.cpp :
void deleteIt(int* ptr) {
delete ptr;
}
MAIN.CPP : 나는 그것을 구축하고 Valgrind의를 통해 실행할 때
#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;
}
여기에 발생하는 상황
valgrind의 operator delete
을 찾고 있지만 operator new
은 main.cpp
입니다. 반대로 gcc (정확하게 clang++
을 g++
으로 대체)와 동일한 빌드가 올바르게 작동합니다. 왜 어떤 아이디어, 또는 어떻게 해결할 수 있습니까?
EDIT : @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*)
실제로 코드를 밟았습니까 (공유 라이브러리가 자신의 힙을 가지기를 기대하므로 완전히 놀랍지는 않습니다) –
main에 대한 operator-delete-line은 문제를 나타냅니다. 어떤 이유로, main은 delete를 export하지 않습니다 ... 사실 삭제는 제거되었습니다. – Deduplicator
잘 잡습니다. 흥미롭게도,'operator delete '의 C++ 14 오버로드를 추가하고'-std = C++ 14'를 사용하면 그 중 하나가 내보내지고 모든 것이 작동합니다.그러나'operator delete (void *)'는 여전히 export되지 않습니다. –