QT Creator:程序在调试模式下崩溃,但在发布模式下工作,在基于QThread的程序的调试模式下有断点

QT Creator : Program crashes in debug mode but working in Release mode and in DEBUG Mode with breakpoints for QThread based program

本文关键字:模式 程序 调试 工作 断点 QThread 崩溃 Creator QT 布模式      更新时间:2023-10-16

我正在开发一个基于桌面(Windows 7)的应用程序,并使用Qt Creator v 5.6.0开发该程序。我有一个很奇怪的问题,即

  1. 我的程序在DEBUG模式下崩溃,但在RELEASE模式下工作正常。

  2. 如果在DEBUG模式下,并且我放置断点来查找崩溃的原因,那么它不会崩溃:它正常工作。但是如果我没有设置任何断点,那么它会在以下代码处崩溃:

项目背景:我的项目包括从系统通信端口连接的设备读取并将数据传输到主窗口UI显示的功能。由于要与通信端口进行通信,我们必须使用第三方库,所以我不使用QtSerial port类,它更简单,更易于使用。

代码设计:在这个类中,我们创建了一些表单来显示从设备读取的数据。

类TestClass:该类将处理与系统串口连接的设备的所有通信,并使用第三方库。这个类也有while循环从连接到串行端口的设备读取数据。

因为测试类使用while循环。所以我们决定让一个测试类在不同的线程中运行。

在MainClass构造函数中创建线程的代码:
MainClass::MainClass (QWidget *parent) : QDialog(parent),
    ui(new Ui::Analzyer)
{
   ............................
   ............................
   workerThread = new QThread;
   testClassObject = new TestClass();   // Declared in HeaderFile of MainClass        
    if((workerThread != NULL) && (testClassObject != NULL))
    {
        workerThread ->moveToThread(testClassObject );
        connect(workerThread , SIGNAL(started()), testClassObject, SLOT(SomeFunc()));
        connect(testClassObject, SIGNAL(exit()), workerThread , SLOT(quit()));
        connect(testClassObject, SIGNAL(exit()), testClassObject,  SLOT(deleteLater()));
        connect(workerThread , SIGNAL(finished()), workerThread , SLOT(deleteLater()));
        // connectToPort Signal is emitted when User clicks the pushbutton from   // Main class UI
        connect(this, SIGNAL(connectToPort(QString)), testClassObject, SLOT(openPort(QString)));
    }
}

崩溃代码:

void TestClass::openPort(const QString portName)
{
    // Here portName is say : "Appliance Interface v2"
    quint32 param2 = getParam2ForPortName(portName);
    qint16 portNumber = 0;
    QByteArray portNameByteArray = portName.toLatin1();
    const char *portNameToOpen = portNameByteArray.data();
     // Program crashed when return from this function
    if(func1(portNameToOpen , param2, 10 , &portNumber) == true)
    {
             ......................
             ......................
    }
}

在这里,我添加了一些qDebug(),并发现我的代码在从或调用func1()返回时崩溃,该函数在slot OpenPort()中被调用。下面是func1()

的原型
bool func1 (const char portDescription[], uInt32 param2,
               uInt16 length, Int16 * portNr);

因为func1()是库代码的一部分。所以我不能检查函数func1()的定义。我可以保证func1()没有问题,因为它被用于不同的基于java的项目,它的工作。

我在项目上做了一些更多的调试,并注意到,当在调试模式下运行断点比在QT线程调试窗口我可以看到我连接的插槽,但当我不把任何断点比我的代码崩溃,在QT线程调试窗口我看不到我连接的插槽

因此,它看起来是openPort Slot的主类和测试类之间的连接问题。

但是我无法理解,当我在operPort()函数中放置断点时,我可以在Qt线程调试窗口中看到我的openPort插槽,但是当没有断点时,openPort插槽在Qt线程调试窗口和程序崩溃中不可见。

请建议,

我可以保证func1()没有问题,因为它被用于不同的基于java的项目,它工作。

等等,func1()是c++还是Java ?
还有,你怎么能确定它能工作呢?
获取库源代码,自己编译,并在其中进行调试。
并且,为了确保,在调试时检查变量的值,在不调试

时使用qDebug()来检查它们。

我很抱歉在我自己的帖子上回复,但在StackOverflow和google上进行了大量讨论之后。我能够解决这个问题。

解决方法:我更改了SLOT(openPort),如下所述:

Connect(this, SIGNAL(connectToPort(QString)), testClassObject, SLOT(openPort(QString)), Qt::DirectConnection); 

即使用"Qt:DirectConnection"方法。如果我们没有指定连接方法,直接方法将自动用于同一线程中对象之间的连接。因为这里我们为TestClass创建了一个新的QThread,并使用了一个可能不是线程安全的thirdParty库。所以使用"Qt::DirectConnection"使openPort()插槽在MainClass线程中运行。基本上,就好像发出信号"直接"调用slot方法。

相关文章: