80 lines · cpp
1// Test that captures the current behavior of indicator-based ASan ODR checker2// when globals get unregistered.3//4// RUN: %clangxx_asan -g -O0 -DSHARED_LIB -DSIZE=1 %s -fPIC -shared -o %t-so-1.so5// RUN: %clangxx_asan -g -O0 -DSHARED_LIB -DSIZE=2 %s -fPIC -shared -o %t-so-2.so6// RUN: %clangxx_asan -g -O0 %s %libdl -Wl,--export-dynamic -o %t7// RUN: %env_asan_opts=report_globals=2:detect_odr_violation=1 %run %t 2>&1 | FileCheck %s8 9// FIXME: Checks do not match on Android.10// UNSUPPORTED: android11 12#include <cstdlib>13#include <dlfcn.h>14#include <stdio.h>15#include <string>16 17#ifdef SHARED_LIB18namespace foo {19char G[SIZE];20}21#else // SHARED_LIB22void *dlopen_or_die(std::string &path) {23 void *handle = dlopen(path.c_str(), RTLD_NOW);24 if (handle) {25 printf("Successfully called dlopen() on %s\n", path.c_str());26 } else {27 printf("Error in dlopen(): %s\n", dlerror());28 std::exit(1);29 }30 31 return handle;32}33 34void dlclose_or_die(void *handle, std::string &path) {35 if (!dlclose(handle)) {36 printf("Successfully called dlclose() on %s\n", path.c_str());37 } else {38 printf("Error in dlclose(): %s\n", dlerror());39 std::exit(1);40 }41}42 43namespace foo {44char G[1];45}46 47// main has its own version of foo::G48// CHECK: Added Global[[MAIN_G:[^\s]+]] size=1/32 name=foo::G {{.*}}49int main(int argc, char *argv[]) {50 std::string base_path = std::string(argv[0]);51 52 std::string path1 = base_path + "-so-1.so";53 // dlopen() brings another foo::G but it matches MAIN_G in size so it's not a54 // violation55 //56 //57 // CHECK: Added Global[[SO1_G:[^\s]+]] size=1/32 name=foo::G {{.*}}58 // CHECK-NOT: ERROR: AddressSanitizer: odr-violation59 void *handle1 = dlopen_or_die(path1);60 // CHECK: Removed Global[[SO1_G]] size=1/32 name=foo::G {{.*}}61 dlclose_or_die(handle1, path1);62 63 // At this point the indicator for foo::G is switched to UNREGISTERED for64 // **both** MAIN_G and SO1_G because the indicator value is shared.65 66 std::string path2 = base_path + "-so-2.so";67 // CHECK: Added Global[[SO2_G:[^\s]+]] size=2/32 name=foo::G {{.*}}68 //69 // This brings another foo::G but now different in size from MAIN_G. We70 // should've reported a violation, but we actually don't because of what's71 // described on line6072 //73 // CHECK-NOT: ERROR: AddressSanitizer: odr-violation74 void *handle2 = dlopen_or_die(path2);75 // CHECK: Removed Global[[MAIN_G]] size=1/32 name=foo::G {{.*}}76 // CHECK: Removed Global[[SO2_G]] size=2/32 name=foo::G {{.*}}77}78 79#endif // SHARED_LIB80