From 2cf1e2431eb962dfc045d06f4b9a7eac246fc33c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <qtc-committer@nokia.com> Date: Mon, 23 Feb 2009 16:13:35 +0100 Subject: [PATCH] Load library at runtime --- src/plugins/debugger/cdb/cdb.pri | 3 - src/plugins/debugger/cdb/cdbdebugengine.cpp | 101 +++++++++++++++----- src/plugins/debugger/cdb/cdbdebugengine.h | 8 +- src/plugins/debugger/cdb/cdbdebugengine_p.h | 21 +++- 4 files changed, 104 insertions(+), 29 deletions(-) diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri index 8a098aa54b2..527cd0be298 100644 --- a/src/plugins/debugger/cdb/cdb.pri +++ b/src/plugins/debugger/cdb/cdb.pri @@ -25,9 +25,6 @@ SOURCES += \ $$PWD/cdbdebugengine.cpp \ $$PWD/cdbdebugeventcallback.cpp \ $$PWD/cdbdebugoutput.cpp - -LIBS += -L$$CDB_LIBPATH Dbghelp.lib dbgeng.lib - } else { error("Debugging Tools for Windows could not be found in $$CDB_PATH") } diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 7fa9afca716..e397410f7bd 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -44,14 +44,46 @@ #include <QtCore/QTimerEvent> #include <QtCore/QFileInfo> #include <QtCore/QDir> +#include <QtCore/QLibrary> #define DBGHELP_TRANSLATE_TCHAR #include <inc/Dbghelp.h> -using namespace Debugger; -using namespace Debugger::Internal; +static const char *dbgEngineDllC = "dbgeng"; +static const char *debugCreateFuncC = "DebugCreate"; -CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine) : +namespace Debugger { +namespace Internal { + +DebuggerEngineLibrary::DebuggerEngineLibrary() : + m_debugCreate(0) +{ +} + +bool DebuggerEngineLibrary::init(QString *errorMessage) +{ + // Load + QLibrary lib(QLatin1String(dbgEngineDllC), 0); + + if (!lib.isLoaded() && !lib.load()) { + *errorMessage = CdbDebugEngine::tr("Unable to load the debugger engine library '%1': %2"). + arg(QLatin1String(dbgEngineDllC), lib.errorString()); + return false; + } + // Locate symbols + void *createFunc = lib.resolve(debugCreateFuncC); + if (!createFunc) { + *errorMessage = CdbDebugEngine::tr("Unable to resolve '%1' in the debugger engine library '%2'"). + arg(QLatin1String(debugCreateFuncC), QLatin1String(dbgEngineDllC)); + return false; + } + m_debugCreate = static_cast<DebugCreateFunction>(createFunc); + return true; +} + +// --- CdbDebugEnginePrivate + +CdbDebugEnginePrivate::CdbDebugEnginePrivate(const DebuggerEngineLibrary &lib, DebuggerManager *parent, CdbDebugEngine* engine) : m_hDebuggeeProcess(0), m_hDebuggeeThread(0), m_bIgnoreNextDebugEvent(false), @@ -63,24 +95,40 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn m_debuggerManagerAccess(parent->engineInterface()) { HRESULT hr; - hr = DebugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient)); - if (FAILED(hr)) m_pDebugClient = 0; - hr = DebugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl)); - if (FAILED(hr)) m_pDebugControl = 0; - hr = DebugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_pDebugSystemObjects)); + hr = lib.debugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient)); + if (FAILED(hr)) { + m_pDebugClient = 0; + } else { + m_pDebugClient->SetOutputCallbacks(&m_debugOutputCallBack); + m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack); + } + + hr = lib.debugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl)); + if (FAILED(hr)) { + m_pDebugControl = 0; + } else { + m_pDebugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE); + } + + hr = lib.debugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_pDebugSystemObjects)); if (FAILED(hr)) m_pDebugSystemObjects = 0; - hr = DebugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_pDebugSymbols)); + + hr = lib.debugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_pDebugSymbols)); if (FAILED(hr)) m_pDebugSymbols = 0; - hr = DebugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_pDebugRegisters)); + + hr = lib.debugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_pDebugRegisters)); if (FAILED(hr)) m_pDebugRegisters = 0; +} - if (m_pDebugControl) { - m_pDebugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE); - } - if (m_pDebugClient) { - m_pDebugClient->SetOutputCallbacks(&m_debugOutputCallBack); - m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack); +IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *parent) +{ + DebuggerEngineLibrary lib; + QString errorMessage; + if (!lib.init(&errorMessage)) { + qWarning("%s", qPrintable(errorMessage)); + return 0; } + return new CdbDebugEngine(lib, parent); } CdbDebugEnginePrivate::~CdbDebugEnginePrivate() @@ -97,9 +145,9 @@ CdbDebugEnginePrivate::~CdbDebugEnginePrivate() m_pDebugRegisters->Release(); } -CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent) - : IDebuggerEngine(parent), - m_d(new CdbDebugEnginePrivate(parent, this)) +CdbDebugEngine::CdbDebugEngine(const DebuggerEngineLibrary &lib, DebuggerManager *parent) : + IDebuggerEngine(parent), + m_d(new CdbDebugEnginePrivate(lib, parent, this)) { } @@ -628,11 +676,6 @@ void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP) qDebug() << Q_FUNC_INFO; } -IDebuggerEngine *createWinEngine(DebuggerManager *parent) -{ - return new CdbDebugEngine(parent); -} - void CdbDebugEngine::setDebugDumpers(bool on) { Q_UNUSED(on) @@ -646,3 +689,13 @@ void CdbDebugEngine::setUseCustomDumpers(bool on) void CdbDebugEngine::reloadSourceFiles() { } + +} // namespace Internal +} // namespace Debugger + +// Accessed by DebuggerManager +Debugger::Internal::IDebuggerEngine *createWinEngine(Debugger::Internal::DebuggerManager *parent) +{ + return Debugger::Internal::CdbDebugEngine::create(parent); +} + diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index aee16bfc38d..b8476d55afc 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -41,16 +41,22 @@ namespace Internal { class DebuggerManager; class CdbDebugEventCallback; +class DebuggerEngineLibrary; class CdbDebugOutput; struct CdbDebugEnginePrivate; class CdbDebugEngine : public IDebuggerEngine { + Q_DISABLE_COPY(CdbDebugEngine) Q_OBJECT + explicit CdbDebugEngine(const DebuggerEngineLibrary &lib, DebuggerManager *parent); + public: - CdbDebugEngine(DebuggerManager *parent); ~CdbDebugEngine(); + // Factory function that returns 0 if the debug engine library cannot be found. + static IDebuggerEngine *create(DebuggerManager *parent); + virtual void shutdown(); virtual void setToolTipExpression(const QPoint &pos, const QString &exp); virtual bool startDebugger(); diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h index db3a19e0a8b..57f5499dd44 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine_p.h +++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h @@ -43,9 +43,27 @@ namespace Internal { class DebuggerManager; class IDebuggerManagerAccessForEngines; +// Thin wrapper around the 'DBEng' debugger engine shared library +// which is loaded at runtime. + +class DebuggerEngineLibrary { +public: + DebuggerEngineLibrary(); + bool init(QString *errorMessage); + + inline HRESULT debugCreate(REFIID interfaceId, PVOID *interfaceHandle) const + { return m_debugCreate(interfaceId, interfaceHandle); } + +private: + // The exported functions of the library + typedef HRESULT (*DebugCreateFunction)(REFIID, PVOID *); + + DebugCreateFunction m_debugCreate; +}; + struct CdbDebugEnginePrivate { - explicit CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine); + explicit CdbDebugEnginePrivate(const DebuggerEngineLibrary &lib, DebuggerManager *parent, CdbDebugEngine* engine); ~CdbDebugEnginePrivate(); bool isDebuggeeRunning() const { return m_watchTimer != -1; } @@ -80,3 +98,4 @@ enum { debugCDB = 0 }; } // namespace Debugger #endif // DEBUGGER_CDBENGINEPRIVATE_H + -- GitLab