[Interest] can the QRegExpEngine cache acces objects belonging to an unloaded library during global destruction?

René J. V. Bertin rjvbertin at gmail.com
Tue Jan 30 11:32:50 CET 2018


Thiago Macieira wrote:

> QLibrary actually unloads them specifically as part of the QtCore global
> destruction, except if you're using glibc on Linux:

That could explain the difference I was seeing, but it's more likely that Darwin 
is either more proactive in unloading plugins with their dependencies included, 
or less intelligent in doing so.

BTW, with the simple unload protection workaround I added, the plugin dtor is 
now called from the location you cited, I think. Not from QFactoryLoaderPrivate 
anymore in any case.

> The thinking was that the danger of using pointers to static date of libraries
> and plugins already unloaded. 

That probably sounded different in your head? :)

> After all, if QtCore is destroying itself, it's only QtCore code itself that 
is being run.

If that code only executes itself of course. I actually noticed a couple of 
kernel messages during the crashes I had, about how execution of code at invalid 
addresses had been prevented.

>> What's the difference between unload() and release(), btw?
> 
> QLibrary doesn't have release(). Did you mean QLibraryPrivate?

Why, yes. QFactoryLoaderPrivate::~QFactoryLoaderPrivate() does first the one, 
then the other. I had a look at the release() code, I'm guessing that it's goal 
is to allow the system to unload the library from memory?

> But what is it doing during destruction that it needs to access the patterns?
> 
> Oh, I know: it's trying to deref the QString....

I suppose it must be that, yes; that corresponds to what Sérgio posted earlier. 
It would probably be impossible to know what QString that is, at the time of the 
crash?

Making deep copies of the QStrings before storing them should also solve this 
issue, but maybe that would be too expensive?

> I'm ok with emptying the cache on aboutToQuit.

I've made an initial simple implementation, subclassing QCache and adding the 
few required methods so I can call clear() on aboutToQuit and toggle the 
availability switch. This indeed solves the crash for me.

A few questions:
- do I need to check for QT_NO_OBJECT here, or is it enough to check for 
QT_BOOTSTRAPPED?
- is it correct that I don't need a Q_OBJECT macro (and moc file) here for 
reliable signal/slot functionality?
- (ahem) do I need to call the parent default constructor explicitly if I 
override (extend) the default constructor?

I'll be testing this more before submitting it for review. For one, I'd like to 
have some idea how often code tries to add new entries (right now I print a 
warning for all attempts to access the cache, so that includes removing items).

R.




More information about the Interest mailing list