简体   繁体   English

自定义QDialog在exec()上导致段错误

[英]Custom QDialog causes segfault upon exec()

I have a program that essentially consists of a central QMainWindow and a member QToolbar pointer. 我有一个基本上由中央QMainWindow和成员QToolbar指针组成的程序。

One action on this toolbar has its triggered signal connected to a ShowNodeEditBox() slot, which instantiates and attempts to exec a custom QDialog -derived widget: 该工具栏上的一个动作将其triggered信号连接到ShowNodeEditBox()插槽,该插槽实例化并尝试执行自定义QDialog派生的小部件:

 void
 Toolbar::ShowNodeEditBox(){
   ...
   //Side note: The custom box stores a pointer to a custom QGLWidget on the main window
   NodeEditBox nodeEdit(this, m_mainWindow->GetGLScene());
   nodeEdit.exec(); 
 }

For some reason, calling exec causes a segfault, even though just constructing the window without it works just fine. 由于某种原因,即使仅在没有窗口的情况下构建窗口也能正常工作,但调用exec会导致段错误。 The stack trace is as follows: 堆栈跟踪如下:

#0  0x0000000000000000 in ?? ()
#1  0x00000030922e64ff in ?? () from /usr/lib64/libQtGui.so.4
#2  0x00000030922e795a in QPainter::QPainter(QPaintDevice*) () from /usr/lib64/libQtGui.so.4
#3  0x00000030921fd7af in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib64/libQtGui.so.4
#4  0x00000030923a0675 in ?? () from /usr/lib64/libQtGui.so.4
#5  0x00000030923a09c9 in ?? () from /usr/lib64/libQtGui.so.4
#6  0x00000030922162da in ?? () from /usr/lib64/libQtGui.so.4
#7  0x00000030922213e7 in QApplication::x11ProcessEvent(_XEvent*) () from /usr/lib64/libQtGui.so.4
#8  0x0000003092249da2 in ?? () from /usr/lib64/libQtGui.so.4
#9  0x00007ffff7410f0e in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#10 0x00007ffff7414938 in ?? () from /lib64/libglib-2.0.so.0
#11 0x00007ffff7414a3a in g_main_context_iteration () from /lib64/libglib-2.0.so.0
#12 0x0000003091b7d5f3 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#13 0x0000003092249a6e in ?? () from /usr/lib64/libQtGui.so.4
#14 0x0000003091b56722 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#15 0x0000003091b569ec in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#16 0x000000309262aaae in QDialog::exec() () from /usr/lib64/libQtGui.so.4
#17 0x000000000045d9e8 in RoadmapOptions::ShowNodeEditBox (this=0xce5da0) at GUI/RoadmapOptions.cpp:562
#18 0x0000000000486f32 in RoadmapOptions::qt_metacall (this=0xce5da0, _c=QMetaObject::InvokeMetaMethod, _id=12, _a=0x7fffffffc740)
    at GUI/MOC/moc_RoadmapOptions.cpp:114

Something is definitely up here, since I see an 0x0, but I haven't been able to figure it out. 自从我看到一个0x0以来,这里肯定有东西,但是我一直无法弄清楚。 The construction of the NodeEditBox itself is quite intricate (lots of sliders, labels, etc. all over the place), so I tried clearing it all off and just calling exec on an empty custom box, constructed like this: NodeEditBox本身的构造非常复杂( NodeEditBox很多滑块,标签等),因此我尝试将其清除,仅在一个空的自定义框中调用exec,如下所示:

NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene){ /* nothing! */ }

Lo and behold (and perhaps thankfully, since it's a really complicated widget), this causes the exact same segfault! 瞧瞧(也许是幸运的,因为它是一个非常复杂的小部件),这会导致完全相同的段错误! I also tried making a pointer to a NodeEditBox with new rather than just instantiating it, as well as making the NodeEditBox a pointer member of the toolbar class and constructing it earlier (thus, only doing exec in ShowNodeEditBox() . And the parent and GLWidget scene pointers are already created, accounted for, and robust, as far as I know. But I still get the same problem every time. 我也试着做一个指向NodeEditBoxnew ,而不是仅仅将其实例化,以及使NodeEditBox工具栏类的指针成员和早期建造它(因此,只有在做execShowNodeEditBox()而家长和GLWidget据我所知,场景指针已经创建,说明并稳定了,但是每次我仍然遇到相同的问题。

What am I missing here? 我在这里想念什么?

**Other info/edit: Using a regular, empty QDialog and popping it up instead of the custom version works just fine. **其他信息/编辑:使用常规的空QDialog并弹出它而不是自定义版本,就可以了。 So maybe it's a parent-related thing. 所以也许这是与父母有关的事情。

Even more interestingly, deriving NodeEditBox from QWidget instead of QDialog works just fine and does not crash! 更有趣的是,从QWidget而不是QDialog派生NodeEditBox可以正常工作,并且不会崩溃! I wanted to use QDialog , though, so that I could call exec. 我想使用QDialog ,以便可以调用exec. show doesn't seem to work unless the NodeEditBox is a member of the toolbar class, which I didn't want because I need multiple, 'disposable' node edit boxes to pop up at different times... 除非NodeEditBox是工具栏类的成员,否则show似乎无法正常工作,我不希望这样,因为我需要在不同时间弹出多个“一次性”节点编辑框...

Should be 应该

NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene)
: QDialog(parent)
{ /* nothing! */ }

instead of 代替

NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene){ /* nothing! */ }
  • you need to pass through input arguments, otehrwise default ctor is called for unbderlying widget, with 0 parent. 您需要传递输入参数,对于不带装饰的部件,将使用otehrwise默认ctor,其父级为0。 Not 100% sure if this causes segfault, but it is definitely error prone. 不能100%确定这是否会导致段错误,但是绝对容易出错。

I don't think there is enough information here to solve this, so here is what I would do to narrow it down: 我认为这里没有足够的信息来解决此问题,因此,我将采取以下措施来缩小范围:

  1. Make sure you can reproduce this crash from a squeaky clean build (ie make clean , etc). 确保您可以从吱吱作响的干净构建中重现此崩溃(例如make clean等)。 Sometimes "mysterious" crashes can be caused by an unclean build (outdated objects/moc files, etc). 有时,“神秘的”崩溃可能是由不干净的版本(过时的对象/ MOC文件等)引起的。

  2. Start with a trivial version of NodeEditBox and work towards the crash. 从一个简单的NodeEditBox版本开始,朝着崩溃的方向努力。 You already stubbed out the constructor - do the same with all other methods and members. 您已经排除了构造函数-对所有其他方法和成员执行相同的操作。 Comment them all out, and then put them back in piece by piece to find the minimal version that makes it crash. 将它们全部注释掉,然后将它们逐段放回去,以找到使其崩溃的最低版本。 Maybe post that minimal version, if it still does not make sense to you. 如果对您来说仍然没有意义,则可以发布该最低版本。

  3. Don't get side-tracked with alternative implementations - the code you presented looks ok - you should be able to get it to work. 不要被替代的实现所困扰-您提供的代码看起来还不错-您应该能够使其正常工作。 The cause of the crash must be in the code you didn't show here. 崩溃的原因必须在您未在此处显示的代码中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM