Skip to content

[release/10.0][Android NativeAOT] NDK r29 duplicate libunwind symbols remain in servicing packages #12138

Description

@simonrozsival

Description

The Android NativeAOT + NDK r29 duplicate-libunwind failure fixed on main by dotnet/runtime#128927 is still present in .NET 10 servicing packages, including 10.0.10.

This is now failing dotnet/android PR validation in:

DotNetInstallAndRunMinorAPILevels(
    True,
    "net10.0-android36.1",
    NativeAOT)

The arm64 application link fails with 20 duplicate symbols between:

Microsoft.NETCore.App.Runtime.NativeAOT.android-arm64/10.0.9/
    runtimes/android-arm64/native/libRuntime.WorkstationGC.a

Android NDK 29.0.14206865/
    .../lib/clang/21/lib/linux/aarch64/libunwind.a

Representative errors:

ld.lld : error : duplicate symbol: __unw_init_local
>>> defined at libunwind.cpp:44
>>> libunwind.cpp.o:(__unw_init_local)
>>>     in libRuntime.WorkstationGC.a
>>> defined at libunwind.cpp
>>> libunwind.cpp.o:(.text.__unw_init_local+0x0)
>>>     in NDK .../aarch64/libunwind.a

ld.lld : error : duplicate symbol: unw_local_addr_space
clang : error : linker command failed with exit code 1
Microsoft.NETCore.Native.targets(389,5): error MSB3073

The complete set of duplicate symbols observed in both failures is:

__unw_add_dynamic_eh_frame_section
__unw_add_dynamic_fde
__unw_get_fpreg
__unw_get_proc_info
__unw_get_proc_name
__unw_get_reg
__unw_init_local
__unw_is_fpreg
__unw_is_signal_frame
__unw_iterate_dwarf_unwind_cache
__unw_regname
__unw_remove_dynamic_eh_frame_section
__unw_remove_dynamic_fde
__unw_resume
__unw_set_fpreg
__unw_set_reg
__unw_step
__unw_step_stage2
libunwind::LocalAddressSpace::sThisAddressSpace
unw_local_addr_space

Recent CI history

I scanned all 76 dotnet/android PR builds from the last three days, including superseded and retried builds. Azure Test results contained this exact failed test in two builds:

Build PR Result
1513118 #12121 Initial run and auto-retry both failed; build failed
1512416 #12130 Initial run and auto-retry both failed; stage retry is running

Both failures have the same configuration:

Component Version
TFM net10.0-android36.1
Runtime NativeAOT, Release
RID android-arm64 (x64 link succeeds)
Microsoft.DotNet.ILCompiler 10.0.9
Microsoft.NETCore.App.Runtime.NativeAOT.android-arm64 10.0.9
Microsoft.Android.Runtime.NativeAOT.36.android-arm64 36.1.69
NDK 29.0.14206865
clang/lld 21.0.0
Android link target aarch64-linux-android21

For comparison, the exact same parameterized test passed in:

The two failures ran on hosted image macos-15/20260715.0340.1; the confirmed passes ran on macos-15/20260629.0276.1. Both images document NDK r29 and ANDROID_NDK_LATEST_HOME pointing to it, so the exact image-level trigger is not yet clear. The product-level conflict is nevertheless the same as dotnet/runtime#121172.

Existing fix and servicing gap

dotnet/runtime#121172 was closed by dotnet/runtime#128927:

d553195ce056de3b309d3f51d558bfe80f6cf911
Privatize NativeAOT libunwind symbols

That commit is on main but is not in release/10.0, and I could not find a release/10.0 backport PR.

Package inspection confirms the gap:

Microsoft.NETCore.App.Runtime.NativeAOT.android-arm64 10.0.9
  nm -g libRuntime.WorkstationGC.a:
    T __unw_get_reg
    T __unw_init_local
    D unw_local_addr_space

Microsoft.NETCore.App.Runtime.NativeAOT.android-arm64 10.0.10
  nm -g libRuntime.WorkstationGC.a:
    T __unw_get_reg
    T __unw_init_local
    D unw_local_addr_space

Microsoft.NETCore.App.Runtime.NativeAOT.android-arm64 11.0.0-preview.7.26360.111
  nm -g: no matches
  nm:
    t __unw_get_reg
    t __unw_init_local
    d unw_local_addr_space

The lowercase symbol types in the .NET 11 package show that dotnet/runtime#128927 correctly made the symbols local. Both current .NET 10 packages still export them globally from the static archive.

Requested action

Please consider backporting dotnet/runtime#128927 (or an equivalent safe fix) to release/10.0 so a future .NET 10 servicing release can link Android NativeAOT apps with NDK r29.

If a servicing backport is not feasible, guidance on the supported workaround would help dotnet/android decide whether to pin the .NET 10 compatibility test to NDK r28.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIssues that need to be assigned.

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions