SIGABRT / std::terminate in VideoPlayer.deinitialize when exiting clear HLS playback on Back

Title: SIGABRT / std::terminate in VideoPlayer.deinitialize* when exiting clear HLS playback on Back (Callie)


:backhand_index_pointing_right: Bug Description

1. Summary

Native crash (SIGABRT / std::terminate) in the Kepler / W3C media runtime when leaving an HLS playback screen via Back. The process dies during VideoPlayer teardown (deinitialize / deinitializeSync, also seen as deinitializeAsync in logs) and relaunches. Reproduces on one Callie device; other Callie on our side cannot reproduce.

App Name: TabloTV
App Link on Amazon Appstore: https://www.amazon.com/gp/product/B0GPZLB146

Bug Severity:
:check_box_with_check: Impacts operation of app

2. Steps to Reproduce

  1. Install the app on an affected Callie device (see Environment).
  2. Launch the app (foreground).
  3. Start clear HLS (m3u8) playback via headless W3C VideoPlayer + Shaka (no DRM / no AES-128).
  4. Wait until playback reaches playing (a few seconds).
  5. Press Back to leave the player screen.

APIs / components involved:

  • @amazon-devices/kepler-player-client / @amazon-devices/kepler-player-server (headless)
  • @amazon-devices/react-native-w3cmedia VideoPlayer
  • Teardown via IPlayerClient.unloadSync → server handleUnloadSyncVideoPlayer.deinitializeSync / deinitialize

3. Observed Behavior

  • After Back, logs show unload / Shaka unload / surface clear, then deinitializeSync / deinitializeAsync.
  • Process aborts with native SIGABRT; app logs stop mid-deinit.
  • A new process starts shortly after (KeplerApplication::init).
  • ACR GDB symbolication stops at:

raise() → abort() → std::terminate()

Backtrace stopped: previous frame identical to this frame (corrupt stack?)

  • ACR has FullUnwind: false; unwind does not continue past std::terminate / libkeplerscript-runtime-loader.

4. Expected Behavior

Back should finish media teardown and return to the previous screen without killing the process. VideoPlayer deinitialize / unloadSync should complete for clear HLS.

4.a Possible Root Cause & Temporary Workaround

Suspected: Uncaught C++ exception / abort inside Amazon native media teardown (VideoPlayer.deinitialize*) on some OS/device builds when exiting HLS. Similar crash site to the community report for AES-128 HLS deinit; our content is clear HLS (empty DRM scheme / license URI). Same API, not confirmed same root cause.

Tried:

  1. Call unloadSync while the surface is still mounted (before navigate/unmount); serialize unload; guard against double unload — still crashed on the affected device.
  2. Soft unload (skip deinitialize*): pause/mute + Shaka unload + clearSurface — avoids the abort on Back on the affected device, but then second playback can fail (HW decoder / caps negotiation), so that is only a partial workaround.

5. Logs or crash report

Attach:

6. Environment

SDK Version: [paste vega --version]
Relevant deps (approx.):

  • @amazon-devices/react-native-w3cmedia: ^2.2.21
  • @amazon-devices/kepler-player-client / kepler-player-server: ^2.2.11
  • @amazon-devices/react-native-kepler: ^2.0.9000000000

App State: Foreground (active / foreground activities true in ACR)

OS Information (affected device at crash):

NAME=“OS”
OE_VERSION=“4.0.0”
OS_MAJOR_VERSION=“1”
OS_MINOR_VERSION=“2”
RELEASE_ID=“21”
OS_VERSION=“1.2”
BRANCH_CODE=“TV Ship”
BUILD_DESC=“OS 1.2 (TV Ship/547)”
BUILD_FINGERPRINT=“4.0.378951.0(3072cab629675a74)/547N:user/release-keys”
BUILD_VARIANT=“user”
BUILD_TAGS=“release-keys”
VERSION_NUMBER=“2101020054720”

Device: Callie, armhf / armv7
Note: Same app build does not crash on another Callie in our lab (different stick / possibly different OS image).

a stick where it is working is:

NAME=“OS”
OE_VERSION=“4.0.0”
OS_MAJOR_VERSION=“1”
OS_MINOR_VERSION=“1”
RELEASE_ID=“14”
OS_VERSION=“1.1”
BRANCH_CODE=“TV Ship day60”
BUILD_DESC=“OS 1.1 (TV Ship day60/99)”
BUILD_FINGERPRINT=“4.0.227617.0(3072cab629675a74)/99N:user-external/release-keys”
BUILD_VARIANT=“user-external”
BUILD_TAGS=“release-keys”
BUILD_DATE=“Tue Feb 17 22:57:51 UTC 2026”
BUILD_TIMESTAMP=“1771369071”
VERSION_NUMBER=“1401010009950”

Reproduces on one Callie; does not on another Callie in our lab on OS 1.1. The affected device also reproduced on OS 1.1 before updating to OS 1.2 (VERSION_NUMBER=2101020054720 / BUILD_FINGERPRINT=…/547N:user/…). So this does not appear limited to the 1.2 image alone.

7. Example Code Snippet

Simplified headless teardown:

// UI (Back): sync unload while surface may still be mounted
client.unloadSync(5000, sessionId);

// Headless handler
handleUnloadSync(timeoutMsec) {
// pause/mute → player unload → clearSurfaceHandle
// → VideoPlayer.deinitializeSync(timeoutMsec) // crash observed here

}

Playback uses Shaka attached to a headless VideoPlayer, not in-UI MSE.

:backhand_index_pointing_right: Playback Issues

Clear HLS (m3u8). Architecture: armv7.

Player SDK: Shaka Player (Vega compiled bundle)
Player SDK Version: 4.8.5
Audio Codecs: AAC (AC-3 on some streams)
Video Codecs: H.264
Manifest Types: m3u8

Q: media/content url
Private / dynamically issued stream URL — can share a redacted sample or private link with Amazon on request.

Q: special headers?
No DRM license headers.

:backhand_index_pointing_right: Additional Context

  • 3P GDB symbolication of the ACR always ends at std::terminate() with incomplete unwind (FullUnwind: false).
  • Soft-unload without deinitialize* avoids the abort but breaks reliable second start (decoder / caps). Looking for guidance on a safe teardown that neither aborts nor leaves the HW decoder unusable.
  • Happy to provide additional ACRs and paired loggingctl captures.

Hi @Jon_Page,

Thank you for the detailed bug report on the SIGABRT crash during VideoPlayer deinitialize.

Our team is investigating this issue and will provide an update as soon as we have more information.

We’ve reviewed the ACR - the crash signature (raise() → abort() → std::terminate() in the native media teardown path) is consistent with an uncaught C++ exception during VideoPlayer.deinitializeSync. The FullUnwind: false confirms the stack corruption you mentioned.

A few questions:

  1. You mentioned one Callie reproduces but another doesn’t - can you confirm the exact VERSION_NUMBER on the non-reproducing stick? (You listed OS 1.1 with 1401010009950 - is that still current on that device?)
  2. Does the crash happen on first playback after app launch, or only after multiple play/back cycles?
  3. When you tried the soft-unload workaround (pause/mute + Shaka unload + clearSurface, skip deinitialize), was the second playback failure immediate or intermittent?

We’d also appreciate the additional ACRs and paired loggingctl captures you offered - those would help us isolate whether this is a timing/race condition in the native teardown.

References:

Thanks for helping us improve the Vega platform.

Warm regards,
Aishwarya

1. Non-reproducing stick VERSION_NUMBER

We cannot produce on 2 different Callie sticks running VERSION_NUMBER=1401010009950 and 1401010445450 (both show as up to date btw)

(OS 1.1 / RELEASE_ID 14 / BUILD_FINGERPRINT=4.0.227617.0(3072cab629675a74)/99N:user-external/release-keys)

Note: the reproducing stick previously hit this on OS 1.1 as well, before it was updated to OS 1.2 (2101020054720), so the split is not “1.2-only.”

2. First playback vs multiple play/Back cycles

Observed on a captured crash log: after playback reached playing, a single Back entered unloadSync > VideoPlayer.deinitializeSync / deinitializeAsync and the process died / relaunched.

So it is not only after many play/Back cycles - one play > Back after playing is enough.

In that same process there was an earlier successful deinitialize ~1 minute before, so we cannot claim it is strictly “first playback after cold launch” for every repro. We have not needed a long multi-cycle sequence to hit it. 9/10 times it will crash on the first back.

3. Soft-unload workaround - second playback failure (diagnostic only, not a shipping mitigation)

To locate the abort, we ran a diagnostic build that still did pause/mute + Shaka unload + clearSurface on Back, but intentionally skipped VideoPlayer.deinitialize* / deinitializeSync.

Result: the SIGABRT stopped. Same exit path otherwise; only omitting deinitialize* avoided process death.

That is not a product workaround we consider acceptable (it leaves teardown incomplete / native player state unclean, and next playback in-process is unreliable). We share it only as evidence that the abort is tied to the deinitialize* path, not to our app-level unload/surface clear steps.

Hi @Jon_Page,

The ACR alone isn’t sufficient for this SIGABRT - we need full device logs captured during the crash.

Could you please provide:

  1. loggingctl capture covering the crash (start → reproduce → stop → export)
  2. Timestamp of when you pressed Back
  3. 2–3 captures if possible (given your 9/10 repro rate)
  4. One successful teardown capture (from the non-reproducing stick or the rare success) for comparison

Thanks,
Aishwarya

Here are 5 logs, 3 crashes, 2 non-crashes. These are from a brand new retail Callie (4k Select) stick.

vega-crash2.log (2.0 MB)

vega-no-crash.log (1.2 MB)

vega-crash1.log (1.2 MB)

vega-crash.log (1.2 MB)

vega-no-crash1.log (1.1 MB)

Logs have [VideoPlayerScreen - handleBackPress] logged when back is pressed to exit the player