summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2013-02-21 13:58:57 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-02-27 07:09:18 +0100
commitcafb02911a29b98ac2652fde64e95870e70fd547 (patch)
tree4c9178b6f09e3a860abccc53b7ce696c056a4b6c /tests
parent790fe22c52f15d4ba1c9e48d6f6847d286cb916f (diff)
Make sure that the reference count for plugins is kept correctly
For systems where the Unix signature checker isn't enabled (read: Mac and Windows), QPluginLoader must actually load the plugin to query for the metadata. On Mac it even tried to keep the library loaded to avoid unloading and reloading again when the user calls load(). However, that plus the fact that it was calling load_sys() (on Mac) meant that it would bypass the reference count checking. And on all Unix, if a library-that-wasnt-a-plugin was already loaded by way of a QLibrary, it would have an effect of unloading said library. So remove the "caching" of the library. We should instead invest time to write a proper Mach-O binary decoder. Task-number: QTBUG-29776 Change-Id: Iebbddabe60047aafedeced21f26a170f59656757 Reviewed-by: Liang Qi <liang.qi@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/lib/mylib.c6
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp6
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp49
3 files changed, 60 insertions, 1 deletions
diff --git a/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c b/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c
index 324dce5b0c..a9abe471b1 100644
--- a/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c
+++ b/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c
@@ -53,6 +53,12 @@
# define BORLAND_STDCALL
#endif
+static int pluginVariable = 0xc0ffee;
+LIB_EXPORT int *pointerAddress()
+{
+ return &pluginVariable;
+}
+
LIB_EXPORT int BORLAND_STDCALL version()
{
return 1;
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp
index 6abb9b6c20..b26b24f454 100644
--- a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp
@@ -46,3 +46,9 @@ QString ThePlugin::pluginName() const
{
return QLatin1String("Plugin ok");
}
+
+static int pluginVariable = 0xc0ffee;
+extern "C" Q_DECL_EXPORT int *pointerAddress()
+{
+ return &pluginVariable;
+}
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index e056fe2b95..cef4f53101 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -99,7 +99,11 @@
static QString sys_qualifiedLibraryName(const QString &fileName)
{
- return QFINDTESTDATA(QString("bin/%1%2%3").arg(PREFIX).arg(fileName).arg(SUFFIX));
+ QString libname = QFINDTESTDATA(QString("bin/%1%2%3").arg(PREFIX).arg(fileName).arg(SUFFIX));
+ QFileInfo fi(libname);
+ if (fi.exists())
+ return fi.canonicalFilePath();
+ return libname;
}
QT_FORWARD_DECLARE_CLASS(QPluginLoader)
@@ -119,6 +123,8 @@ private slots:
#endif
void relativePath();
void reloadPlugin();
+ void preloadedPlugin_data();
+ void preloadedPlugin();
};
void tst_QPluginLoader::cleanup()
@@ -354,6 +360,47 @@ void tst_QPluginLoader::reloadPlugin()
QVERIFY(loader.unload());
}
+
+void tst_QPluginLoader::preloadedPlugin_data()
+{
+ QTest::addColumn<bool>("doLoad");
+ QTest::addColumn<QString>("libname");
+ QTest::newRow("create-plugin") << false << sys_qualifiedLibraryName("theplugin");
+ QTest::newRow("load-plugin") << true << sys_qualifiedLibraryName("theplugin");
+ QTest::newRow("create-non-plugin") << false << sys_qualifiedLibraryName("tst_qpluginloaderlib");
+ QTest::newRow("load-non-plugin") << true << sys_qualifiedLibraryName("tst_qpluginloaderlib");
+}
+
+void tst_QPluginLoader::preloadedPlugin()
+{
+ // check that using QPluginLoader does not interfere with QLibrary
+ QFETCH(QString, libname);
+ QLibrary lib(libname);
+ QVERIFY(lib.load());
+
+ typedef int *(*pf_t)();
+ pf_t pf = (pf_t)lib.resolve("pointerAddress");
+ QVERIFY(pf);
+
+ int *pluginVariable = pf();
+ QVERIFY(pluginVariable);
+ QCOMPARE(*pluginVariable, 0xc0ffee);
+
+ {
+ // load the plugin
+ QPluginLoader loader(libname);
+ QFETCH(bool, doLoad);
+ if (doLoad && loader.load()) {
+ // unload() returns false because QLibrary has it loaded
+ QVERIFY(!loader.unload());
+ }
+ }
+
+ QVERIFY(lib.isLoaded());
+
+ // if the library was unloaded behind our backs, the following will crash:
+ QCOMPARE(*pluginVariable, 0xc0ffee);
+ QVERIFY(lib.unload());
}
QTEST_MAIN(tst_QPluginLoader)