Skip to content

fix(android): Force 16 KB ELF alignment for libsentry-tm-perf-logger.so#6396

Merged
antonis merged 5 commits into
mainfrom
fix/android-tm-perf-logger-16kb-alignment
Jul 3, 2026
Merged

fix(android): Force 16 KB ELF alignment for libsentry-tm-perf-logger.so#6396
antonis merged 5 commits into
mainfrom
fix/android-tm-perf-logger-16kb-alignment

Conversation

@antonis

@antonis antonis commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

libsentry-tm-perf-logger.so — the native library introduced in 8.17.0 (#6307) for Turbo Module performance tracking — is compiled from source in the consuming app via packages/core/android/src/main/jni/CMakeLists.txt. That CMake target did not pass a max-page-size link option, so on NDK r27 and earlier (RN 0.86 / Expo SDK 57 ship with NDK 27) the linker defaulted to 4 KB ELF segment alignment. Every other .so bundled by RN/AGP is already 16 KB aligned, so this was the lone misaligned library in the APK.

This PR:

  1. Adds -Wl,-z,max-page-size=16384 to the CMake target (a no-op on NDK r28+, where 16 KB is already the default):

    target_link_options(
        sentry-tm-perf-logger
        PRIVATE
            "-Wl,-z,max-page-size=16384"
    )
  2. Adds a regression guard — scripts/check-android-16kb-alignment.sh unzips a built APK/AAB and asserts every bundled .so has ELF LOAD segments aligned to at least 16 KB, failing otherwise. It is wired into the sample-application workflow right after the New Architecture Android build (the only place a real APK is produced in CI).

💡 Motivation and Context

Fixes #6394.

On Android 15+ with a 16 KB page size image, affected apps showed the "Android App Compatibility" dialog on every launch and ran in page-size-compat mode. This also fails Google Play's 16 KB requirement. It affected all New Architecture apps on RN ≥ 0.75, regardless of whether enableTurboModuleTracking was enabled — the library is packaged whenever the New Architecture is on, and Android's installer scans every bundled .so for alignment.

💚 How did you test it?

Compiled the actual library sources (SentryTurboModulePerfLogger.cpp + OnLoad.cpp) against the RN 0.86 source tree with NDK 27 (the toolchain RN 0.86 / Expo SDK 57 use), both with and without the flag, and inspected the ELF program headers with llvm-readelf -l:

Build LOAD segment p_align Result
Without the flag (current main) 0x1000 (4 KB) ❌ reproduces the bug
With -Wl,-z,max-page-size=16384 0x4000 (16 KB) ✅ fixed

Backward compatibility confirmed from the fixed binary's headers: every LOAD segment satisfies Offset ≡ VirtAddr (mod 0x4000), which implies mod 0x1000 — so it still loads correctly on 4 KB-page devices (16 KB is a multiple of 4 KB). No file-size change was observed for this library.

The new check-android-16kb-alignment.sh guard was also verified locally against two synthetic APKs — one containing the fixed lib (exit 0, pass) and one containing the pre-fix 4 KB lib (exit 1, fail, offending library reported), reproducing #6394 and confirming the check would catch a future regression.

📝 Checklist

  • I added tests to verify changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

🤖 Generated with Claude Code

The native library added in 8.17.0 (#6307) for Turbo Module performance
tracking is compiled from source with the app's NDK. On NDK r27 and
earlier the linker defaults to 4 KB segment alignment, so this library
was the lone misaligned `.so` in the APK (all prebuilt libs are already
16 KB aligned). This tripped Android 15+'s 16 KB page size compatibility
check and Google Play's 16 KB requirement for New Architecture apps —
even when `enableTurboModuleTracking` was left disabled, since the
library is packaged whenever the New Architecture is enabled.

Pass `-Wl,-z,max-page-size=16384` to the CMake target. Verified with
NDK 27 against the RN 0.86 source tree: LOAD segment alignment goes from
0x1000 (4 KB) to 0x4000 (16 KB), with no file-size change. Backward
compatible with 4 KB-page devices (16 KB is a multiple of 4 KB) and a
no-op on NDK r28+ where 16 KB is already the default.

Fixes #6394

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix(android): Force 16 KB ELF alignment for libsentry-tm-perf-logger.so by antonis in #6396
  • chore(deps): update Sentry Android Gradle Plugin to v6.14.0 by github-actions in #6395

🤖 This preview updates automatically when you update the PR.

Comment thread CHANGELOG.md Outdated
antonis and others added 2 commits July 3, 2026 10:50
Guards against regressing #6394. Adds scripts/check-android-16kb-alignment.sh
which unzips a built APK/AAB and asserts every bundled .so has ELF LOAD
segments aligned to at least 16 KB (p_align >= 0x4000), failing otherwise.

Wired into the sample-application workflow right after the New Architecture
Android app build, where a real APK is produced. The script is portable
across the macOS (bash 3.2) and Ubuntu CI (mawk) shells and resolves
readelf from $READELF, then llvm-readelf, then readelf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sentry

sentry Bot commented Jul 3, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.17.0 (95) Release

⚙️ sentry-react-native Build Distribution Settings

@antonis antonis marked this pull request as ready for review July 3, 2026 09:05
@antonis antonis marked this pull request as draft July 3, 2026 09:06
@antonis

antonis commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Converting to draft to check the CI check failures

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3847.67 ms 1221.52 ms -2626.14 ms
Size 4.98 MiB 6.51 MiB 1.53 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
eb93136+dirty 3843.09 ms 1220.11 ms -2622.98 ms
ad66da3+dirty 3820.96 ms 1214.43 ms -2606.52 ms
b04af96+dirty 3818.92 ms 1219.76 ms -2599.16 ms
9210ae6+dirty 3815.93 ms 1214.14 ms -2601.79 ms
ca9d079+dirty 3835.63 ms 1218.68 ms -2616.95 ms
09a902f+dirty 3835.67 ms 1217.11 ms -2618.57 ms
5a21b51+dirty 3823.11 ms 1214.46 ms -2608.65 ms
d038a14+dirty 3845.71 ms 1228.11 ms -2617.59 ms
64630e5+dirty 3842.70 ms 1218.11 ms -2624.60 ms
0a147b2+dirty 3838.15 ms 1221.94 ms -2616.21 ms

App size

Revision Plain With Sentry Diff
eb93136+dirty 5.15 MiB 6.69 MiB 1.53 MiB
ad66da3+dirty 5.15 MiB 6.67 MiB 1.51 MiB
b04af96+dirty 4.98 MiB 6.54 MiB 1.56 MiB
9210ae6+dirty 5.15 MiB 6.68 MiB 1.53 MiB
ca9d079+dirty 5.15 MiB 6.69 MiB 1.53 MiB
09a902f+dirty 4.98 MiB 6.46 MiB 1.49 MiB
5a21b51+dirty 5.15 MiB 6.67 MiB 1.51 MiB
d038a14+dirty 5.15 MiB 6.67 MiB 1.51 MiB
64630e5+dirty 4.98 MiB 6.46 MiB 1.49 MiB
0a147b2+dirty 4.98 MiB 6.51 MiB 1.53 MiB

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 436.81 ms 466.48 ms 29.66 ms
Size 49.74 MiB 55.09 MiB 5.34 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
8929511+dirty 405.33 ms 452.16 ms 46.83 ms
4b87b12+dirty 421.82 ms 413.60 ms -8.22 ms
822d35b+dirty 429.31 ms 498.04 ms 68.73 ms
44c8b3f+dirty 414.20 ms 457.28 ms 43.08 ms
5569641+dirty 406.43 ms 428.51 ms 22.08 ms
580fb5c+dirty 436.34 ms 471.63 ms 35.28 ms
7ff4d0f+dirty 413.81 ms 450.64 ms 36.83 ms
6177334+dirty 408.16 ms 441.14 ms 32.98 ms
1e5d96d+dirty 519.43 ms 543.62 ms 24.19 ms
f9c1ed4+dirty 431.00 ms 466.22 ms 35.22 ms

App size

Revision Plain With Sentry Diff
8929511+dirty 43.75 MiB 48.16 MiB 4.41 MiB
4b87b12+dirty 43.75 MiB 48.14 MiB 4.39 MiB
822d35b+dirty 49.74 MiB 54.84 MiB 5.10 MiB
44c8b3f+dirty 48.30 MiB 53.46 MiB 5.15 MiB
5569641+dirty 48.30 MiB 53.48 MiB 5.18 MiB
580fb5c+dirty 49.74 MiB 54.79 MiB 5.05 MiB
7ff4d0f+dirty 48.30 MiB 53.60 MiB 5.30 MiB
6177334+dirty 48.30 MiB 53.54 MiB 5.23 MiB
1e5d96d+dirty 49.74 MiB 54.81 MiB 5.07 MiB
f9c1ed4+dirty 49.74 MiB 54.86 MiB 5.12 MiB

The initial CI run failed because the check scanned every .so in the APK,
including React Native and third-party libraries (libreactnative,
libhermesvm, libreanimated, librnscreens, ...) which are 4 KB aligned in
the x86 build CI produces. RN aligns arm64 to 16 KB but not x86, and those
libraries are outside this repo's control.

Add an optional name-filter argument to the check script and pass
'libsentry' in CI so the guard verifies only the libraries this repo ships
(libsentry-tm-perf-logger.so et al.). A regression that drops the
max-page-size flag from our CMake target is still caught — verified
locally: with the filter, our lib at 4 KB still fails the check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@antonis antonis marked this pull request as ready for review July 3, 2026 09:27
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3838.84 ms 1221.96 ms -2616.88 ms
Size 4.98 MiB 6.51 MiB 1.53 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
0bd8916+dirty 3816.17 ms 1215.05 ms -2601.12 ms
0a147b2+dirty 3845.11 ms 1230.81 ms -2614.30 ms
774257e+dirty 3821.35 ms 1211.96 ms -2609.39 ms
acd838e+dirty 3835.94 ms 1215.87 ms -2620.07 ms
038a6d7+dirty 3838.96 ms 1218.86 ms -2620.10 ms
a216cb9+dirty 3853.25 ms 1224.77 ms -2628.48 ms
df5d108+dirty 1207.34 ms 1210.50 ms 3.16 ms
2c735cc+dirty 1223.33 ms 1224.38 ms 1.04 ms
5a010b7+dirty 3856.76 ms 1232.65 ms -2624.11 ms
f170ec3+dirty 3844.74 ms 1222.67 ms -2622.07 ms

App size

Revision Plain With Sentry Diff
0bd8916+dirty 5.15 MiB 6.69 MiB 1.53 MiB
0a147b2+dirty 4.98 MiB 6.51 MiB 1.53 MiB
774257e+dirty 5.15 MiB 6.70 MiB 1.54 MiB
acd838e+dirty 5.15 MiB 6.70 MiB 1.55 MiB
038a6d7+dirty 5.15 MiB 6.70 MiB 1.55 MiB
a216cb9+dirty 4.98 MiB 6.51 MiB 1.53 MiB
df5d108+dirty 3.38 MiB 4.73 MiB 1.35 MiB
2c735cc+dirty 3.38 MiB 4.74 MiB 1.35 MiB
5a010b7+dirty 5.15 MiB 6.69 MiB 1.54 MiB
f170ec3+dirty 5.15 MiB 6.69 MiB 1.53 MiB

@antonis antonis merged commit ade5420 into main Jul 3, 2026
92 of 93 checks passed
@antonis antonis deleted the fix/android-tm-perf-logger-16kb-alignment branch July 3, 2026 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

libsentry-tm-perf-logger.so is not 16 KB page aligned after upgrading from 8.16.0 to 8.17.0

2 participants