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

asan hangs at exception #38989

Closed
llvmbot opened this issue Nov 12, 2018 · 12 comments
Closed

asan hangs at exception #38989

llvmbot opened this issue Nov 12, 2018 · 12 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla compiler-rt:asan Address sanitizer

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 12, 2018

Bugzilla Link 39641
Resolution FIXED
Resolved on Jul 18, 2019 01:14
Version 8.0
OS Linux
Attachments test case
Reporter LLVM Bugzilla Contributor
CC @dwblaikie,@kcc,@serge-sans-paille

Extended Description

Hello.

Attached is a test-case for the problem.
If some C++ shlib is dlopen()ed by the C program,
and then this shlib throws an exception (that it
also catches of course - invisible to the C code),
then asan fails to find __cxa_throw, and calls the
__asan_handle_no_return() in an infinite loop.

Another bug here is that it is not possible to
see the symbols of asan functions:

(gdb) bt
#​0 0x00000000004e6bf9 in __asan::AsanThread::stack_top() ()
#​1 0x00000000004e4785 in __asan_handle_no_return ()
#​2 0x000000000043304c in __interceptor___cxa_throw ()
#​3 0x00007ffff40fea9f in foo () at shlib.cpp:4
#​4 0x00007ffff40fe97d in bar () at shlib.cpp:13
#​5 0x00000000005121eb in main () at main.c:11

... even though everything was compiled with debug info.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 12, 2018

assigned to @serge-sans-paille

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 15, 2018

The reason appears simple.
clang statically links asan to the main
executable, and not to shared lib.
As the result, we get this:

Run till exit from #​0 __dlsym (handle=0xffffffffffffffff,
name=0x5195e8 "__cxa_throw") at dlsym.c:56
0x00000000004e8e85 in __interception::GetRealFunctionAddress(char const*, unsigned long*, unsigned long, unsigned long) ()
Value returned is $1 = (void ) 0x0
(gdb) bt
#​0 0x00000000004e8e85 in __interception::GetRealFunctionAddress(char const
, unsigned long*, unsigned long, unsigned long) ()
#​1 0x00000000004d2db3 in __asan::InitializeAsanInterceptors() ()
#​2 0x00000000004e4c84 in __asan::AsanInitInternal() [clone .part.0] ()
#​3 0x00007ffff7de5806 in _dl_init (main_map=0x7ffff7ffe170, argc=1,
argv=0x7fffffffdf08, env=0x7fffffffdf18) at dl-init.c:104
#​4 0x00007ffff7dd60ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2

Since the main executable is not linked to
libstdc++ (only the C++ shlib is linked to it),
dlsym() can't resolve __cxa_throw.
The additional bug, compared to gcc's asan, is
that clang's one doesn't check the dlsym() failure
and that leads to hangs (not sure why a hang and
not a NULL deref).
In gcc things are much better: it uses dynamic
linking of libasan (not static, as clang), and
it checks the dlsym() return, so with gcc there
is only a run-time error msg.

@serge-sans-paille
Copy link
Collaborator

This is still reproducible with compiler-rt master version.
The infinite loop is caused by asan choosing to dlsym on its interceptor when finding next symbol fails (in your case because libstdc++ is not loaded yet).

A nice way to fix that error would be to lazily load interceptors, but that would come at a small runtime cost.

Adding Kostya Serebryany for more advices...

@kcc
Copy link
Contributor

kcc commented Jun 18, 2019

Is there an easy workaround in the build command line(s) for this program?
I am reluctant to support this case if it adds further complexity to asan.

@serge-sans-paille
Copy link
Collaborator

The workaround is trivial: pass -lstdc++ to the linker when compiling the main function.

That way, when asan builds its interceptors, the `__cxa_throw`` symbol is found by dlopen.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jun 20, 2019

Is this somehow specific to libstdc++,
or this "workaround" will have to be applied
for all deps, recursively?

Also, gcc's asan at least doesn't hang in an
infinite loop. It prints an error and goes on,
which is a big win by itself.

@serge-sans-paille
Copy link
Collaborator

It's not specific to libstdc++, the issue would raise for any shared library linked into a dlopened library and not in the main executable.

I agree with the error handling aspect, @​kostya, any idea to improve the situation?

@kcc
Copy link
Contributor

kcc commented Jun 21, 2019

No good ideas, sorry, except that patches are welcome
(as long as they don't add too much complexity)

@serge-sans-paille
Copy link
Collaborator

@​Kostya:

in this snippet

INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
  CHECK(REAL(__cxa_throw));
  __asan_handle_no_return();
  REAL(__cxa_throw)(a, b, c);
}

we could check whether REAL(__cxa_throw) != __cxa_throw, which is the cause of the origin loop. Even better, if REAL(__cxa_throw) == __cxa_throw, we could try a new dlsym lookup because if the input program is correct, then __cxa_throw must be available when called.

Taking this one step further, there is no need to run the dlsym at startup, it could be done lazily upon first call :-)

@kcc
Copy link
Contributor

kcc commented Jun 26, 2019

I'd like to avoid any kind of lazy init, it usually adds complexity more than it removes it.
If you can come up with a simple check in the interceptor, and a test,
please submit a patch.

@serge-sans-paille
Copy link
Collaborator

https://reviews.llvm.org/D63877 now raises a decent error

@serge-sans-paille
Copy link
Collaborator

Fixed by https://reviews.llvm.org/rL366413

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
feltech added a commit to feltech/OpenAssetIO that referenced this issue Mar 10, 2022
ASan hangs in an infinite loop if an exception is raised in a `.so`
that was loaded by a `dlopen`ed library. There doesn't seem to be a fix
for this yet - the bug report says it is fixed, but there is a
subsequent revert of the fix and the issue was not re-opened. See code
comments.

See: https://bugs.llvm.org/show_bug.cgi?id=39641
and: llvm/llvm-project#38989

Signed-off-by: David Feltell <david.feltell@foundry.com>
feltech added a commit to feltech/OpenAssetIO that referenced this issue Mar 10, 2022
ASan hangs in an infinite loop if an exception is raised in a `.so`
that was loaded by a `dlopen`ed library. There doesn't seem to be a fix
for this yet - the bug report says it is fixed, but there is a
subsequent revert of the fix and the issue was not re-opened. See code
comments.

See: https://bugs.llvm.org/show_bug.cgi?id=39641
and: llvm/llvm-project#38989

Signed-off-by: David Feltell <david.feltell@foundry.com>
feltech added a commit to feltech/OpenAssetIO that referenced this issue Mar 10, 2022
ASan hangs in an infinite loop if an exception is raised in a `.so`
that was loaded by a `dlopen`ed library. There doesn't seem to be a fix
for this yet - the bug report says it is fixed, but there is a
subsequent revert of the fix and the issue was not re-opened. See code
comments.

See: https://bugs.llvm.org/show_bug.cgi?id=39641
and: llvm/llvm-project#38989

Signed-off-by: David Feltell <david.feltell@foundry.com>
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla compiler-rt:asan Address sanitizer
Projects
None yet
Development

No branches or pull requests

3 participants