Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang] [windows] [address-sanitizer] stack overflow when test is failing #898

Closed
hia3 opened this issue Apr 28, 2017 · 6 comments
Closed

Comments

@hia3
Copy link

hia3 commented Apr 28, 2017

Description

Catch enters infinite recursion trying to print error message when compiled with clang -faddress-sanitize under Windows

Steps to reproduce

  1. Install VS 2015 and clang
  2. Put catch.hpp and test.bat from test.zip in one directory, start test.bat
  3. Resulting executable, instead of reporting an error, will output:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and then it will crash.

@refi64
Copy link

refi64 commented Apr 28, 2017

FWIW this works normally under Linux.

What if you use normal Clang:

clang++ -fsanitize=address -o test.exe test.cpp

Also, you seem to be building a normal, shared executable. What if you change the library name to clang_rt.asan_dynamic-x86_64.lib? (The one you're using is for applications using the static CRT.)

@hia3
Copy link
Author

hia3 commented Apr 28, 2017

Compiling with

clang++ -fsanitize=address -o test.exe test.cpp

gives me

==748==AddressSanitizer CHECK failed: D:\src\llvm_package_300231\llvm\projects\compiler-rt\lib\asan\asan_rtl.cc:505 "((!asan_init_is_running && "ASan init calls itself!")) != (0)" (0x0, 0x0)
==748==AddressSanitizer CHECK failed: D:\src\llvm_package_300231\llvm\projects\compiler-rt\lib\asan\asan_poisoning.cc:37 "((AddrIsInMem(addr))) != (0)" (0x0, 0x0)

even if 'test.cpp' is just an empty main. This is why I've added /DEBUG when linking. This has nothing to do with Catch, must be clang bug.

With clang_rt.asan_dynamic-x86_64.lib linking fails:

test.obj : error LNK2019: unresolved external symbol __asan_shadow_memory_dynamic_address referenced in function "struct Catch::IResultCapture & __cdecl Catch::getResultCapture(void)" (?getResultCapture@Catch@@YAAEAUIResultCapture@1@XZ)
test.obj : error LNK2019: unresolved external symbol __asan_option_detect_stack_use_after_return referenced in function "struct Catch::IResultCapture & __cdecl Catch::getResultCapture(void)" (?getResultCapture@Catch@@YAAEAUIResultCapture@1@XZ)
test.exe : fatal error LNK1120: 2 unresolved externals

@horenmar
Copy link
Member

Is ASan supported under Windows? Last time I checked, it was "this will very likely work for C, C++ is very much beta".

@ekilmer
Copy link

ekilmer commented Mar 14, 2021

Hello. Now that Address Sanitizer is Generally Available for MSVC, I've noticed that I'm unable to run my tests due to this issue--they get stuck and won't complete.

After some digging, I found a relevant open issue on Microsoft's tracker with a potential workaround that would consist of the following (naive) change to Catch here

exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
and here for the single include header:
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);

- exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
+ exceptionHandlerHandle = AddVectoredExceptionHandler(0, handleVectoredException);

I've tested this change locally with a modified (read: updated) version of the batch script in the OP with a fully updated Visual Studio (v16.9.1) on latest Catch (v2.13.4), and it seems to run to completion!

echo #define CATCH_CONFIG_MAIN > test.cpp
echo #include "catch.hpp" >> test.cpp
echo TEST_CASE( "t", "[t]" ) { REQUIRE( 2 == 1 ); } >> test.cpp

call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
echo Please wait...
cl /EHsc test.cpp -fsanitize=address -c
link /DEBUG test.obj

start test.exe

However, I don't understand the consequences of this change and how it could affect the rest of Catch's logic and exception handling, so hopefully this helps one of the maintainers or someone else more familiar with the code base and C++ in general 🙂

@reder2000
Copy link

reder2000 commented Apr 25, 2021

This is related to the way asan is implemented on x64 msvc. See here doc.
Catch2 is catching tons of 0xc0000005 (FCE - first chance exceptions) and gets confused.
Your fix works but gives up on FCEs.

catch2+asan+msvc is working on x86 unmodified (but nobody builds for x86 anymore)

Maybe catch2 could offer an option to give up on first chance exception or do it automatically on x64 with

... ```

Edit: with catch2 moving as a library, this way to fix depending on asan would not work. 

@unixwitch
Copy link

as a workaround, setting CATCH_CONFIG_NO_WINDOWS_SEH fixed this issue for me (tested with 2.13.6).

ekilmer added a commit to trailofbits/pe-parse that referenced this issue May 16, 2021
ASAN on Windows messes with exception handlers, and Catch2 doesn't
account for this. A workaround is to disable SEH on Windows with ASAN as
suggested in this reply to an existing issue
catchorg/Catch2#898 (comment)
ekilmer added a commit to trailofbits/pe-parse that referenced this issue May 16, 2021
ASAN on Windows messes with exception handlers, and Catch2 doesn't
account for this. A workaround is to disable SEH on Windows with ASAN as
suggested in this reply to an existing issue
catchorg/Catch2#898 (comment)
ekilmer added a commit to trailofbits/pe-parse that referenced this issue May 16, 2021
ASAN on Windows messes with exception handlers, and Catch2 doesn't
account for this. A workaround is to disable SEH on Windows with ASAN as
suggested in this reply to an existing issue
catchorg/Catch2#898 (comment)

CI requires some sourcing of the development tools for required paths
woodruffw pushed a commit to trailofbits/pe-parse that referenced this issue May 19, 2021
ASAN on Windows messes with exception handlers, and Catch2 doesn't
account for this. A workaround is to disable SEH on Windows with ASAN as
suggested in this reply to an existing issue
catchorg/Catch2#898 (comment)

CI requires some sourcing of the development tools for required paths
nicramage pushed a commit to nicramage/Catch2 that referenced this issue Feb 1, 2024
This avoids issues with Catch2's handler firing too early, on
structured exceptions that would be handled later. This issue
meant that the old attempts at structured exception handling
were incompatible with Windows's ASan, because it throws
continuable `C0000005` exception, which it then handles.

With the new handling, Catch2 is only notified if nothing else,
including the debugger, has handled the exception.

Signed-off-by: Alan Jowett <alanjo@microsoft.com>

Closes catchorg#2332
Closes catchorg#2286
Closes catchorg#898
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants