An Unknown Segfault
-
Hello,
I'm creating an application that is used to scan MTG Cards in real-time from 4 or more cameras, and output the nameplate list of each camera to a per-camera-window, which can then be captured in a streaming platform like OBS. It is in early stage and the actual detection/processing is not yet implemented, partially because of this segfault. It uses Qt, tbb queues and `tbb::flow::graph.
How the project flow works? (In context of this problem)
The project uses a customChannelWizarddialog component that involves 3 steps. Step 1 lets you select a camera, it has a combo box and a live preview below that. First thought would be, to just useVideoOutput,MediaCaptureSession,MediaDevicesandCameraQML types for the wizard camera selection. But when the wizard closes, we have to add the channel to theEngineand now you've to destroy theCameraandMediaCaptureSession, because they still hold the camera handle. Back then, I would initialize theQCameraandQMediaCaptureSessionin a per-camera capture thread, calledCameraMetrics(which lived in the main thread) methods from thetbb::flow::graphnodes and lot more synchronizarion problems. Now, we ask the engine (from QML) to provide us aChannel(custom type holding per-camera half-components, includingQCameraandQMediaCaptureSession) object, owned by C++ and use it to display the preview, pass it back to C++ if channel is to be created or destroy it, if canceled.Channelis used for the main thread andChannelRawis used by the EngineWorker thread, as it holds the supposedly thread safe components. Both are connected by main thread giving frames, and worker thread giving metricsQAtomicInts.The problem
Before, if there were no channels, you add one, and launch the wizard again, it would not show anything in the preview (Cameraprobably fails silently) for the same camera. You close the app, let it save the channel configurations, launch it again, a simple click on theAdd Channelbutton causes a segfault.Now, with the QtMultimedia moved to the main thread, I sometimes, get it at the start, or clicking a channel, or Add Channel. Disabling
ChannelWizardsometimes work. I can't debug it. It produces this call stack almost always: After some more tinkering, disablingDashboarddoesn't cause it either.Call Stack
1 QV4::Heap::Base::mark qv4heap_p.h 147 0x7ffff6cda402 2 QV4::Managed::mark qv4managed_p.h 178 0x7ffff6cda402 3 QV4::MemoryManager::collectFromJSStack qv4mm.cpp 1474 0x7ffff6cda402 4 QV4::(anonymous namespace)::markJSStack unique_ptr.h 173 0x7ffff6cda51b 5 QV4::GCStateMachine::transition qv4mm.cpp 1567 0x7ffff6cdacb7 6 QV4::GCStateMachine::step qv4mm_p.h 89 0x7ffff6cdbd55 7 QV4::MemoryManager::runGC qv4mm.cpp 1289 0x7ffff6cdbd55 8 QV4::MemoryManager::allocate qv4mm_p.h 409 0x7ffff6cdeae4 9 QV4::MemoryManager::allocData qv4mm.cpp 1011 0x7ffff6cdeae4 10 QV4::MemoryManager::allocManaged<QV4::CallContext> qv4mm_p.h 215 0x7ffff6bbc5c6 11 QV4::ExecutionContext::newCallContext qv4context.cpp 74 0x7ffff6bbc5c6 12 QV4::Runtime::PushCallContext::call qv4runtime.cpp 1758 0x7ffff6c84ebd 13 QV4::Moth::VME::interpret qv4vme_moth.cpp 926 0x7ffff6cd0344 14 QV4::Moth::VME::exec qv4vme_moth.cpp 493 0x7ffff6cd65e3 15 QV4::doCall qv4function.cpp 53 0x7ffff6c09a8a 16 QV4::Function::call qv4function.cpp 78 0x7ffff6c09d21 17 QQmlJavaScriptExpression::evaluate qqmljavascriptexpression.cpp 238 0x7ffff6d7f293 18 QQmlBinding::evaluate qqmlbinding.cpp 195 0x7ffff6d0de8d 19 QQmlBinding::doUpdate qqmlbinding.cpp 713 0x7ffff6d0dfa9 20 QQmlBinding::update qqmlbinding.cpp 165 0x7ffff6d117b2 21 QPropertyObserverPointer::notify qproperty_p.h 916 0x7ffff4c2e1af 22 QObjectCompatProperty<QQuickItemPrivate, double, &QQuickItemPrivate::_qt_property_height_offset, &QQuickItemPrivate::setHeight, &QQuickItemPrivate::heightChanged, decltype(nullptr)>::notify qproperty_p.h 671 0x7ffff4c2e1af 23 QQuickItem::geometryChange qquickitem.cpp 3921 0x7ffff4c1aabc 24 QQuickItem::setSize qquickitem.cpp 7790 0x7ffff4c11ff0 25 QQuickControlPrivate::resizeBackground qquickcontrol.cpp 366 0x7ffff5309b1b 26 QQuickControl::geometryChange qquickcontrol.cpp 2134 0x7ffff5313ddd 27 QQuickItem::setSize qquickitem.cpp 7790 0x7ffff4c11ff0 28 QQuickGridLayoutItem::setGeometry qquickgridlayoutengine_p.h 86 0x7fffc3fbf196 29 QGridLayoutEngine::setGeometries qgridlayoutengine.cpp 1060 0x7ffff77acede 30 QQuickGridLayoutBase::rearrange qquicklinearlayout.cpp 479 0x7fffc3fbce66 31 QQuickLayout::geometryChange qquicklayout.cpp 980 0x7fffc3fb953d 32 QQuickItem::setSize qquickitem.cpp 7790 0x7ffff4c11ff0 33 QQuickAnchorsPrivate::setItemSize qquickanchors.cpp 392 0x7ffff4bda0fa 34 QQuickAnchorsPrivate::fillChanged qquickanchors.cpp 168 0x7ffff4bda0fa 35 operator()()The state of the project at the time
https://github.com/ahsanullah-8bit/MTGScanner/tree/d1177115f395cb173632a102a893775e038b2561Google AI Search said, these are the common causes:
- Object Ownership Issues
- Dangling Pointers in Loaders
- Uninitialized C++ Objects
- Module-Specific Bugs
- Lifecycle of argc/argv
How I approached it?
I know the call stack says, the garbage collector is having the segfault. But I looked at my code again and again, tried different LLMs, questions, posts, articles, etc.- I re-wrote most of the threading and engine architecture again.
- Replicated most of the project in another dummy one.
- Tried Local Debuggers (Ubuntu and Windows).
- Tried ASAN
- Tried Valgrind.
- Tried Breakpoints and Tracepoints.
- Tried the old console printing.
- Commenting out parts.
- Blamed my life for a few days, and gave it a break.
it might be a skill issue to not solve the problem after this much debugging.
Platform
Ubuntu 24.04.4 LTS and Windows 11
Qt 6.10.1
GCC 13.3.0 and MSVC 18Last Steps (solution)
- Deleted the local repository and cloned it again.
- Upgraded from Qt 6.10.1 to Qt 6.11.1
Later was probably the main. Because someone on Reddit said they introduced GC fixes in Qt 6.11.
I'm gonna have to test it thoroughly.
-
Seriously? No, reply? It's the same with the Reddit page as well.
Edit: My bad yo, I forgot to remove this reply, after an LLM told me the post is too much. But it's just frustration, you guys would understand better than anyone else.
@AhsanKhan said in An Unknown Segfault:
Seriously? No, reply? It's the same with the Reddit page as well.
The original post is around 196 lines, 985 words, or 23 kilobytes of text, plus links to external resources. That's a lot to ask a forum user to read and understand. There might be a reasonable answer or interesting discussion, if the question is reduced to a more easily digestible level.
-
Seriously? No, reply? It's the same with the Reddit page as well.
Edit: My bad yo, I forgot to remove this reply, after an LLM told me the post is too much. But it's just frustration, you guys would understand better than anyone else.
@AhsanKhan said in An Unknown Segfault:
Seriously? No, reply? It's the same with the Reddit page as well.
We're not here for debugging your app. Please provide a minimal, compilable example to reproduce your problem.
-
Hey, I had a look at your callstack and I think it's more specific than the generic AI answer you got.
The GC crash in QV4::Managed::mark is the effect, not the cause. Something it tries to mark is already dead or corrupt. The interesting part is when it crashes — this happens, for the crash you posted, during componentComplete on startup. So a C++ object exposed to QML is either not fully initialised yet or already destroyed when the first bindings evaluate.
The most obvious thing I noticed: in main.cpp your engine is a stack-allocated object and gets passed to QML as a context property, but I don't see QQmlEngine::setObjectOwnership being set for it. If the QML engine assumes it can manage that object's lifetime, the next GC cycle will try to mark a wrapper around something that's either on the stack or already gone. That alone could explain why the crash is so inconsistent in where it appears.
The other thing worth checking is whether any Q_PROPERTY NOTIFY signal fires before the owning object is fully constructed — the stack shows a topPadding binding via SafeArea::marginsChanged triggering the whole geometry cascade, which suggests a binding is evaluating earlier than expected.
And even with QtMultimedia back on the main thread, if any tbb node captures a raw pointer to a QML-exposed object in a lambda, that's a ticking time bomb once the object moves or gets deleted.
Trying to reproduce it with just ApplicationWindow + ChannelWizard and no tbb/engine code would at least tell you if it's a pure ownership/binding issue or something from the threading side.
-
@AhsanKhan said in An Unknown Segfault:
Seriously? No, reply? It's the same with the Reddit page as well.
The original post is around 196 lines, 985 words, or 23 kilobytes of text, plus links to external resources. That's a lot to ask a forum user to read and understand. There might be a reasonable answer or interesting discussion, if the question is reduced to a more easily digestible level.
-
A AhsanKhan has marked this topic as solved