Prevent segmentation faults caused by unfavorable ordering of static destructors #83
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Invoking the
QSettings
destructor from a destructor of a static variable (static QNapiConfig cfg
) is a bad idea. In case the configuration file has not been changed since it was lastsync()
'ed,QConfFileSettingsPrivate::syncConfFile()
will create aQFileInfo
instance and then call itslastModified()
method, which (a few calls down the chain) depends on the default constructor ofQDateTime()
to succeed. The problem with that constructor is that (at least until Qt 5.7 inclusive) it callsdefaultDateTimePrivate()
, which is defined usingQ_GLOBAL_STATIC_WITH_ARGS
(so it is basically another static entity whose destructor is called either before or after theQNapiConfig
destructor). If one is lucky, thecfg
singleton will be destroyed beforedefaultDateTimePrivate
and things will work just fine, but this ordering is not guaranteed. For example, on Arch Linux with Qt 5.7, QNapi will segfault if you invoke it usingqnapi -o
and then press the Save button in the dialog box.As
sync()
is explicitly invoked inQNapiConfig::save()
, there is no practical need to calldelete
for theQSettings
instance as the only thing its destructor does is syncing the changes (i.e. it is equivalent to callingsync()
explicitly). AsQNapiConfig
is a singleton, no memory leak is possible here either as the OS will free any resources allocated to the program upon its exit anyway.However, this issue might be a sign that perhaps the singleton pattern needs to be reimplemented in a safer manner.