[Interest] QCoreApplication::arguments(): getting the application name safely during global destruction

Thiago Macieira thiago.macieira at intel.com
Tue Jan 21 16:51:17 CET 2020


On Tuesday, 21 January 2020 02:54:30 PST René J.V. Bertin wrote:
> Thanks for the answers; I almost missed them because of GMane changes.
> 
> > Sorry, it's a bug in the application code.
> 
> I was beginning to think as much.
> 
> > QCoreApplication keep s a reference to argc. Since main() has exited, the
> > reference is now dangling
> 
> I suppose this depends on the runtime, but at some point the memory will
> indeed be freed.

The chance that it has been overwritten is 100% at this point. The memory that 
was used to spill the argument to the stack was inside main()'s frame. That 
frame was destroyed when main() returned. And the runtime called exit(), which 
called more functions. So yes, the memory was overwritten.

> > this reason and many others,) QCoreApplication should have been destroyed
> > before main() returned.
> 
> Hmmm, this happened in a style plugin called from the MuseScore application
> which allocates the application instance using `new`; I think I triggered
> this codepath where main() indeed exits without deallocating the instance
> first:
> 
> ```
>       if (MScore::noGui) {
> #ifdef Q_OS_MAC
>             // see issue #28706: Hangup in converter mode with MusicXML
>             source qApp->processEvents();
> #endif
>             exit(processNonGui(argv) ? 0 : EXIT_FAILURE);
>             }
>       else {
> ```

That's not what we see in the backtrace. There was no main() in it and tail-
call optimisation is not possible in this code above.  This was a return from 
main().

Anyway, you have to make sure that QCoreApplication does not outlive its 
arguments. Since argc was passed by reference to the constructor, you must 
destroy QCoreApplication before argc is itself destroyed.

And calling exit() usually is a mistake. Return from main() instead.

> So you're suggesting I should report this as an issue in their code?

Yes.

> BTW, does qApp get reset to NULL/nullptr when the QCoreApplication instance
> is destroyed, IOW, is testing qApp safe even during global destruction
> (under normal circumstances)?

It does and it's safe:

/*!
    Destroys the QCoreApplication object.
*/
QCoreApplication::~QCoreApplication()
{
    qt_call_post_routines();

    self = nullptr;


-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products





More information about the Interest mailing list