Commit 2cf1e243 authored by Friedemann Kleint's avatar Friedemann Kleint

Load library at runtime

parent c6821e8a
...@@ -25,9 +25,6 @@ SOURCES += \ ...@@ -25,9 +25,6 @@ SOURCES += \
$$PWD/cdbdebugengine.cpp \ $$PWD/cdbdebugengine.cpp \
$$PWD/cdbdebugeventcallback.cpp \ $$PWD/cdbdebugeventcallback.cpp \
$$PWD/cdbdebugoutput.cpp $$PWD/cdbdebugoutput.cpp
LIBS += -L$$CDB_LIBPATH Dbghelp.lib dbgeng.lib
} else { } else {
error("Debugging Tools for Windows could not be found in $$CDB_PATH") error("Debugging Tools for Windows could not be found in $$CDB_PATH")
} }
......
...@@ -44,14 +44,46 @@ ...@@ -44,14 +44,46 @@
#include <QtCore/QTimerEvent> #include <QtCore/QTimerEvent>
#include <QtCore/QFileInfo> #include <QtCore/QFileInfo>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QLibrary>
#define DBGHELP_TRANSLATE_TCHAR #define DBGHELP_TRANSLATE_TCHAR
#include <inc/Dbghelp.h> #include <inc/Dbghelp.h>
using namespace Debugger; static const char *dbgEngineDllC = "dbgeng";
using namespace Debugger::Internal; 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_hDebuggeeProcess(0),
m_hDebuggeeThread(0), m_hDebuggeeThread(0),
m_bIgnoreNextDebugEvent(false), m_bIgnoreNextDebugEvent(false),
...@@ -63,24 +95,40 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn ...@@ -63,24 +95,40 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn
m_debuggerManagerAccess(parent->engineInterface()) m_debuggerManagerAccess(parent->engineInterface())
{ {
HRESULT hr; HRESULT hr;
hr = DebugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient)); hr = lib.debugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient));
if (FAILED(hr)) m_pDebugClient = 0; if (FAILED(hr)) {
hr = DebugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl)); m_pDebugClient = 0;
if (FAILED(hr)) m_pDebugControl = 0; } else {
hr = DebugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_pDebugSystemObjects)); 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; 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; 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 (FAILED(hr)) m_pDebugRegisters = 0;
}
if (m_pDebugControl) { IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *parent)
m_pDebugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE); {
} DebuggerEngineLibrary lib;
if (m_pDebugClient) { QString errorMessage;
m_pDebugClient->SetOutputCallbacks(&m_debugOutputCallBack); if (!lib.init(&errorMessage)) {
m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack); qWarning("%s", qPrintable(errorMessage));
return 0;
} }
return new CdbDebugEngine(lib, parent);
} }
CdbDebugEnginePrivate::~CdbDebugEnginePrivate() CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
...@@ -97,9 +145,9 @@ CdbDebugEnginePrivate::~CdbDebugEnginePrivate() ...@@ -97,9 +145,9 @@ CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
m_pDebugRegisters->Release(); m_pDebugRegisters->Release();
} }
CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent) CdbDebugEngine::CdbDebugEngine(const DebuggerEngineLibrary &lib, DebuggerManager *parent) :
: IDebuggerEngine(parent), IDebuggerEngine(parent),
m_d(new CdbDebugEnginePrivate(parent, this)) m_d(new CdbDebugEnginePrivate(lib, parent, this))
{ {
} }
...@@ -628,11 +676,6 @@ void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP) ...@@ -628,11 +676,6 @@ void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
} }
IDebuggerEngine *createWinEngine(DebuggerManager *parent)
{
return new CdbDebugEngine(parent);
}
void CdbDebugEngine::setDebugDumpers(bool on) void CdbDebugEngine::setDebugDumpers(bool on)
{ {
Q_UNUSED(on) Q_UNUSED(on)
...@@ -646,3 +689,13 @@ void CdbDebugEngine::setUseCustomDumpers(bool on) ...@@ -646,3 +689,13 @@ void CdbDebugEngine::setUseCustomDumpers(bool on)
void CdbDebugEngine::reloadSourceFiles() void CdbDebugEngine::reloadSourceFiles()
{ {
} }
} // namespace Internal
} // namespace Debugger
// Accessed by DebuggerManager
Debugger::Internal::IDebuggerEngine *createWinEngine(Debugger::Internal::DebuggerManager *parent)
{
return Debugger::Internal::CdbDebugEngine::create(parent);
}
...@@ -41,16 +41,22 @@ namespace Internal { ...@@ -41,16 +41,22 @@ namespace Internal {
class DebuggerManager; class DebuggerManager;
class CdbDebugEventCallback; class CdbDebugEventCallback;
class DebuggerEngineLibrary;
class CdbDebugOutput; class CdbDebugOutput;
struct CdbDebugEnginePrivate; struct CdbDebugEnginePrivate;
class CdbDebugEngine : public IDebuggerEngine class CdbDebugEngine : public IDebuggerEngine
{ {
Q_DISABLE_COPY(CdbDebugEngine)
Q_OBJECT Q_OBJECT
explicit CdbDebugEngine(const DebuggerEngineLibrary &lib, DebuggerManager *parent);
public: public:
CdbDebugEngine(DebuggerManager *parent);
~CdbDebugEngine(); ~CdbDebugEngine();
// Factory function that returns 0 if the debug engine library cannot be found.
static IDebuggerEngine *create(DebuggerManager *parent);
virtual void shutdown(); virtual void shutdown();
virtual void setToolTipExpression(const QPoint &pos, const QString &exp); virtual void setToolTipExpression(const QPoint &pos, const QString &exp);
virtual bool startDebugger(); virtual bool startDebugger();
......
...@@ -43,9 +43,27 @@ namespace Internal { ...@@ -43,9 +43,27 @@ namespace Internal {
class DebuggerManager; class DebuggerManager;
class IDebuggerManagerAccessForEngines; 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 struct CdbDebugEnginePrivate
{ {
explicit CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine); explicit CdbDebugEnginePrivate(const DebuggerEngineLibrary &lib, DebuggerManager *parent, CdbDebugEngine* engine);
~CdbDebugEnginePrivate(); ~CdbDebugEnginePrivate();
bool isDebuggeeRunning() const { return m_watchTimer != -1; } bool isDebuggeeRunning() const { return m_watchTimer != -1; }
...@@ -80,3 +98,4 @@ enum { debugCDB = 0 }; ...@@ -80,3 +98,4 @@ enum { debugCDB = 0 };
} // namespace Debugger } // namespace Debugger
#endif // DEBUGGER_CDBENGINEPRIVATE_H #endif // DEBUGGER_CDBENGINEPRIVATE_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment