| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 3 | |
Hi everyone. I'm trying to debug a multi-threaded QT application that is displaying some very odd behavior. The application is exiting at points in the code that shouldn't result in the application terminating at all For example, the application would exit when a function called "getDecisionState" was called. The contents of that function were: QMutexLocket locker(&m_lock); Return m_nDecisionState; I had to change the contents of the function for some other reasons, and now the application exits at a completely different place - right now it seems to exit inside a QTcpSocket::waitForReadyRead() call. I'm building against Qt 4.2.2, and linking statically. Has anyone seen anything like this before? There are no compilation warnings, so I'm a bit confused as to how this can happen... any ideas at all? I'm clutching at straws here.. Thanks! -- [ signature omitted ]
On 1/18/08, Thomas Richards <thomas.richards@xxxxxxxxx> wrote: > Has anyone seen anything like this before? There are no compilation > warnings, so I'm a bit confused as to how this can happen... any ideas > at all? I'm clutching at straws here.. One idea on how to debug this is to use strace and see what system calls are being made. It will even let you see how the program is terminating. You could then run it in the debugger and put a break point on the system call it is using to exit so you can examine the state of the running program. Cheers Rich. -- [ signature omitted ]
Thomas Richards wrote: >Hi everyone. > > >I'm trying to debug a multi-threaded QT application that is displaying >some very odd behavior. The application is exiting at points in the code >that shouldn't result in the application terminating at all > >For example, the application would exit when a function called >"getDecisionState" was called. The contents of that function were: > >QMutexLocket locker(&m_lock); >Return m_nDecisionState; > > >I had to change the contents of the function for some other reasons, and >now the application exits at a completely different place - right now it >seems to exit inside a QTcpSocket::waitForReadyRead() call. > >I'm building against Qt 4.2.2, and linking statically. > >Has anyone seen anything like this before? There are no compilation >warnings, so I'm a bit confused as to how this can happen... any ideas >at all? I'm clutching at straws here.. Did you use QThread::terminate() anywhere in your code? We are aware of a Linux kernel bug that causes threads to disappear while terminating. See https://bugzilla.novell.com/show_bug.cgi?id=289641 -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Hello again,
I'd like to re-raise this issue since I have some new information, but
still no resolution. My original problem was:
> >
> >I'm trying to debug a multi-threaded QT application that is
displaying
> >some very odd behavior. The application is exiting at points in the
code
> >that shouldn't result in the application terminating at all
> >
I changed the project settings so I'd get Qt's warning messages on the
console. I notice that this is printed:
QThread: Destroyed while thread is still running
This is obviously the problem - for some reason my thread is being
killed before it's finished. I'm 99.9% certain that I'm not explicitly
killing the thread. In the main thread I connect the thread's finished()
signal to a function of my own, like this:
QObject::connect(this, SIGNAL(killTheseApps(const QStringList&)),
this, SLOT(KillApps(const
QStringList&)),
Qt::QueuedConnection
);
And in that function I double check that the thread is really finished,
before asking the main application to quit:
void ALClient::threadFinished()
{
if (m_thread.isFinished())
{
qApp->quit();
}
}
This is the only class that has access to the thread object.
I've managed to narrow down the condition that leads to the crash. When
the condition (we'll call it 'c') is true, the worker thread asks the
main thread to show a dialog box asking the user how they wish to
proceed. The thread then waits until the dialog box is closed, and reads
the user feedback. Somewhere in the code to do this my QThread is being
terminated.
So, I ask the main thread to show the dialog box by calling a method on
the main thread, the contents of which look like this:
m_lock.lock();
emit killTheseApps(liApps);
m_lock.unlock();
I wasn't sure whether emit calls are thread safe, so I protected the
call with a mutex lock anyway. This signal is connected to another
method using a Qt::QueuedConnecton. The slot looks like this:
CKillAppsDlg dlg(liApps, &m_splashScreen);
switch (dlg.exec())
{
case CKillAppsDlg::RES_ABORT:
m_nDecisionState = STATE_ABORT;
break;
case CKillAppsDlg::RES_CONTINUE_UPDATE:
m_nDecisionState = STATE_CONTINUE;
break;
case CKillAppsDlg::RES_KILL_APPS:
m_nDecisionState = STATE_KILL_APPS;
break;
default:
LogDebugMessage("Ack! unknown decision was made!");
Q_ASSERT(false);
}
m_dlgWaitSignal.wakeAll();
That last line calls wakeAll() on a QWaitCondition. While this has been
going on in the main thread, the worker thread has moved on, and has now
called a method on the main thread called "getDecisionState", the
contents of which look like this:
QMutexLocker locker(&m_lock);
m_dlgWaitSignal.wait(&m_lock);
return m_nDecisionState;
The documentation for QWaitCondition is confusing to me - it seems to
use the same mutex for both the wait condition, and to protect the data
you are trying to access.
...And that's it. The problem *must* occur somewhere in the above code.
I've been looking at this for over a week now, it'd be great if someone
on the list could point me in the right direction! Apart from this minor
niggle, I've enjoyed using Qt very much.
Cheers,
--
[ signature omitted ]
On Friday 18 January 2008 04:30, Thomas Richards wrote: > For example, the application would exit when a function called > "getDecisionState" was called. The contents of that function were: > > QMutexLocket locker(&m_lock); > Return m_nDecisionState; This sounds like the instance owning this veriable does no longer exist. This happens a) if you explicitly delete an object before the last access to it has finished. b) if there is a race condition between two threads, one accessing it, while the other is already deleting it. A nice way of triggering this is calling something like this from a thread that does not own the QObject: myobj->deleteLater(); myobj->dosomething(); This works perfectly well in the thread that owns the object, but leads to random crashes from other threads. Konrad
Attachment:
Attachment:
pgpXpTztu4obL.pgp
Description: PGP signature