fix crash when more than one instances of ExtractorCollection are destructed
ClosedPublic

Authored by mgallien on Sep 9 2017, 8:15 PM.

Details

Summary

fix crash when more than one instances of ExtractorCollection are destructed

Test Plan

without the modification to Extractor class, the new test fails. With the fix, valgrind does not report any new memory leak.

Due to the way QPluginLoader::instance works, the plugins are implicitly shared. If the first ExtractorCollection delete them, the second one will fail due to double delete.

Diff Detail

Repository
R286 KFileMetaData
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
mgallien created this revision.Sep 9 2017, 8:15 PM
Restricted Application added a project: Frameworks. · View Herald TranscriptSep 9 2017, 8:15 PM
mgallien edited the test plan for this revision. (Show Details)Sep 9 2017, 8:19 PM

According to QPluginLoader, if one wants to release the memory,

According to documentation of QPluginLoader, memory is released at application quit. If you want to release it earlier, one should use unload.
I can modify the patch to use that to release as soon as it is possible (i.e. no ExtractorCollection contains a given plugin). For that, I will probably need to make QPluginLoader a member of Extractor class.
What do you think ?

mgallien updated this revision to Diff 19415.Sep 11 2017, 7:15 PM

fix memory leak

mgallien updated this revision to Diff 19416.Sep 11 2017, 7:17 PM

fix another potential memory leak

anthonyfieroni added inline comments.Sep 12 2017, 7:26 AM
src/extractor.cpp
39–46

Make a method to call it, here and in destructor to not have duplicate code.
Other looks good to me +1.

mgallien updated this revision to Diff 19450.Sep 12 2017, 4:31 PM

remove duplicated code

Should I push the fix in its current version ?

Add @dfaure to accept it.

src/extractor.cpp
34–37

d *should* never be nullptr

mgallien added inline comments.Sep 19 2017, 7:14 PM
src/extractor.cpp
34–37

If the Extractor is built using the move constructor, the other instance will have a null d pointer. As far as I know, this is standard practice.

I forgot to say that I do not mind modifying the patch. I am just hoping to make steady progress on it since I am having crash very often with my music player.

dfaure requested changes to this revision.Sep 24 2017, 10:53 AM
dfaure added inline comments.
src/extractor.cpp
34–37

You are correct. However, to improve readability, move (haha) the implementation of the move constructor to be with the default constructor, i.e. above this freeExtractorPlugin method. This will make it clearer that there are multiple ctors, when reading top to bottom.

36

Are you sure you want to call unload? We've had many many problems in the past with unloading plugins.
Anything that still refers to a static object from the plugin (e.g. QMetaObject registration, or anything else) will crash.

src/extractor.h
43

add noexcept

45

The proper syntax for a move constructor is
Extractor& operator=(Extractor &&other) noexcept

src/extractorcollection.cpp
110

This lacks encapsulation. Add a setPluginFileName method to the Extract class, so d doesn't have to be public.

121

This whole std::move business is fun, but we could just add an Extractor ctor that takes an ExtractorPlugin as parameter, no?

(and possibly a QPluginLoader, depending on what we decide about unloading).

Then the loading will be using QPluginLoader here, as before, without a need for cloning the extractor, which looks strange to me, design wise.

Either move the whole loading code to Extractor, or load here and then instanciate (as before), but creating two extractor instances (and moving one to the other) looks weird, overkill, and recipe for trouble.

This revision now requires changes to proceed.Sep 24 2017, 10:53 AM
mgallien updated this revision to Diff 19917.Sep 25 2017, 6:42 PM

reduce the scope of modifications, use an enum to indicate if the plugin should be deleted
and use private methods instead of direct access to private class

mgallien updated this revision to Diff 19918.Sep 25 2017, 6:45 PM
mgallien marked 6 inline comments as done.

add missing noexcept

Reverted most of my changes and only use a private method with two parameters to set the ExtractorPlugin in Extractor class. The second parameter should indicate if the Extractor instance is owner of the plugin or not. The private class is no longer included in extractorcollection.cpp.
I am not really sure this is the right approach as it is very easy to use a wrong combination for the arguments of Extractor::setExtractorPlugin. I will try to improve on that.

mgallien marked an inline comment as done.Sep 25 2017, 6:52 PM
dfaure accepted this revision.Oct 1 2017, 1:50 PM

Looks good. To nitpick, setAutoDeletePlugin(true) would have been clearer IMHO.

(Shared sounds like shared_ptr i.e. refcounting, which isn't the case here, it's just autodelete=off)

This revision is now accepted and ready to land.Oct 1 2017, 1:50 PM
mgallien updated this revision to Diff 20200.Oct 1 2017, 7:16 PM

add a setAutoDeletePlugin method and modify the name of the enum value to not use the shared word

This revision was automatically updated to reflect the committed changes.