-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
libc++ asan annotations for short string inline storage is incompatible with apple blocks runtime #96099
Comments
Triggering this is as easy as:
This is likely all true in most larger Objective-C++ code bases. |
Won't this happen with any code which uses asan annotations for their memory in a structure that gets copied for the apple blocks? If so shouldn't this be fixed in the block runtime instead? |
Yes, but you'd only use asan annotations for things with inline storage. And even then, it seems to be very rare in practice. I've only seen this happen with std::string so far.
That seems like the right fix to me too, but:
So we'll need something else in the meantime as well. |
It seems to be Apple-specific issue and I agree that it should be fixed in the block logic. However, if it's impossible to do it in time, we can temporarily turn off short string annotations for macOS only. But why it's using There are a few other possible solutions for that, but using the constructor is probably the best one. I don't have macOS, so unfortunately I cannot test anything myself. |
A block closure is a block of bytes. It doesn't know about the types of data therein. See clang/docs/Block-ABI-Apple.rst |
This commit disables short string AddressSanitizer annotations on Apple platforms as a temporary solution to the problem reported in issue llvm#96099. For more information on Apple's block implementation, please refer to [`clang/docs/Block-ABI-Apple.rst`](/clang/docs/Block-ABI-Apple.rst). The core issue lies in the fact that blocks are unaware of their content, causing AddressSanitizer errors when blocks are moved using `memmove`. I believe - and I'm not alone - that the issue should ideally be addressed within the block moving logic. However, if a timely resolution is not feasible, this temporary fix can be used. Before merging, we should ensure that a more permanent solution cannot be implemented in time and that this change effectively resolves the issue.
Thank you for pointing me into the explanation. Other solutions I see right now are:
|
This commit disables short string AddressSanitizer annotations on Apple platforms as a temporary solution to the problem reported in #96099. For more information on Apple's block implementation, please refer to clang/docs/Block-ABI-Apple.rst [1]. The core issue lies in the fact that blocks are unaware of their content, causing AddressSanitizer errors when blocks are moved using `memmove`. I believe - and I'm not alone - that the issue should ideally be addressed within the block moving logic. However, this patch provides a temporary fix until a proper resolution exists in the Blocks runtime. [1]: https://github.com/llvm/llvm-project/blob/main/clang/docs/Block-ABI-Apple.rst
As a matter of process, removing the 19.x release milestone since this isn't really actionable from the LLVM side IMO. This should be fixed in the Blocks runtime AFAIU. |
This commit disables short string AddressSanitizer annotations on Apple platforms as a temporary solution to the problem reported in llvm#96099. For more information on Apple's block implementation, please refer to clang/docs/Block-ABI-Apple.rst [1]. The core issue lies in the fact that blocks are unaware of their content, causing AddressSanitizer errors when blocks are moved using `memmove`. I believe - and I'm not alone - that the issue should ideally be addressed within the block moving logic. However, this patch provides a temporary fix until a proper resolution exists in the Blocks runtime. [1]: https://github.com/llvm/llvm-project/blob/main/clang/docs/Block-ABI-Apple.rst
Summary: This commit disables short string AddressSanitizer annotations on Apple platforms as a temporary solution to the problem reported in #96099. For more information on Apple's block implementation, please refer to clang/docs/Block-ABI-Apple.rst [1]. The core issue lies in the fact that blocks are unaware of their content, causing AddressSanitizer errors when blocks are moved using `memmove`. I believe - and I'm not alone - that the issue should ideally be addressed within the block moving logic. However, this patch provides a temporary fix until a proper resolution exists in the Blocks runtime. [1]: https://github.com/llvm/llvm-project/blob/main/clang/docs/Block-ABI-Apple.rst Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251313
Consider this program:
I don't have a completely standalone repro yet, but based on my current understanding, it's possible to make a repro that uses just the llvm-project repo. For my current repro, I'm using Chromium's toolchain like so:
This triggers an asan report from the blocks runtime:
Here's why:
When creating a block closure, clang will copy C++ objects into the closure using their copy constructor, see clang/lib/CGBlocks.cpp (so far so good).
clang will create calls to
objc_retainBlock
under various conditions, see clang/lib/CodeGen/CGObjC.cpp. One such condition is passing a block to a function taking an rvalue reference when ARC is enabled (but there are other conditions).objc_retainBlock
just calls_Block_copy
(https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/NSObject.mm#L221>If the block contains C++ objects, bit 25 in the block descriptor is set. This bit is called
BLOCK_HAS_COPY_DISPOSE
in both clang and BlocksRuntime. CGBlocks.cpp generates a copy helper (GenerateCopyHelperFunction
) that the block points to. For C++ objects in the closure, it again calls copy ctors._Block_copy
is defined in compiler-rt/lib/BlocksRuntime/runtime.c. It's part of the system dyld closure which ships in macOS. It does:That is, it first makes a copy of the block's closure variables using
memmove()
and then calls the copy helper to fix things up.1a96179 enabled asan instrumentation for the short string inline storage. In the repro, the string is set to
"123"
, meaning some of its short string storage isn't initialized. That makes thatmemmove()
in the block runtime fail.Given that this call is in a macOS system library, fixing this will probably be involved.
(This of course only happens if
_LIBCPP_INSTRUMENTED_WITH_ASAN
is enabled.)clang/docs/Block-ABI-Apple.rst describes the whole blocks ABI fairly well.
The text was updated successfully, but these errors were encountered: