Commit 7f90f294 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger: Add incremental API for modules.

And use it from CDB's module load/unload callbacks
instead of re-setting all modules. Some cleanup./Fixed
conflicts in 2.0
Acked-by: hjk
parent 71840d93
......@@ -1516,12 +1516,26 @@ void CdbDebugEnginePrivate::updateModules()
static const char *dumperPrefixC = "dumper";
void CdbDebugEnginePrivate::handleModuleLoad(const QString &name)
void CdbDebugEnginePrivate::handleModuleLoad(quint64 offset, const QString &name)
{
if (debugCDB>2)
qDebug() << Q_FUNC_INFO << "\n " << name;
qDebug() << Q_FUNC_INFO << "\n " << offset << name;
Module module;
// Determine module parameters by offset. The callback has almost all the
// parameters we need with the exception of 'symbolsRead'. Retrieve the
// parameters by offset as to avoid a hack like 'check last module'.
QString errorMessage;
if (getModuleByOffset(interfaces().debugSymbols, offset, &module, &errorMessage)) {
manager()->modulesHandler()->addModule(module);
} else {
m_engine->warning(errorMessage);
}
m_dumper->moduleLoadHook(name, m_hDebuggeeProcess);
updateModules();
}
void CdbDebugEnginePrivate::handleModuleUnload(const QString &imageName)
{
manager()->modulesHandler()->removeModule(imageName);
}
void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT2 pBP)
......
......@@ -87,7 +87,8 @@ public:
void handleBreakpointEvent(PDEBUG_BREAKPOINT2 pBP);
void cleanStackTrace();
void clearForRun();
void handleModuleLoad(const QString &);
void handleModuleLoad(quint64 offset, const QString &);
void handleModuleUnload(const QString &name);
CdbSymbolGroupContext *getSymbolGroupContext(int frameIndex, QString *errorMessage) const;
void clearDisplay();
......
......@@ -174,7 +174,7 @@ STDMETHODIMP CdbDebugEventCallback::LoadModule(
if (debugCDB > 1)
qDebug() << Q_FUNC_INFO << ModuleName;
handleModuleLoad();
m_pEngine->m_d->handleModuleLoad(QString::fromUtf16(reinterpret_cast<const ushort *>(ModuleName)));
m_pEngine->m_d->handleModuleLoad(BaseOffset, QString::fromUtf16(reinterpret_cast<const ushort *>(ModuleName)));
return S_OK;
}
......@@ -188,6 +188,7 @@ STDMETHODIMP CdbDebugEventCallback::UnloadModule(
Q_UNUSED(BaseOffset)
if (debugCDB > 1)
qDebug() << Q_FUNC_INFO << ImageBaseName;
m_pEngine->m_d->handleModuleUnload(QString::fromUtf16(reinterpret_cast<const ushort *>(ImageBaseName)));
handleModuleUnload();
m_pEngine->m_d->updateModules();
return S_OK;
......
......@@ -63,6 +63,51 @@ bool getModuleNameList(CIDebugSymbols *syms, QStringList *modules, QString *erro
return true;
}
// Get basic module parameters from struct (except name)
static inline void getBasicModuleParameters(const DEBUG_MODULE_PARAMETERS &p,
Module *module)
{
const QString hexPrefix = QLatin1String("0x");
module->symbolsRead = (p.Flags & DEBUG_MODULE_USER_MODE)
&& (p.SymbolType != DEBUG_SYMTYPE_NONE);
module->startAddress = hexPrefix + QString::number(p.Base, 16);
module->endAddress = hexPrefix + QString::number((p.Base + p.Size), 16);
}
// Get module name by index
static inline bool getModuleName(CIDebugSymbols *syms, ULONG index, QString *n, QString *errorMessage)
{
WCHAR wszBuf[MAX_PATH];
const HRESULT hr = syms->GetModuleNameStringWide(DEBUG_MODNAME_IMAGE, index, 0, wszBuf, MAX_PATH - 1, 0);
if (FAILED(hr) && hr != E_INVALIDARG) {
*errorMessage= CdbCore::msgComFailed("GetModuleNameStringWide", hr);
return false;
}
*n = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
return true;
}
bool getModuleByOffset(CIDebugSymbols *syms, quint64 offset,
Module *module, QString *errorMessage)
{
// Find by base address and set parameters
ULONG index;
HRESULT hr = syms->GetModuleByOffset(offset, 0, &index, 0);
if (FAILED(hr)) {
*errorMessage= CdbCore::msgComFailed("GetModuleByOffset", hr);
return false;
}
DEBUG_MODULE_PARAMETERS parameters;
memset(&parameters, 0, sizeof(DEBUG_MODULE_PARAMETERS));
hr = syms->GetModuleParameters(1, 0, 0u, &parameters);
if (FAILED(hr)) {
*errorMessage= CdbCore::msgComFailed("GetModuleParameters", hr);
return false;
}
getBasicModuleParameters(parameters, module);
return getModuleName(syms, index, &(module->moduleName), errorMessage);
}
bool getModuleList(CIDebugSymbols *syms, QList<Module> *modules, QString *errorMessage)
{
ULONG count;
......@@ -79,22 +124,13 @@ bool getModuleList(CIDebugSymbols *syms, QList<Module> *modules, QString *errorM
return false;
}
// fill array
const QString hexPrefix = QLatin1String("0x");
WCHAR wszBuf[MAX_PATH];
for (ULONG m = 0; m < count; m++) {
const DEBUG_MODULE_PARAMETERS &p = parameters.at(m);
if (p.Base != DEBUG_INVALID_OFFSET) { // Partial results?
Module module;
module.symbolsRead = (p.Flags & DEBUG_MODULE_USER_MODE)
&& (p.SymbolType != DEBUG_SYMTYPE_NONE);
module.startAddress = hexPrefix + QString::number(p.Base, 16);
module.endAddress = hexPrefix + QString::number((p.Base + p.Size), 16);
hr = syms->GetModuleNameStringWide(DEBUG_MODNAME_IMAGE, m, 0, wszBuf, MAX_PATH - 1, 0);
if (FAILED(hr) && hr != E_INVALIDARG) {
*errorMessage= CdbCore::msgComFailed("GetModuleNameStringWide", hr);
getBasicModuleParameters(p, &module);
if (!getModuleName(syms, m, &(module.moduleName), errorMessage))
return false;
}
module.moduleName = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
modules->push_back(module);
}
}
......
......@@ -42,6 +42,8 @@ class Symbol;
bool getModuleList(CIDebugSymbols *syms, QList<Module> *modules, QString *errorMessage);
bool getModuleNameList(CIDebugSymbols *syms, QStringList *modules, QString *errorMessage);
bool getModuleByOffset(CIDebugSymbols *syms, quint64 offset, Module *module, QString *errorMessage);
// Search symbols matching a pattern. Does not filter on module names.
bool searchSymbols(CIDebugSymbols *syms, const QString &pattern,
QStringList *matches, QString *errorMessage);
......
......@@ -56,9 +56,7 @@ class Debugger::Internal::ModulesModel : public QAbstractItemModel
Q_OBJECT
public:
ModulesModel(ModulesHandler *parent)
: QAbstractItemModel(parent)
{}
explicit ModulesModel(ModulesHandler *parent);
// QAbstractItemModel
int columnCount(const QModelIndex &parent) const
......@@ -72,13 +70,27 @@ public:
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
void clearModel() { if (!m_modules.isEmpty()) { m_modules.clear(); update(); } }
void update() { reset(); }
void clearModel();
void addModule(const Module &m);
void removeModule(const QString &moduleName);
void setModules(const QList<Module> &m);
public:
const QList<Module> &modules() const { return m_modules; }
private:
int indexOfModule(const QString &name) const;
const QVariant m_yes;
const QVariant m_no;
QList<Module> m_modules;
};
ModulesModel::ModulesModel(ModulesHandler *parent) :
QAbstractItemModel(parent),
m_yes(tr("yes")), m_no(tr("no"))
{
}
QVariant ModulesModel::headerData(int section,
Qt::Orientation orientation, int role) const
{
......@@ -112,7 +124,7 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const
break;
case 1:
if (role == Qt::DisplayRole)
return module.symbolsRead ? "yes" : "no";
return module.symbolsRead ? m_yes : m_no;
break;
case 2:
if (role == Qt::DisplayRole)
......@@ -131,6 +143,45 @@ bool ModulesModel::setData(const QModelIndex &index, const QVariant &value, int
return QAbstractItemModel::setData(index, value, role);
}
void ModulesModel::addModule(const Module &m)
{
beginInsertRows(QModelIndex(), m_modules.size(), m_modules.size());
m_modules.push_back(m);
endInsertRows();
}
void ModulesModel::setModules(const QList<Module> &m)
{
m_modules = m;
reset();
}
void ModulesModel::clearModel()
{
if (!m_modules.isEmpty()) {
m_modules.clear();
reset();
}
}
int ModulesModel::indexOfModule(const QString &name) const
{
// Recent modules are more likely to be unloaded first.
for (int i = m_modules.size() - 1; i >= 0; i--)
if (m_modules.at(i).moduleName == name)
return i;
return -1;
}
void ModulesModel::removeModule(const QString &moduleName)
{
const int index = indexOfModule(moduleName);
QTC_ASSERT(index != -1, return);
beginRemoveRows(QModelIndex(), index, index);
m_modules.removeAt(index);
endRemoveRows();
}
//////////////////////////////////////////////////////////////////
//
......@@ -155,16 +206,24 @@ void ModulesHandler::removeAll()
m_model->clearModel();
}
void ModulesHandler::addModule(const Module &module)
{
m_model->addModule(module);
}
void ModulesHandler::removeModule(const QString &moduleName)
{
m_model->removeModule(moduleName);
}
void ModulesHandler::setModules(const QList<Module> &modules)
{
m_model->m_modules = modules;
m_model->update();
m_model->setModules(modules);
}
QList<Module> ModulesHandler::modules() const
{
return m_model->m_modules;
return m_model->modules();
}
#include "moduleshandler.moc"
......@@ -100,6 +100,9 @@ public:
QAbstractItemModel *model() const;
void setModules(const QList<Module> &modules);
void addModule(const Module &module);
void removeModule(const QString &moduleName);
QList<Module> modules() const;
void removeAll();
......
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