-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Hello,
It seems that there's a case of false odr-violation alarm with shared objects. Below is my code:
--- template.h
template<typename T>
class Base {
public:
Base() = default;
virtual ~Base() = default;
};
template<typename T>
class Derived : Base<T> {
public:
Derived() = default;
~Derived() {};
};
--- weak.cpp
#include <iostream>
#include <typeinfo>
#include "template.h"
void weak() {
std::cout << typeid(Derived<int>).name() << "\n";
std::cout << typeid(Derived<char>).name() << "\n";
}
--- strong.cpp
#include <iostream>
#include <typeinfo>
#include "template.h"
template<>
class Derived<int> : Base<int> {
public:
Derived() = default;
~Derived();
};
template<>
class Derived<char> : Base<char> {
public:
Derived() = default;
~Derived();
};
Derived<int>::~Derived() {}
Derived<char>::~Derived() {}
void strong() {
std::cout << typeid(Derived<int>).name() << "\n";
std::cout << typeid(Derived<char>).name() << "\n";
}
--- main.cpp
extern void weak();
extern void strong();
int main() {
weak();
strong();
}
--- Makefile
CLANG=~/llvms/upstream-git/install-debug/bin/clang++
all: run
%.o: %.cpp
$(CLANG) -fPIC -c -fsanitize=address -o $@ $^
lib%.so: %.o
$(CLANG) -fPIC -shared -o $@ $^
main-strong: main.o libstrong.so libweak.so
$(CLANG) -fPIC -fsanitize=address -o $@ main.o libstrong.so libweak.so -L. -lstrong -lweak
main-weak: main.o libstrong.so libweak.so
$(CLANG) -fPIC -fsanitize=address -o $@ main.o libweak.so libstrong.so -L. -lweak -lstrong
run: main-strong main-weak
LD_LIBRARY_PATH=. ./main-strong
LD_LIBRARY_PATH=. ./main-weak
clean:
rm -f *.so *.o main-strong main-weak
And below is the result from make run:
LD_LIBRARY_PATH=. ./main-strong
7DerivedIiE
7DerivedIcE
7DerivedIiE
7DerivedIcE
LD_LIBRARY_PATH=. ./main-weak
==1511755==The following global variable is not properly aligned.
==1511755==This may happen if another global with the same name
==1511755==resides in another non-instrumented module.
==1511755==Or the global comes from a C file built w/o -fno-common.
==1511755==In either case this is likely an ODR violation bug,
==1511755==but AddressSanitizer can not provide more details.
=================================================================
==1511755==ERROR: AddressSanitizer: odr-violation (0x7f91069c5249):
[1] size=12 'typeinfo name for Derived<char>' strong.cpp
[2] size=12 'typeinfo name for Derived<char>' strong.cpp
These globals were registered at these points:
[1]:
#0 0x434e17 (/data/users/twoh/tmp/weakso/main-weak+0x434e17)
#1 0x7f91067c168b (libstrong.so+0x168b)
[2]:
#0 0x434e17 (/data/users/twoh/tmp/weakso/main-weak+0x434e17)
#1 0x7f91067c168b (libstrong.so+0x168b)
==1511755==HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_odr_violation=0
SUMMARY: AddressSanitizer: odr-violation: global 'typeinfo name for Derived<char>' at strong.cpp
==1511755==ABORTING
If I checked the IR, _ZTS7DerivedIcE has external linkage in strong.cpp, while it has linkonce_odr linkage in weak.cpp. As ASAN doesn't instrument weak symbols, _ZTS7DerivedIcE is not aligned in libweak.so as
nm libweak.so | grep _ZTS7DerivedIcE
0000000000001249 V _ZTS7DerivedIcE
. So it seems that if dynamic linker observes weak symbol (from libweak.so) before the strong symbol (From libstrong.so) as in the case of main-weak binary, odr-violation is reported from here (https://github.com/llvm-mirror/compiler-rt/blob/master/lib/asan/asan_globals.cc#L200) when the registration is attempted from the instrumentation for the strong symbol.
I was able to repro this issue from top-of-trunk. I wonder if there's any fix or work around available. Thanks!