-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
XCode 14.2/Swift 5.7 memory corruption on Task creation when app is launched on iOS < 16. #63420
Comments
|
Hello @DougGregor and @rjmccall! Sorry for bothering you by directly mentioning here. Could you please take a look at the issue, maybe you will suggest how severe the actual problem is. Thanks a lot in advance, Yury! |
|
CC: @mikeash |
|
@mstyura Thanks a lot for the nice reproducer. I'm able to replicate the crash here. I'll see if I can figure out what's going on. |
|
I uncommented just This async function pointer specifies an initial context size of 16. However, the runtime assumes that it will be able to store a In the current version of the concurrency runtime, I think this is usually harmless, as this field will usually extend into whatever else the task uses the initial context for. But if there is no other such use, we don't allocate enough memory, and this dead write turns into a memory smasher. The compiler probably needs to pad this value a bit when targeting older OSes. @rjmccall can you take a look? |
@mikeash could you please elaborate on the reasons behind the safety of writing outside of "bounds", as I understand that this always happens when run over an old runtime? I've observed that crashes do not occur when a lambda captures external variables, and I'm curious about how these variables are stored. I wonder if writing to the "Flags" field might potentially interfere with the data structures related to the context of the lambda capture. Thank you.
I understand that it's a natural behavior for a compiler that was compiled with the AsyncContext definition without flags, but with a backward-compatible runtime that assumes the presence of flags. In light of this, perhaps it would be sensible to reintroduce the "flags" field in the form of a private and unusable field (aka placeholder), in order to preserve size assumptions and avoid any potential breakage. |
|
When creating a task, the compiler generates an "initial context size" which tells the runtime how much extra space to allocate. This space is then used for various task-local stuff, like variables that persist across suspension points. The runtime also puts an That's on newer concurrency runtimes, after the commit I linked above. On older concurrency runtimes, it's supposed to look like this: However, with a new compiler that thinks The It looks like this is usually harmless, as the runtime sets If nothing else needs to be stored, the compiler asks the runtime to allocate just enough space for I don't think we need to go so far as to reintroduce |
|
Yes, I think setting a minimum size is probably the way to go. |
|
Hello @rjmccall! Sorry for bothering you. I've downloaded
are just not include in the |
|
@AnthonyLatsis the problems is that whenever I use custom toolchain with xcode, I'm getting the error when trying to launch app with debugger attached: The workaround suggested here haven't helped. |
|
Hm. cc @shahmishal |
|
@JDevlieghere @adrian-prantl can you help look into this issue? |
|
Hi @mstyura |
|
FWIW I tried to repo this with a slightly different Xcode and swift-5.8-DEVELOPMENT-SNAPSHOT-2023-02-20-a-osx.pkg, and did not reproduce the failure. |
|
@jasonmolenda thanks for a hint. ReportBasically swift toolchain has |
|
@mstyura excellent, thanks for getting to the bottom of it. Ah, I see from the LLDB LC_RPATHs that LLDB looks for the installed Xcode.app as /Applications/Xcode.app to find Python, but you have Xcode installed as Xcode_14.2.app. The Xcode app bundle is normally self contained, but the CommandLineTools lldb has an assumption about the name. I'll look into what we might be able to do to make this more resilient. |
|
As @jasonmolenda pointed out, Xcode and the Command Line Tools (CLT) are self contained and each contain a copy of the Python 3 framework, which allows us to have a relative RPATH from LLDB. There's (purposely) no Python 3 in the operating system so there's no relative RPATH that can guarantee you to find the Python framework from |
Description
Task creation in some contexts can lead to corruption of the application's memory. Examples can be seen in the demo application code.
Steps to reproduce
TaskCrasher - Release - libgmalloc - use with arm64 simulator;arm64iOS simulator withiOS 15.4;Expected behavior
Application is not crashed.
Actual behavior
Demo app crashes with
libgmallocenabled. Address sanitizer unfortunately unable to catch the issue.I've actually encountered problem on real production application on iOS device where app is randomly crashed on memory access to address
0x100000000 + offsetwhere offset is usually+0x10,+0x20or-0x8in application or system library code.Also in real application
libmallocwere capable to detect it was corrupted on some point, but it was unclear who was responsible for corruption.Environment
checked that issue happen on iOS 14 and iOS 13 and iOS 15 as deployment target.
Additional context:
An app that I observed crashing worked fine when built with
XCode 13.4.1andSwift 5.6, but experienced significant, random crashes with "bad access" errors on addresses like0x100000020when built withXCode 14.2orXCode 14.1andSwift 5.7. As a result, it's currently not feasible to target iOS versions lower than 16 and useSwift 5.7with async functions and Tasks without encountering random crashes.UPD: On demo application issue is only happen when compiled with
-O(optimize for speed), but not when compiled with-Osize(optimize for size) or-Onone.The text was updated successfully, but these errors were encountered: