Petter Olofsson Petter Olofsson - 12 days ago 7
C++ Question

qtimer crashes when created in constructor or static

So, i have finally found this odd issue that i have found no answer for.

I'm creating a small gui, launching an application in a separate window and then polling the state of this app using a qtimer.

process_timer = new QTimer(this);
connect(process_timer, SIGNAL(timeout()), this, SLOT(checkFlashProcess()));
process_timer->start(100);


So this works. But i would rather not create a new timer every time, so i placed the creation of process_timer in the constructor of the gui:

Flasher::Flasher(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Flasher)
{
ui->setupUi(this);
process_timer = new QTimer(this);
}


Now this leads to a crash and the output:
QObject::connect: Cannot connect (null)::timeout() to Flasher::checkFlashProcess()

Same for this:

Flasher::Flasher(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Flasher),
process_timer(new QTimer)
{...


QTimer *process_timer is defined in the application header.

I have also tried defining process_timer as non dynamic:

header.h:
QTimer process_timer;
code.cpp
void Flasher::on_flashButton_clicked()
{
(...)
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, process_pid );
if(hProcess)
{
qDebug() << "Got handle for process!";
connect(&process_timer, SIGNAL(timeout()), this, SLOT(checkFlashProcess()));
process_timer.start(30);
}


This also leads to a crash.

Callback:

void Flasher::checkFlashProcess()
{
qDebug() << "Got handle for process!";
}


But Why is this? I guess that the timer does not get created in the constructor, but creating objects in the constructor should not be a problem right? And why would the static version crash also, would this be the same issue?

Answer

Ok, so it seems that this was not related to qtimer but rather a memory problem. I was looking around alot for how to get the process handle in windows and mostly found sources about unix. Then between these two I apperently got things mixed up and ended up using a DWORD for the process_pid, which seems to have been placed just before the timer in memory. Thus calling openprocess caused corruption and led to the crash. Creating the timer after starting the application "fixed" this by restoring the timer again.

Another lesson learned, and using a qint64 for pid from qProcess to OpenProcess works fine. Hopefully someone else can find this when looking to do something similar and can avoid the hassle, thanks for kicking me to create a mcve to isolate the issue.