Skip to content

fix qtfred heap corruption in FastDebug builds#7450

Merged
wookieejedi merged 1 commit into
scp-fs2open:masterfrom
Goober5000:fix/qtfred_fastdebug
May 12, 2026
Merged

fix qtfred heap corruption in FastDebug builds#7450
wookieejedi merged 1 commit into
scp-fs2open:masterfrom
Goober5000:fix/qtfred_fastdebug

Conversation

@Goober5000
Copy link
Copy Markdown
Contributor

FastDebug FSO compiled with /MDd (debug CRT) but imported Qt's Release libraries via CMAKE_MAP_IMPORTED_CONFIG_FASTDEBUG = Release Debug. Qt Release ships /MD, so any allocation crossing the qtfred <-> Qt boundary went into one heap and came back out of the other, tripping _CrtIsValidHeapPointer on a perfectly-valid std::string dtor. Latent for ages because it only surfaces when an allocation actually crosses; opening a mission file is one such path.

To paper over the resulting STL layout difference, FastDebug also forced _ITERATOR_DEBUG_LEVEL=0 so qtfred's std::string matched Release Qt's. Not needed once we link Debug Qt, and keeping it would introduce a fresh mismatch (qtfred IDL=0 vs Debug Qt IDL=2).

Fix:

  • Map FastDebug imports to "Debug Release """ in qtfred/CMakeLists. Debug picks Qt's debug libs; Release is a defensive fallback; the empty entry falls back to plain IMPORTED_LOCATION, required because Qt's host tools (uic/moc/rcc/qhelpgenerator) ship a single variant with no IMPORTED_LOCATION_. Must precede find_package(Qt5): CMake snapshots the variable into each target's MAP_IMPORTED_CONFIG property at creation time. (Also why the prior "Release Debug" was silently a no-op -- set after find_package, ignored; CMake fell back to Release on its own.)
  • Extend the qwindows/qsqlite plugin POST_BUILD copies' "d"-suffix generator expression to match FastDebug as well as Debug, so the Debug Qt runtime finds qwindowsd.dll / qsqlited.dll alongside.
  • Drop the FastDebug-only _ITERATOR_DEBUG_LEVEL=0 from the MSVC toolchain file. Qt was the sole consumer; pure-C deps don't care.

Cost: FastDebug STL containers pick up MSVC's debug-iterator overhead. Reasonable trade for a config named "Debug with optimizations".

FastDebug FSO compiled with /MDd (debug CRT) but imported Qt's Release
libraries via CMAKE_MAP_IMPORTED_CONFIG_FASTDEBUG = Release Debug. Qt
Release ships /MD, so any allocation crossing the qtfred <-> Qt boundary
went into one heap and came back out of the other, tripping
_CrtIsValidHeapPointer on a perfectly-valid std::string dtor. Latent for
ages because it only surfaces when an allocation actually crosses;
opening a mission file is one such path.

To paper over the resulting STL layout difference, FastDebug also forced
_ITERATOR_DEBUG_LEVEL=0 so qtfred's std::string matched Release Qt's.
Not needed once we link Debug Qt, and keeping it would introduce a fresh
mismatch (qtfred IDL=0 vs Debug Qt IDL=2).

Fix:
  - Map FastDebug imports to "Debug Release \"\"" in qtfred/CMakeLists.
    Debug picks Qt's debug libs; Release is a defensive fallback; the
    empty entry falls back to plain IMPORTED_LOCATION, required because
    Qt's host tools (uic/moc/rcc/qhelpgenerator) ship a single variant
    with no IMPORTED_LOCATION_<CONFIG>. Must precede find_package(Qt5):
    CMake snapshots the variable into each target's MAP_IMPORTED_CONFIG
    property at creation time. (Also why the prior "Release Debug" was
    silently a no-op -- set after find_package, ignored; CMake fell
    back to Release on its own.)
  - Extend the qwindows/qsqlite plugin POST_BUILD copies' "d"-suffix
    generator expression to match FastDebug as well as Debug, so the
    Debug Qt runtime finds qwindowsd.dll / qsqlited.dll alongside.
  - Drop the FastDebug-only _ITERATOR_DEBUG_LEVEL=0 from the MSVC
    toolchain file. Qt was the sole consumer; pure-C deps don't care.

Cost: FastDebug STL containers pick up MSVC's debug-iterator overhead.
Reasonable trade for a config named "Debug with optimizations".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Goober5000 Goober5000 added fix A fix for bugs, not-a-bugs, and/or regressions. qtfred A feature or issue related to qtFred. build An issue related to the build systems labels May 11, 2026
@github-project-automation github-project-automation Bot moved this to Work In Progress (PRs) in qtFRED2 May 11, 2026
@github-project-automation github-project-automation Bot moved this from Work In Progress (PRs) to In Review (PRs) in qtFRED2 May 11, 2026
Copy link
Copy Markdown
Contributor

@TheForce172 TheForce172 left a comment

Choose a reason for hiding this comment

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

LGTM

@wookieejedi wookieejedi merged commit 1a34123 into scp-fs2open:master May 12, 2026
20 checks passed
@github-project-automation github-project-automation Bot moved this from In Review (PRs) to Done in qtFRED2 May 12, 2026
@Goober5000 Goober5000 deleted the fix/qtfred_fastdebug branch May 12, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build An issue related to the build systems fix A fix for bugs, not-a-bugs, and/or regressions. qtfred A feature or issue related to qtFred.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants