From ccce91461a39adebde7ec7803b4cc0b97093f77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 30 Apr 2025 15:12:46 +0000 Subject: [PATCH] Revert "iOS: Replace variable length array in event dispatcher with QVarLengthArray" This reverts commit be93c06758260b1e0738ab17a2ecc4ee8f90e87e. The assumption was that using a QVarLengthArray was equivalent to the existing C-style VLA, as we initialized the QVarLengthArray with defaultStackSize as the Prealloc template argument. However we failed to take into account that we adjust the stack size via Stack::computeSize(), by adding space for our memory guard, so we would effectively always end up with the user-main stack on the heap. This caused problems for Qt Quick's V4 engine, because it checks for C++ stack overflow by comparing the current stack pointer to the base and limit given by pthread_get_stackaddr_np and RLIMIT_STACK, resulting in "RangeError: Maximum call stack size exceeded." errors and failure to load the QML. We can't tweak what pthread_get_stackaddr_np reports for an already started thread, so in practice we can not put the user-main stack on the heap, so we revert back to the use of C-style variable length arrays, which should be fine for this specific use-case. Change-Id: I05a4bd32697abee71aa9e70f9f5a011cc338f915 Pick-to: 6.9 6.8 Reviewed-by: Volker Hilsheimer --- src/plugins/platforms/ios/qioseventdispatcher.mm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 675e647bb09..5e4b074c56b 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -188,16 +188,23 @@ extern "C" int qt_main_wrapper(int argc, char *argv[]) s_isQtApplication = true; @autoreleasepool { - constexpr size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads + size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads uint requestedStackSize = qMax(0, infoPlistValue(@"QtRunLoopIntegrationStackSize", defaultStackSize)); if (infoPlistValue(@"QtRunLoopIntegrationDisableSeparateStack", false)) requestedStackSize = 0; - QVarLengthArray reservedStack(Stack::computeSize(requestedStackSize)); - if (reservedStack.size() > 0) { - userMainStack.adopt(reservedStack.data(), reservedStack.size()); + QT_WARNING_PUSH + QT_WARNING_DISABLE_CLANG("-Wunknown-warning-option") + QT_WARNING_DISABLE_CLANG("-Wvla-cxx-extension") + // The user-main stack _must_ live on the stack, so that the stack pointer + // during user-main is within pthread_get_stackaddr_np/pthread_get_stacksize_np. + char reservedStack[Stack::computeSize(requestedStackSize)]; + QT_WARNING_POP + + if (sizeof(reservedStack) > 0) { + userMainStack.adopt(reservedStack, sizeof(reservedStack)); if (infoPlistValue(@"QtRunLoopIntegrationDebugStackUsage", false)) { debugStackUsage = true;