Skip to content

fix: retain native debug symbols#988

Open
ovitrif wants to merge 22 commits into
masterfrom
fix/sigabrt-crash-982
Open

fix: retain native debug symbols#988
ovitrif wants to merge 22 commits into
masterfrom
fix/sigabrt-crash-982

Conversation

@ovitrif

@ovitrif ovitrif commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Refs #982

Related

Description

This PR fixes the native crash symbolication path without bloating the app download.

  • Consumes stripped Rust Android packages:
    • com.synonym:bitkit-core-android:0.1.73
    • com.synonym:ldk-node-android:0.7.0-rc.51
    • com.synonym:vss-client-android:0.5.20
  • Keeps Android on the existing com.synonym:paykit-android:0.1.0-rc8 package for now. pubky/paykit-rs#54 prepares Paykit symbols upstream, but Android is intentionally not consuming that newer Paykit package in this PR because Paykit is not user-facing yet and the app integration update should land separately.
  • Resolves the consumed dependencies' separate native-debug-symbols classifier artifacts during just release.
  • Merges those upstream symbol zips into app/build/outputs/native-debug-symbols/mainnetRelease/native-debug-symbols-182.zip for Play Console and GitHub release uploads.
  • Includes native-debug-symbols-182.zip in both public and internal release workflow artifacts, with SHA256SUMS.txt, so release managers can keep the exact symbol archive from the release build.
  • Keeps Android-side guards so release builds fail if the required upstream symbol artifacts are missing, if duplicate upstream symbol entries would overwrite each other, or if the final archive would be created from stripped packaged .so files.
  • Keeps the app runtime artifacts stripped; the large DWARF/debug payload lives only in symbol archives.

Upstream package publication runs consumed by Android:

  • synonymdev/bitkit-core: 27626818150
  • synonymdev/ldk-node: 27703694826
  • synonymdev/vss-rust-client-ffi: 27703652412

Prepared upstream but not consumed by Android yet:

Preview

N/A

QA Notes

Passed locally on this rebased head:

  • actionlint .github/workflows/release.yml .github/workflows/release-internal.yml
  • sh -n scripts/create-native-debug-symbols.sh
  • GITHUB_TOKEN=$GITHUB_PAT just release
  • GITHUB_TOKEN=$GITHUB_PAT just compile
  • GITHUB_TOKEN=$GITHUB_PAT just test
  • GITHUB_TOKEN=$GITHUB_PAT just lint
  • git diff --check

Previously passed locally for this PR chain:

  • scripts/create-native-debug-symbols.sh
  • ./gradlew --no-daemon testDevDebugUnitTest --tests to.bitkit.build.NativeReleaseConfigTest

Artifact proof:

  • Remote POM/AAR/native-debug-symbols classifier URLs return HTTP 200 for bitkit-core, ldk-node, and vss-rust-client-ffi at the versions consumed by Android.
  • Downloaded remote AARs for bitkit-core, ldk-node, and vss-rust-client-ffi contain no .debug_* sections in packaged Rust .so files.
  • just release produced app/build/outputs/bundle/mainnetRelease/bitkit-mainnet-release-182.aab at 89,123,089 bytes.
  • just release produced app/build/outputs/native-debug-symbols/mainnetRelease/native-debug-symbols-182.zip at 315,939,504 bytes.
  • The built AAB contains stripped libbitkitcore.so, libldk_node.so, and libvss_rust_client_ffi.so files for arm64-v8a and armeabi-v7a, with no .debug_info sections.
  • The native debug symbols archive contains .debug_info DWARF metadata for libbitkitcore.so, libldk_node.so, and libvss_rust_client_ffi.so for both arm64-v8a and armeabi-v7a.
  • The native debug symbols archive intentionally does not contain libpaykit.so yet.

@ovitrif ovitrif changed the title fix: bump bitkit-core dependency fix: address prod sigabrt #982 Jun 3, 2026
@ovitrif ovitrif self-assigned this Jun 3, 2026
@ovitrif ovitrif added this to the 2.3.0 milestone Jun 3, 2026
@ovitrif ovitrif changed the title fix: address prod sigabrt #982 fix: native code abort signal crash Jun 3, 2026
@ovitrif ovitrif force-pushed the fix/sigabrt-crash-982 branch 2 times, most recently from f64bc5a to 008aa9c Compare June 3, 2026 22:44
@ovitrif ovitrif changed the title fix: native code abort signal crash chore: retain native debug symbols Jun 3, 2026
@ovitrif ovitrif marked this pull request as draft June 3, 2026 22:50
@ovitrif ovitrif mentioned this pull request Jun 3, 2026
3 tasks
@ovitrif ovitrif requested review from ben-kaufman and piotr-iohk June 4, 2026 13:18
@ovitrif ovitrif changed the title chore: retain native debug symbols fix: create native symbols zip Jun 4, 2026
@ovitrif ovitrif marked this pull request as ready for review June 4, 2026 14:19
chatgpt-codex-connector[bot]

This comment was marked as resolved.

@ovitrif ovitrif changed the title fix: create native symbols zip fix: native code abort signal crash Jun 4, 2026
@ovitrif

This comment was marked as outdated.

ben-kaufman

This comment was marked as resolved.

@ovitrif ovitrif modified the milestones: 2.3.0, 2.4.0 Jun 4, 2026
@ovitrif ovitrif marked this pull request as draft June 4, 2026 18:08
@ovitrif

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@synonymdev synonymdev deleted a comment from chatgpt-codex-connector Bot Jun 5, 2026
@ovitrif ovitrif changed the title fix: native code abort signal crash fix: retain native debug symbols Jun 5, 2026
@ovitrif ovitrif requested a review from ben-kaufman June 9, 2026 21:05
@ovitrif

This comment was marked as resolved.

@piotr-iohk piotr-iohk mentioned this pull request Jun 17, 2026
5 tasks
@ovitrif ovitrif marked this pull request as ready for review June 17, 2026 12:34
@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR establishes a complete native debug symbol pipeline for Play Console crash symbolication: stripped Rust AARs are consumed for the app download, and separate native-debug-symbols classifier artifacts from bitkit-core, ldk-node, and vss-client are downloaded by a new Gradle Sync task, then merged and validated by a new shell script that guards against accidentally shipping stripped placeholder archives.

  • Gradle side: A custom nativeDebugSymbols configuration and syncNativeDebugSymbolArtifacts Sync task download upstream symbol ZIPs into intermediates/; debugSymbolLevel = "FULL" is added to the release NDK block; three library versions are bumped to their stripped-AAR counterparts.
  • Script side: create-native-debug-symbols.sh reads the build number from app/build.gradle.kts, merges per-dependency ZIPs into a single numbered archive, and rejects any output that lacks DWARF .debug_info sections — with llvm-readelf/readelf discovered from NDK env vars or local.properties.
  • CI/Justfile: Both release workflows and just release now run syncNativeDebugSymbolArtifacts + the shell script in the same credentialed step, and the resulting native-debug-symbols-{versionCode}.zip is included in uploaded artifacts and SHA256 checksums.

Confidence Score: 4/5

Safe to merge; the two shell script findings are both minor robustness concerns that don't affect correctness for the current set of three well-separated dependency archives.

The overall pipeline is well-structured: credentials are correctly scoped, validation guards prevent stripped archives from reaching Play Console, and the regression tests lock in configuration invariants. The shell script's awk build-number extraction lacks a numeric guard (so a future refactoring of versionCode to a Kotlin constant would silently produce a mislabeled archive), and the archive merge loop processes ZIPs in non-deterministic glob order with overwrite semantics. Neither issue is reachable with the current codebase, but both add fragility worth addressing.

scripts/create-native-debug-symbols.sh — specifically the awk build-number extraction (no integer validation) and the for archive in *.zip loop (non-deterministic overwrite order).

Important Files Changed

Filename Overview
scripts/create-native-debug-symbols.sh New shell script that merges upstream native debug symbol ZIPs and validates DWARF metadata; the awk-based versionCode extraction is fragile, and copy_archive_symbols silently ignores per-archive missing libs (deferred to downstream validation).
app/build.gradle.kts Adds debugSymbolLevel = FULL for release builds, a custom nativeDebugSymbols configuration, and a syncNativeDebugSymbolArtifacts Sync task; implementation is clean and the nativeDebugSymbolsArtifact() helper correctly reads versions from the version catalog.
.github/workflows/release.yml Both sync and script steps correctly run inside the same env: block that sets GPR_TOKEN/GITHUB_TOKEN; SHA256 checksums now include the symbol archive alongside AAB and APK.
.github/workflows/release-internal.yml Mirrors release.yml changes for the internal build; all three steps (Gradle build, syncNativeDebugSymbolArtifacts, script) share the same env block with required credentials.
gradle/libs.versions.toml Version bumps for bitkit-core (0.1.72→0.1.73), ldk-node-android (0.7.0-rc.46→0.7.0-rc.50), and vss-client (0.5.12→0.5.19) to consume stripped AAR packages with separate native-debug-symbols classifier artifacts.
app/src/test/java/to/bitkit/build/NativeReleaseConfigTest.kt New string-matching regression tests that guard configuration invariants across build.gradle.kts, Justfile, and the shell script; repo-root discovery via libs.versions.toml lookup is robust.
Justfile The release recipe gains an embedded sh block that cleans stale archives before the build, then runs sync and script steps in the correct order.
.agents/commands/release.md Documents the new native debug symbols upload step for both GitHub Releases and Play Console; instructions are clear and consistent with the Justfile/workflow changes.
README.md Adds concise documentation on the release artifacts and native debug symbol handling workflow.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Dev as Developer / CI
    participant Gradle as Gradle Build
    participant GPR as GitHub Package Registry
    participant Script as create-native-debug-symbols.sh
    participant Play as Play Console

    Dev->>Gradle: assembleMainnetRelease bundleMainnetRelease
    Gradle-->>Dev: bitkit-mainnet-release-N.apk / .aab (stripped .so)

    Dev->>Gradle: :app:syncNativeDebugSymbolArtifacts
    Gradle->>GPR: "Resolve bitkit-core:native-debug-symbols@zip"
    Gradle->>GPR: "Resolve ldk-node-android:native-debug-symbols@zip"
    Gradle->>GPR: "Resolve vss-client-android:native-debug-symbols@zip"
    GPR-->>Gradle: 3x symbol ZIPs to intermediates/native-debug-symbol-artifacts/

    Dev->>Script: scripts/create-native-debug-symbols.sh
    Script->>Script: Extract and merge per-lib .so files from 3 ZIPs
    Script->>Script: validate_symbol_tree (llvm-readelf: .debug_info present?)
    Script-->>Dev: native-debug-symbols-N.zip (315 MB DWARF archive)

    Dev->>Play: Upload .aab (stripped, ~89 MB)
    Dev->>Play: Upload native-debug-symbols-N.zip (App bundle explorer - Assets)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Dev as Developer / CI
    participant Gradle as Gradle Build
    participant GPR as GitHub Package Registry
    participant Script as create-native-debug-symbols.sh
    participant Play as Play Console

    Dev->>Gradle: assembleMainnetRelease bundleMainnetRelease
    Gradle-->>Dev: bitkit-mainnet-release-N.apk / .aab (stripped .so)

    Dev->>Gradle: :app:syncNativeDebugSymbolArtifacts
    Gradle->>GPR: "Resolve bitkit-core:native-debug-symbols@zip"
    Gradle->>GPR: "Resolve ldk-node-android:native-debug-symbols@zip"
    Gradle->>GPR: "Resolve vss-client-android:native-debug-symbols@zip"
    GPR-->>Gradle: 3x symbol ZIPs to intermediates/native-debug-symbol-artifacts/

    Dev->>Script: scripts/create-native-debug-symbols.sh
    Script->>Script: Extract and merge per-lib .so files from 3 ZIPs
    Script->>Script: validate_symbol_tree (llvm-readelf: .debug_info present?)
    Script-->>Dev: native-debug-symbols-N.zip (315 MB DWARF archive)

    Dev->>Play: Upload .aab (stripped, ~89 MB)
    Dev->>Play: Upload native-debug-symbols-N.zip (App bundle explorer - Assets)
Loading

Reviews (1): Last reviewed commit: "fix: defer paykit symbol integration" | Re-trigger Greptile

greptile-apps[bot]

This comment was marked as resolved.

@ovitrif ovitrif force-pushed the fix/sigabrt-crash-982 branch from 01d9b88 to 4cd95d1 Compare June 17, 2026 17:21

@ovitrif ovitrif left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self-reviewed and tested

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants