Skip to content
Snippets Groups Projects
Commit 2cf1e243 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Load library at runtime

parent c6821e8a
No related branches found
No related tags found
No related merge requests found
...@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment