简体   繁体   English

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

I am working on a Desktop (Windows 7) based application and using Qt Creator v 5.6.0 for development of the Program. 我正在基于桌面(Windows 7)的应用程序上工作,并使用Qt Creator v 5.6.0开发本程序。 I have a very strange issue ie 我有一个很奇怪的问题,即

  1. My Program crashes in DEBUG mode but works fine in RELEASE mode. 我的程序在DEBUG模式下崩溃,但在RELEASE模式下运行良好。

  2. If in DEBUG mode, and I put break points to find the reason of the crash, then it doesn't crash: It work properly. 如果处于调试模式,并且我放置了断点以查找崩溃的原因,那么它不会崩溃:它可以正常工作。 But if I do not put any break points then it crashes at below code: 但是,如果我不放置任何断点,则会在下面的代码中崩溃:

Project Background: My Project includes functionality to read from the device connected at System communication port and transmits data to the MainWindow UI to display. 项目背景:“我的项目”具有以下功能:从系统通信端口上连接的设备读取数据,并将数据传输到MainWindow UI进行显示。 Since to communicate with the communication port we have to use the third party library so I am not using QtSerial Port class which is much simpler and easy to use. 由于要与通信端口进行通信,我们必须使用第三方库,因此我不使用QtSerial Port类,该类更加简单易用。

Code Design: Class MainClass : In this class we have created some forms to display the data read from the device. 代码设计:类MainClass:在此类中,我们创建了一些表格来显示从设备读取的数据。

Class TestClass: This class will handle all the communication with the device connected at the system Serial Port and use the third party library. 类TestClass:此类将处理与系统串行端口上连接的设备的所有通信,并使用第三方库。 This class also have the while loop to read data from the device connected at Serial Port. 此类还具有while循环,可从串行端口连接的设备读取数据。

Since Test Class is using while loop. 由于测试类正在使用while循环。 So we decided to make a Test Class run in different Thread. 因此,我们决定使Test Class在不同的线程中运行。

Code for creating Thread in MainClass Constructor: 在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)));
    }

}

Crash Code: 崩溃代码:

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)
    {
             ......................
             ......................
    }
}

Here, I added some qDebug() and found that my code crashes when it returns from or call the func1() which is getting called in slot OpenPort(). 在这里,我添加了一些qDebug(),发现我的代码在从插槽OpenPort()中调用或调用func1()返回时崩溃。 Below is the prototype of the func1() 下面是func1()的原型

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

Since, func1() is the part of the library code. 由于func1()是库代码的一部分。 So I can not check the defination of the function func1(). 因此,我无法检查功能func1()的定义。 I can assure that there is no problem in func1() Since it is being used in different java based projects and it works. 我可以确保func1()中没有问题,因为它已在基于Java的不同项目中使用,并且可以正常工作。

I did some more debugging on the Project and noticed that when in Run in DEBUG Mode with BreakPoints than in the QT Thread Debug Window I can see my connected Slot but when I do not put any breakPoint than my code crashes and in Qt Thread Debug Window I can not see my connected Slot 我在项目上进行了更多的调试,发现在带有BreakPoints的DEBUG模式下运行时,与在QT Thread Debug窗口中相比,我可以看到连接的插槽,但是当我没有放置任何BreakPoint时,我的代码就会崩溃并在Qt Thread Debug窗口中我看不到连接的插槽

So, It looks the problem of connection between the Main Class and the Test Class for openPort Slot. 因此,它看起来是openPort插槽的主类和测试类之间的连接问题。

But I am not able to understand taht when i put breakpoints in operPort() function than I can see my openPort Slot in Qt Thread Debug window but when no breakpoints than openPort Slot is not visible in Qt Thread Debug Window and Program Crashes. 但是当我在operPort()函数中设置断点时,我无法理解,而不是在Qt Thread Debug窗口中看到openPort Slot,但是在Qt Thread Debug Window和Program Crashs中看不到openPort Slot断点的情况。

Kindly Suggest, 请建议,

I can assure that there is no problem in func1() Since it is being used in different java based projects and it works. 我可以确保func1()中没有问题,因为它已在基于Java的不同项目中使用,并且可以正常工作。

Wait, is func1() C++ or Java ? 等一下,func1()是C ++还是Java?
Also, how can you be sure it works ? 另外,您如何确定它有效?
Get the library source, compile it yourself, and debug in it. 获取库源代码,自己编译,然后在其中调试。
And, just to be sure, check values of your variables while debugging, and qDebug() them when not debugging 并且,请确保在调试时检查变量的值,并在不进行调试时检查它们的qDebug()

I apologise for replying on my own post but after lots of dicussion on StackOverflow and google. 很抱歉在我自己的帖子上进行回复,但是在对StackOverflow和Google进行了多次讨论之后。 I was able to solve the Issue. 我能够解决问题。

To Solve the Issue: I changed the SLOT(openPort) as mentioned below: 解决此问题:我如下所述更改了SLOT(openPort):

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

That is to use the "Qt:DirectConnection" method. 那就是使用“ Qt:DirectConnection”方法。 If we don't specify a connection method, the direct method is automatically used for connections between objects on the SAME thread. 如果我们未指定连接方法,则直接方法将自动用于SAME线程上的对象之间的连接。 Since here we have created a new QThread for TestClass and using a thirdParty library which might not be a thread safe. 从这里开始,我们为TestClass创建了一个新的QThread并使用了thirdParty库,该库可能不是线程安全的。 So using "Qt::DirectConnection" make the openPort() SlOT to run in MainClass Thread. 因此,使用“ Qt :: DirectConnection”使openPort()SlOT在MainClass Thread中运行。 Basically, it's as if emitting the signal calls the slot method "directly". 基本上,就像发出信号一样,直接调用slot方法。

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

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