You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi Rio安卓64位应用External exception XX问题排查咨询

Having dealt with similar Delphi Android 64-bit issues before, let's break down what these External exception XX errors mean and how to troubleshoot them—especially since you're seeing them across all devices and can't replicate the problem locally.

Understanding the External exception XX Errors

These aren't standard Delphi exceptions—they're wrappers for Android native signals that the Delphi runtime converts into exception objects. For context on common codes you're seeing:

  • External exception B0 typically maps to SIGBUS (bus error, often from misaligned memory access or invalid memory addresses)
  • External exception 87 usually corresponds to SIGFPE (floating-point exception, e.g., division by zero or invalid floating-point calculations)
  • External exception 90 is often SIGABRT (abort signal triggered by native code assertions or low-level crashes)

The fact they're popping up in "safe" FMX code like ArrangeControl or TRectF.Offset is a critical clue: the actual root cause is likely memory corruption or invalid state introduced earlier in your code, which only manifests later when FMX tries to perform routine operations.

Likely Root Causes

Based on your call stack (triggered via FormKeyUp → ShowPreviousFrame → Realign → ArrangeControl) and cross-device occurrence, here are the most probable culprits:

  • Memory corruption: Wild pointers, out-of-bounds array access, or freeing objects while they're still referenced can corrupt the heap or stack. This corruption might not trigger an error immediately—it lays in wait until FMX code accesses the damaged memory.
  • Thread safety violations: If background threads modify FMX controls or UI-related data without proper synchronization (using TThread.Synchronize/TThread.Queue), they can leave controls in an invalid state. When the UI thread tries to realign controls (like in ShowPreviousFrame), this invalid state causes a native signal.
  • FMX control lifecycle bugs: Examples include accessing a frame/control after it's been destroyed, or calling EndUpdate/Realign on a form that's in the process of being disposed.
  • Delphi Rio Android 64-bit compiler bugs: Rio (10.3) had several known issues with Android 64-bit, including memory alignment problems in FMX controls and JNI interaction bugs.
  • Third-party component/library issues: Non-standard Delphi components or native Android libraries (via JNI) might not be properly adapted for 64-bit, leading to memory errors.
Troubleshooting Steps

Since you can't replicate locally, focus on logging, memory debugging, and incremental isolation:

1. Enhance Error Context Logging

Your existing exception reporter captures the stack, but you need more context to pinpoint the root cause:

  • Add logs before/after ShowFrame and ShowPreviousFrame that record:
    • The frame being shown/hidden (class name, memory address, and ComponentState)
    • Form bounds and alignment properties (e.g., Self.BoundsRect, Align values of child controls)
    • Thread ID of the executing code (to catch unexpected background thread access)
  • Modify GlobalGetExceptionStackInfo to log additional details like the contents of the TRectF being passed to ArrangeControl (if possible) and any recent UI operations.

2. Enable Memory Debugging Tools

  • Use Android's AddressSanitizer (ASAN): Compile your app with ASAN enabled (in Delphi's project options under Linking → Advanced → Additional linker flags, add -fsanitize=address). ASAN will catch memory leaks, out-of-bounds access, and use-after-free errors in native code, pointing you directly to the source of corruption.
  • Leverage Delphi's memory checks: Enable FastMM4 (or the built-in memory manager's debug mode) to detect invalid memory operations. While FastMM's Android 64-bit support is limited, it can still catch some Delphi-level memory issues.

3. Audit Thread Safety

  • Verify all UI-related operations (frame creation/destruction, form updates, control property changes) run on the main UI thread. Any background thread modifying UI state must use TThread.Synchronize or TThread.Queue.
  • Check if ShowPreviousFrame or ShowFrame is ever called indirectly from a background thread (your call stack shows it's triggered by FormKeyUp (UI thread), but hidden indirect calls could exist).

4. Isolate the Problem Code

  • Simplify frame transitions: Temporarily disable the TShowFrameTransition animation in ShowFrame to rule out animation-related state corruption.
  • Remove third-party components: Gradually disable or remove non-core third-party components (especially those handling UI or memory) and monitor if exceptions stop occurring.
  • Test with a minimal reproducible case: Create a stripped-down version of your app that only includes the MainForm, frame navigation, and key handling. If the exception still occurs, you can narrow down the issue faster.

5. Check Control Lifecycle Management

  • Add logs to your frame's OnCreate and OnDestroy events to ensure frames are properly created and disposed. Look for cases where a frame is destroyed but still referenced in your MainForm.
  • Verify that EndUpdate is always paired with BeginUpdate on your form—unbalanced calls can leave the form in an invalid state that triggers realignment errors.

6. Update Delphi or Apply Patches

Delphi Rio had several critical fixes for Android 64-bit in subsequent patches (e.g., 10.3.3). If you're not running the latest patch for Rio, apply it. Alternatively, test your app in a newer Delphi version (like 10.4 Sydney or 11 Alexandria) to see if the issue is resolved—Embarcadero fixed many FMX memory and alignment bugs in later releases.


内容的提问来源于stack exchange,提问作者zeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:37:32