forked from qt-creator/qt-creator
Load library at runtime
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
@@ -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));
|
||||
if (FAILED(hr)) m_pDebugSystemObjects = 0;
|
||||
hr = DebugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_pDebugSymbols));
|
||||
if (FAILED(hr)) m_pDebugSymbols = 0;
|
||||
hr = 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) {
|
||||
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 = lib.debugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_pDebugSymbols));
|
||||
if (FAILED(hr)) m_pDebugSymbols = 0;
|
||||
|
||||
hr = lib.debugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_pDebugRegisters));
|
||||
if (FAILED(hr)) m_pDebugRegisters = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user