Index: lib/asan/CMakeLists.txt =================================================================== --- lib/asan/CMakeLists.txt +++ lib/asan/CMakeLists.txt @@ -64,6 +64,14 @@ -ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS) append_list_if(MSVC /DEBUG ASAN_DYNAMIC_LINK_FLAGS) +# Delay load dbghelp. Newer versions of dbghelp depend on ucrtbase.dll. We +# can't allow ucrtbase.dll to initialize before ASan, or some heap allocations +# will not be intercepted (http://llvm.org/pr30903). The loader initializes +# dependencies before dependent DLLs, so we can't have a direct dependence on +# dbghelp. +append_list_if(MSVC -delayload:dbghelp.dll ASAN_DYNAMIC_LINK_FLAGS) +append_list_if(MSVC -defaultlib:delayimp.lib ASAN_DYNAMIC_LINK_FLAGS) + append_list_if(COMPILER_RT_HAS_LIBC c ASAN_DYNAMIC_LIBS) append_list_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS) append_list_if(COMPILER_RT_HAS_LIBRT rt ASAN_DYNAMIC_LIBS) Index: test/asan/TestCases/Windows/delay_dbghelp.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Windows/delay_dbghelp.cc @@ -0,0 +1,19 @@ +// Make a directory, copy the problematic copies of dbg*.dll into that +// directory, build an exe there, and force the loader to find dbghelp.dll there +// instead of searching in C:/Windows/system32 first. Touching t.exe.local does +// this, according to MSDN: +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682600(v=vs.85).aspx +// +// RUN: rm -rf %t.dir && mkdir %t.dir && cd %t.dir +// RUN: find %/S/Inputs/delay_dbghelp -iname '*.dll' | xargs cp -t . +// RUN: touch t.exe.local +// RUN: %clang_cl_asan %s -Fet.exe +// RUN: %run %t.dir/t.exe + +// REQUIRES: asan-64-bits + +extern "C" int puts(const char *); + +int main() { + puts("main"); +}