更新CLion与MinGW后Qt6应用eventFilter触发SIGILL非法指令错误
CLion更新MinGW工具链后Qt6应用eventFilter触发SIGILL错误
在CLion中使用CMake构建Qt6应用,此前运行完全正常。更新CLion及其捆绑的完整MinGW工具链后,应用开始抛出SIGILL错误,经排查该错误触发于所有eventFilter函数中。
GDB输出信息
[New Thread 2036.0xe58] [New Thread 2036.0x3be8] [New Thread 2036.0x1f40] [New Thread 2036.0x28e8] [New Thread 2036.0x1f04] Thread 1 hit Breakpoint 1, PermanentInventory::PermanentInventory (this=0xdd3da0, parent=0x0) at C:/Users/mmonfort/DEV-SPACE/prigo-economat/client/prico-economat-client/src/PermanentInventory.cpp:16 16 _ui->setupUi(this); The target architecture is set to "auto" (currently "i386:x86-64"). warning: QLayout: Attempting to add QLayout "" to ConsumableInventory "consinventory_tab", which already has a layout [New Thread 2036.0x3150] Thread 1 received signal SIGILL, Illegal instruction. 0x00007ff77d114935 in ConsumableInventory::eventFilter (this=0xe63f30, watched=0xe65ab0, event=0x5ff9e0) at C:/Users/mmonfort/DEV-SPACE/prigo-economat/client/prico-economat-client/src/ConsumableInventory.cpp:50 50 search();
回溯信息
#0 0x00007ff77d114935 in ConsumableInventory::eventFilter (this=0xe63f30, watched=0xe65ab0, event=0x5ff9e0) at C:/Users/mmonfort/DEV-SPACE/prigo-economat/client/prico-economat-client/src/ConsumableInventory.cpp:50 #1 0x00007ff9b670f698 in QCoreApplicationPrivate::canQuitAutomatically() () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Core.dll #2 0x00007ff987b85055 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #3 0x00007ff9b6710b78 in QCoreApplication::sendEvent(QObject*, QEvent*) () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Core.dll #4 0x00007ff987bc6d8a in QWidget::ensurePolished() const () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #5 0x00007ff987bc6dbb in QWidget::ensurePolished() const () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #6 0x00007ff987bc6dbb in QWidget::ensurePolished() const () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #7 0x00007ff987bc6dbb in QWidget::ensurePolished() const () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #8 0x00007ff987bc6dbb in QWidget::ensurePolished() const () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #9 0x00007ff987bc6dbb in QWidget::ensurePolished() const () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #10 0x00007ff987bc9c3d in QWidgetPrivate::setVisible(bool) () from C:\Users\mmonfort\DEV-SPACE\prigo-economat\client\cmake-build-debug\prico-economat-client\Qt6Widgets.dll #11 0x00007ff77d116a3c in main (argc=1, argv=0xd919f0) at C:/Users/mmonfort/DEV-SPACE/prigo-economat/client/prico-economat-client/src/main.cpp:14 #12 0x00007ff77d111340 in __tmainCRTStartup () #13 0x00007ff77d111146 in mainCRTStartup () #14 0x00007ffa03e07344 in KERNEL32!BaseThreadInitThunk () from C:\Windows\System32\kernel32.dll #15 0x00007ffa05d426b1 in ntdll!RtlUserThreadStart () from C:\Windows\SYSTEM32\ntdll.dll #16 0x0000000000000000 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?)
触发错误的代码
bool PermanentInventory::eventFilter(QObject *watched, QEvent *event) { if(event->type() == QEvent::KeyPress && watched == _ui->perminventory_searchedit){ if(((QKeyEvent*)event)->key() == Qt::Key_Enter ||((QKeyEvent*)event)->key() == Qt::Key_Return){ search(); } } }
反汇编代码(末尾含ud2指令)
PermanentInventory::eventFilter(QObject*, QEvent*): push %rbp mov %rsp,%rbp sub $0x20,%rsp mov %rcx,0x10(%rbp) mov %rdx,0x18(%rbp) mov %r8,0x20(%rbp) mov 0x20(%rbp),%rax mov %rax,%rcx call 0x7ff6ccd16ed0 <QEvent::type() const> cmp $0x6,%eax jne 0x7ff6cccc7ad4 <PermanentInventory::eventFilter(QObject*, QEvent*)+62> mov 0x10(%rbp),%rax mov 0x28(%rax),%rax mov 0x10(%rax),%rax cmp %rax,0x18(%rbp) jne 0x7ff6cccc7ad4 <PermanentInventory::eventFilter(QObject*, QEvent*)+62> mov $0x1,%eax jmp 0x7ff6cccc7ad9 <PermanentInventory::eventFilter(QObject*, QEvent*)+67> mov $0x0,%eax test %al,%al je 0x7ff6cccc7b1f <PermanentInventory::eventFilter(QObject*, QEvent*)+137> mov 0x20(%rbp),%rax mov %rax,%rcx call 0x7ff6ccd18540 <QKeyEvent::key() const> cmp $0x1000005,%eax je 0x7ff6cccc7b03 <PermanentInventory::eventFilter(QObject*, QEvent*)+109> mov 0x20(%rbp),%rax mov %rax,%rcx call 0x7ff6ccd18540 <QKeyEvent::key() const> cmp $0x1000004,%eax jne 0x7ff6cccc7b0a <PermanentInventory::eventFilter(QObject*, QEvent*)+116> mov $0x1,%eax jmp 0x7ff6cccc7b0f <PermanentInventory::eventFilter(QObject*, QEvent*)+121> mov $0x0,%eax test %al,%al je 0x7ff6cccc7b1f <PermanentInventory::eventFilter(QObject*, QEvent*)+137> mov 0x10(%rbp),%rax mov %rax,%rcx call 0x7ff6cccc83dc <PermanentInventory::search()> ud2
问题原因与解决方法
原因
反汇编末尾的ud2是编译器插入的非法指令,用于标记未定义行为。问题出在eventFilter函数:该函数声明返回bool类型,但代码中没有任何return语句。更新后的MinGW工具链(GCC版本升级)启用了更严格的编译检查,针对这种未返回值的函数插入了ud2指令,导致运行时触发SIGILL错误。
解决方法
修改eventFilter函数,添加符合Qt要求的返回值:
- 如果需要拦截事件,返回
true; - 如果需要让事件继续传递,返回
false。
示例修改后的代码:
bool PermanentInventory::eventFilter(QObject *watched, QEvent *event) { if(event->type() == QEvent::KeyPress && watched == _ui->perminventory_searchedit){ if(((QKeyEvent*)event)->key() == Qt::Key_Enter ||((QKeyEvent*)event)->key() == Qt::Key_Return){ search(); // 根据需求选择返回true或false return false; } } // 默认返回false,允许事件继续传递 return false; }
内容的提问来源于stack exchange,提问作者Mathieu Monfort
相关产品推荐
相关产品推荐

