Summary
Stop linking or extracting the Android NDK's libunwind.a into NativeAOT application links.
This is the parent goal for #12139. Removing libc++/libc++abi is a prerequisite because libc++abi is currently the primary built-in _Unwind_* consumer that causes the NDK archive to be extracted.
NativeAOT's private LLVM-libunwind implementation must remain. It is required for managed stack walking, exception handling, GC, stack traces, profiling, and related runtime services.
Motivation
Android NativeAOT currently has two unwind implementations in the final link closure:
- NativeAOT's private implementation in
libRuntime.WorkstationGC.a;
- the Android NDK implementation in
libunwind.a.
With .NET 10.0.9 and NDK 29.0.14206865, both archives export the same global symbols. Two independent dotnet/android PR builds reproduce the resulting linker failure:
Both fail:
DotNetInstallAndRunMinorAPILevels(True, "net10.0-android36.1", NativeAOT)
ld.lld reports duplicate definitions including:
__unw_init_local
__unw_get_reg
__unw_step
__unw_resume
unw_local_addr_space
The .NET 11 fix in dotnet/runtime#128927 privatizes NativeAOT's symbols and remains valuable defense-in-depth. It does not make the second unwind implementation useful, however. Avoiding the NDK archive entirely removes duplicate code from the link closure and prevents this class of collision for runtime versions without privatization.
Dependency and sequence
Likely implementation surfaces include:
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
src/Xamarin.Android.Build.Tasks/Utilities/NativeRuntimeComponents.cs
src/androidsdk/androidsdk.targets
build-tools/create-packs/Microsoft.Android.Runtime.proj
Validation
For arm64, arm32, x64, and x86 where supported, in Debug and Release:
- final link response does not contain the Android NDK's
libunwind.a;
- final
libNativeAOT.so has no unresolved _Unwind_* requirements;
- NativeAOT's private unwind implementation remains present and usable;
- managed exceptions and native-to-managed exception transitions work;
- GC stack walking and repeated GC bridge processing work;
- managed stack traces, profiling, and crash reporting work;
- workload NativeLinker and legacy linker paths both succeed;
- supported third-party native-library scenarios continue to link.
Non-goals
Related
Summary
Stop linking or extracting the Android NDK's
libunwind.ainto NativeAOT application links.This is the parent goal for #12139. Removing libc++/libc++abi is a prerequisite because libc++abi is currently the primary built-in
_Unwind_*consumer that causes the NDK archive to be extracted.NativeAOT's private LLVM-libunwind implementation must remain. It is required for managed stack walking, exception handling, GC, stack traces, profiling, and related runtime services.
Motivation
Android NativeAOT currently has two unwind implementations in the final link closure:
libRuntime.WorkstationGC.a;libunwind.a.With .NET 10.0.9 and NDK 29.0.14206865, both archives export the same global symbols. Two independent
dotnet/androidPR builds reproduce the resulting linker failure:dotnet-androidbuild #1513800dotnet-androidbuild #1513910Both fail:
ld.lldreports duplicate definitions including:__unw_init_local__unw_get_reg__unw_step__unw_resumeunw_local_addr_spaceThe .NET 11 fix in dotnet/runtime#128927 privatizes NativeAOT's symbols and remains valuable defense-in-depth. It does not make the second unwind implementation useful, however. Avoiding the NDK archive entirely removes duplicate code from the link closure and prevents this class of collision for runtime versions without privatization.
Dependency and sequence
libc++_static.aandlibc++abi.afrom NativeAOT application links._Unwind_*consumer, including compiler runtime objects and supported third-party native libraries.libunwind.ainput is unused without relying only on linker garbage collection.libunwind.ainput from both the workload NativeLinker path and the legacy NDK/clang path.libunwind.aentry in NativeAOT link responses.Likely implementation surfaces include:
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targetssrc/Xamarin.Android.Build.Tasks/Utilities/NativeRuntimeComponents.cssrc/androidsdk/androidsdk.targetsbuild-tools/create-packs/Microsoft.Android.Runtime.projValidation
For arm64, arm32, x64, and x86 where supported, in Debug and Release:
libunwind.a;libNativeAOT.sohas no unresolved_Unwind_*requirements;Non-goals
_Unwind_*.Related
libNativeAOT.so