Fix: prevent crash when closing multiple profiles at once

Changes -

  • Audited all uses of QtConcurrent::run and QFutureWatcher throughout the codebase.
  • Refactored all async lambdas and slots that could access deleted QObjects:
    • Used QPointer to safely guard access to any QObject (Host, dialogs, etc.) in lambdas, ensuring the lambda checks if the object is still alive before accessing it.
    • Parent all QFutureWatcher instances to the relevant QObject, so they are auto-deleted if the parent is destroyed.
    • In critical cases, ensured destructors wait for async operations to finish before allowing the object to be destroyed.
  • Applied this robust pattern to all at-risk locations:
    • Profile save operations (Host.cpp)
    • XML export operations (XMLexport.cpp)
    • Package export operations (dlgPackageExporter.cpp)
    • Theme download and unzip operations (dlgProfilePreferences.cpp)
  • Reviewed and updated all related code to ensure no use-after-free or double-free is possible, even under rapid profile closing or shutdown.
  • Confirmed by user feedback and code audit that the crash is no longer reproducible.

How the Bug Was Fixed

  • Root cause: Async operations (like saving profiles or exporting packages) could finish after their parent objects were destroyed, leading to use-after-free crashes.
  • Solution:
    • All async callbacks now use QPointer to check object validity before accessing members.
    • All QFutureWatcher objects are parented to the relevant QObject, ensuring proper cleanup.
    • Destructors wait for async operations to finish if necessary.
  • Result: No more crashes when closing multiple profiles at once, even under heavy or rapid usage. Solves - #7478 /claim #7478

Claim

Total prize pool $100
Total paid $0
Status Pending
Submitted May 24, 2025
Last updated May 24, 2025

Contributors

LU

Luffy

@luffy-orf

100%

Sponsors

MU

Mudlet

@Mudlet

$100