forked from OSchip/llvm-project
[ASan Win] Manually call __asan_init early in the DLL initialization process to avoid a null function call in cout/cerr constructors
llvm-svn: 210030
This commit is contained in:
parent
82899febf0
commit
b1415c46fb
|
@ -325,9 +325,24 @@ INTERCEPT_LIBRARY_FUNCTION(strnlen);
|
|||
INTERCEPT_LIBRARY_FUNCTION(strtol);
|
||||
INTERCEPT_LIBRARY_FUNCTION(wcslen);
|
||||
|
||||
// Must be at the end of the file due to the way INTERCEPT_HOOKS is defined.
|
||||
// Must be after all the interceptor declarations due to the way INTERCEPT_HOOKS
|
||||
// is defined.
|
||||
void InterceptHooks() {
|
||||
INTERCEPT_HOOKS();
|
||||
}
|
||||
|
||||
// We want to call __asan_init before C/C++ initializers/constructors are
|
||||
// executed, otherwise functions like memset might be invoked.
|
||||
// For some strange reason, merely linking in asan_preinit.cc doesn't work
|
||||
// as the callback is never called... Is link.exe doing something too smart?
|
||||
|
||||
// In DLLs, the callbacks are expected to return 0,
|
||||
// otherwise CRT initialization fails.
|
||||
static int call_asan_init() {
|
||||
__asan_init_v3();
|
||||
return 0;
|
||||
}
|
||||
#pragma section(".CRT$XIB", long, read) // NOLINT
|
||||
__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = call_asan_init;
|
||||
|
||||
#endif // ASAN_DLL_THUNK
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
|
||||
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
|
||||
// RUN: %run %t %t.dll 2>&1 | FileCheck %s
|
||||
|
||||
// Test that it works correctly even with ICF enabled.
|
||||
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll -link /OPT:REF /OPT:ICF
|
||||
// RUN: %run %t %t.dll 2>&1 | FileCheck %s
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern "C" __declspec(dllexport)
|
||||
int test_function() {
|
||||
// Just make sure we can use cout.
|
||||
std::cout << "All ok\n";
|
||||
// CHECK: All ok
|
||||
|
||||
// This line forces a declaration of some global basic_ostream internal object that
|
||||
// calls memcpy() in its constructor. This doesn't work if __asan_init is not
|
||||
// called early enough.
|
||||
std::cout << 42;
|
||||
// CHECK: 42
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue