Skip to content

asan: odr-violation false alarm with shared libraries #1017

@taewookoh

Description

@taewookoh

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions