Slot exception being thrown on exit of Qt app with Pkill
-
Hi,
My Qt application is designed as the child thread of the child process namely UiApp.
When Qt application is being killed with Pkill <UiApp> in the terminal, it throws below error:-Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.I tried the below 2 approaches but unable to find the rootcause.
i) Put a breakpoint in the throw function namely __cxa_throw and Run in the debugger and ask it to stop in any C++ exception thrown (gdb
command "catch throw") with backtrace.
ii)Reimplement QApplication::notify() and catch all exceptions there.Any thoughts in this regard are highly appreciated.
-
@Ramakanth said in Slot exception being thrown on exit of Qt app with Pkill:
My Qt application is designed as the child thread of the child process namely UiApp
What does this mean? Do you start your Qt app from another process? And why do you need to kill it?
-
@Ramakanth What does the backtrace show when it crashes? The error is quite clear. Something is throwing an exception while being inside an event handler.
So you just have to determine what it is and take out the throw, or reimplement the notify function it mentioned in order to catch the exception before it becomes unhandled.
The backtrace should get you right to the function you need to look at to fix the thrown exception.
-
@jsulm Yes UI app is spawned from another process which inturn invokes Qt app as a child thread.
Inorder to Kill the Qt application, Pkill is used on the parent process. The exception indicates it is being thrown in eventhandler but not able to get the rootcause of eventhandler function with backtrace -
@Ramakanth said in Slot exception being thrown on exit of Qt app with Pkill:
process which inturn invokes Qt app as a child thread
You can't invoke an app as thread - an app always runs in its own process.
Maybe you mean that your UI is running in another thread? -
@ambershark I debugged using gdb but it doesnot traces to any exception being thrown even if the app is terminated with pKill..Ideally it should point to the exception when Qt app is being launched with gdb but there are no traces of exception when Qt app is launched.
-
@ambershark I debugged using gdb but it doesnot traces to any exception being thrown even if the app is terminated with pKill..Ideally it should point to the exception when Qt app is being launched with gdb but there are no traces of exception when Qt app is launched.
-
@Ramakanth said in Slot exception being thrown on exit of Qt app with Pkill:
as a child thread
What is a child thread? How do you start the Qt application (code please)? You should not kill threads, nor processes, for no reason at all, close it (whatever it is) gracefully.
-
@Ramakanth said in Slot exception being thrown on exit of Qt app with Pkill:
@ambershark I debugged using gdb but it doesnot traces to any exception being thrown even if the app is terminated with pKill..Ideally it should point to the exception when Qt app is being launched with gdb but there are no traces of exception when Qt app is launched.
Can you share the backtrace? Start your app with gdb, then while it is running kill it (causing the exception) and post the
bt
here.If you are running the GUI in a separate thread and killing that thread you could have issues like these. Like @kshegunov says, it's really bad to kill a thread. More often than not in my experience you end up with a crash if you kill a thread while it's running.
Lastly, you're killing the application, so honestly who really cares if it throws an exception as it dies. It's not the normal execution path, so it's not like you need to fix an exception from a killed process.
-
@ambershark Yes creating the Qt GUI in a thread using pthread_create and killing with pthread_cancel. As SigTerm is handled when Pkill or kill -15 is executed, the cleanup of resources including Qt GUI thread is being done. Ideally this may be abnormal, but would like to see if there is a graceful exit while cleaning up resources in UiApp.
Let me know if you any see issue in creation of Qt GUI thread with pthread or do I need to fallback to QThread or these kind of messages appear with this thread design approach?
Here is the backtrace:
sudo gdb ./UiApp
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
http://bugs.launchpad.net/gdb-linaro/...
Reading symbols from /usr/bin/qt/UiApp...done.
(gdb) catch throw
Catchpoint 1 (throw)
(gdb) run
Starting program: /usr/bin/qt/UiApp
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
[New Thread 0xb7fda740 (LWP 5232)]Program received signal SIGTERM, Terminated.
0xb7fdd424 in __kernel_vsyscall ()
(gdb) backtrace
#0 0xb7fdd424 in __kernel_vsyscall ()
#1 0xb4f6b746 in epoll_wait () at ../sysdeps/unix/syscall-template.S:82
#2 0x08f0ce6d in osFlagsGet (pEventList=0xb45c30f8, reqFlags=1, getOption=1, pActualFlags=0xbffff5cc,
wait=10000) at src/Flags.c:688
#3 0x080fcbaa in MainLoop () at src/App.c:560
#4 0x080fcf7f in main () at src/App.c:748
(gdb) continue
Continuing.
stop: Unknown instance:
Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.[Thread 0xb7fda740 (LWP 5232) exited]
[Inferior 1 (process 5195) exited normally]
(gdb) quit -
@Ramakanth It's as I figured. It just has to do with the fact you are killing the thread rather than exiting it nicely.
You can do as the error message suggests and catch the exception and exit cleanly from
QApplication::notify()
. That should "fix" the problem.Another question, why pthreads? Why not use Qt's threading? Just curious here.
-
@ambershark said in Slot exception being thrown on exit of Qt app with Pkill:
You can do as the error message suggests and catch the exception and exit cleanly from QApplication::notify(). That should "fix" the problem.
Though I created the custom QcoreApplication instance and implement notify, it is not able to catch exception in both std and undefined exceptions..Is there any workaround for this as the GUI is being created in thread? Do you see any advantages in using Qt thread over Pthread as the backend or business logic is implemented in C language?
-
@kshegunov Here is the sample code how GUI App instance is invoked and implemented in a thread created using pthread.
int argc = 0;
char *argv[1];QApplication app(argc,argv); QFile style(styleSheetPath); style.open(QFile::ReadOnly); qApp->setStyleSheet(style.readAll()); style.close(); uiWidget = new MainWidget(); app.exec(); if(uiWidget ) { delete uiWidget; uiWidget = NULL; }
-
@Ramakanth said in Slot exception being thrown on exit of Qt app with Pkill:
Do you see any advantages in using Qt thread over Pthread as the backend or business logic is implemented in C language?
Ease of use and cross platform compatibility. QThreads are much easier to deal with than pthreads. The only time I use C++ threading or pthreads (not really anymore since C++ now has native threading) is when I don't have Qt in a project and don't want to add the heavy Qt libs.
Though I created the custom QcoreApplication instance and implement notify, it is not able to catch exception in both std and undefined exceptions..Is there any workaround for this as the GUI is being created in thread?
What does your catch look like? Are you doing
catch (...)
? You're probably going to have to for exceptions like this. Like I said it's a really bad idea though. You're better off letting it crash because of the unnatural behavior. People understand that killing a process can cause it to crash. Especially us linux guys. :)Another option is actually catching the
SIGKILL
, then cleaning up your thread properly via a call toquit()
before letting the application be killed.This is related to java but the concept is the same for C++.
https://stackoverflow.com/questions/2541597/how-to-gracefully-handle-the-sigkill-signal-in-javaYou can never handle
kill -9
though. That's pretty much the linux way for utterly destroying a process. Wish windows had that. -
Yes my catch look like catch(...) I did try other option of catching the SIGKILL, then cleaning up the thread(created with QThread) with quit() but still the exception is being thrown..As mentioned, probably need to live with crash on killing a process with pkill or kill -15 command.
-
@ambershark said in Slot exception being thrown on exit of Qt app with Pkill:
You can never handle kill -9 though. That's pretty much the linux way for utterly destroying a process. Wish windows had that.
BOOL WINAPI TerminateProcess
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx ? -
@JonB said in Slot exception being thrown on exit of Qt app with Pkill:
@ambershark said in Slot exception being thrown on exit of Qt app with Pkill:
You can never handle kill -9 though. That's pretty much the linux way for utterly destroying a process. Wish windows had that.
BOOL WINAPI TerminateProcess
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx ?Not quite the same thing.
kill -9
in linux can kill anything. I have had many times in windows where even trying to kill an app in task manager fails. That is essentially using a TerminateProcess.Windows doesn't have anything that will truly destroy a process like that. TerminateProcess is more on the same level as just
kill <process>
notkill -9 <process>
. :)Here's a funny meme relating to signaling kills in windows vs linux. Always makes me laugh when I see it because it's just so true.
-
@ambershark
I had the impression that a program cannot catchTerminateProcess
as though it were a signal, and nor can it clean up, which would make it indeed more likekill -9
than another number, but I could be mistaken.One reason TaskMan etc. sometimes cannot kill a process is that it lacks the necessary rights. Depending, you sometimes need the killer to have to grab the OS token for "elevated privileges" (I forget what it is, one of the
SE_...
ones) before doing the kill, then it works.Finally, the ultimate reason is probably that this is Windoze OS, not Linux! I always suspect that the
TerminateProcess
is getting through OK, but the problem is that the OS cannot terminate the process correctly for goodness-knows-what-reason, rather than the request to kill not being proper. -
@JonB No you're right .. a process can't catch TerminateProcess. It just seems like windows can't kill things sometimes (even with full permissions). Whereas on osx/linux or any posix os when you kill -9, it's super dead, unless it's a zombie process. But it's really hard to kill zombies unless you shoot them in the head. :P