forked from qt-creator/qt-creator
Process Listing Windows
This commit is contained in:
committed by
unknown
parent
1e7d6a01e6
commit
86b6c44e4e
@@ -1,7 +1,8 @@
|
|||||||
<ui version="4.0" >
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
<class>AttachExternalDialog</class>
|
<class>AttachExternalDialog</class>
|
||||||
<widget class="QDialog" name="AttachExternalDialog" >
|
<widget class="QDialog" name="AttachExternalDialog">
|
||||||
<property name="geometry" >
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
@@ -9,50 +10,76 @@
|
|||||||
<height>866</height>
|
<height>866</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle">
|
||||||
<string>Start Debugger</string>
|
<string>Start Debugger</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" >
|
<layout class="QVBoxLayout">
|
||||||
<property name="spacing" >
|
<property name="spacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin">
|
||||||
<number>9</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout" >
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="pidLabel" >
|
<widget class="QLabel" name="pidLabel">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Attach to Process ID:</string>
|
<string>Attach to Process ID:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="pidLineEdit" />
|
<widget class="QLineEdit" name="pidLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="filterLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filter:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QWidget" name="filterWidget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="filterLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="filterClearToolButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="procView" >
|
<widget class="QTreeView" name="procView">
|
||||||
<property name="editTriggers" >
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line" >
|
<widget class="Line" name="line">
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons" >
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "stackhandler.h"
|
#include "stackhandler.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/winutils.h>
|
||||||
#include <utils/consoleprocess.h>
|
#include <utils/consoleprocess.h>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
@@ -49,6 +50,31 @@
|
|||||||
static const char *dbgEngineDllC = "dbgeng";
|
static const char *dbgEngineDllC = "dbgeng";
|
||||||
static const char *debugCreateFuncC = "DebugCreate";
|
static const char *debugCreateFuncC = "DebugCreate";
|
||||||
|
|
||||||
|
static QString debugEngineComError(HRESULT hr)
|
||||||
|
{
|
||||||
|
if (!FAILED(hr))
|
||||||
|
return QLatin1String("S_OK");
|
||||||
|
switch (hr) {
|
||||||
|
case E_FAIL:
|
||||||
|
break;
|
||||||
|
case E_INVALIDARG:
|
||||||
|
return QLatin1String("E_INVALIDARG");
|
||||||
|
case E_NOINTERFACE:
|
||||||
|
return QLatin1String("E_NOINTERFACE");
|
||||||
|
case E_OUTOFMEMORY:
|
||||||
|
return QLatin1String("E_OUTOFMEMORY");
|
||||||
|
case E_UNEXPECTED:
|
||||||
|
return QLatin1String("E_UNEXPECTED");
|
||||||
|
case E_NOTIMPL:
|
||||||
|
return QLatin1String("E_NOTIMPL");
|
||||||
|
}
|
||||||
|
if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
|
||||||
|
return QLatin1String("ERROR_ACCESS_DENIED");;
|
||||||
|
if (hr == HRESULT_FROM_NT(STATUS_CONTROL_C_EXIT))
|
||||||
|
return QLatin1String("STATUS_CONTROL_C_EXIT");
|
||||||
|
return Core::Utils::winErrorMessage(HRESULT_CODE(hr));
|
||||||
|
}
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -177,14 +203,48 @@ void CdbDebugEngine::setToolTipExpression(const QPoint & /*pos*/, const QString
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CdbDebugEngine::startDebugger()
|
bool CdbDebugEngine::startDebugger()
|
||||||
|
{
|
||||||
|
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
||||||
|
QString errorMessage;
|
||||||
|
bool rc = false;
|
||||||
|
switch (m_d->m_debuggerManager->startMode()) {
|
||||||
|
case AttachExternal:
|
||||||
|
rc = startAttachDebugger(m_d->m_debuggerManager->m_attachedPID, &errorMessage);
|
||||||
|
break;
|
||||||
|
case StartInternal:
|
||||||
|
case StartExternal:
|
||||||
|
rc = startDebuggerWithExecutable(&errorMessage);
|
||||||
|
break;
|
||||||
|
case AttachCore:
|
||||||
|
errorMessage = tr("CdbDebugEngine: Attach to core not supported!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rc) {
|
||||||
|
m_d->m_debuggerManager->showStatusMessage(tr("Debugger Running"), -1);
|
||||||
|
startWatchTimer();
|
||||||
|
} else {
|
||||||
|
qWarning("%s\n", qPrintable(errorMessage));
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CdbDebugEngine::startAttachDebugger(unsigned long pid, QString *errorMessage)
|
||||||
|
{
|
||||||
|
const HRESULT hr = m_d->m_pDebugClient->AttachProcess(NULL, pid,
|
||||||
|
DEBUG_ATTACH_NONINVASIVE |DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND);
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << "Attaching to " << pid << " returns " << hr;
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
*errorMessage = tr("AttachProcess failed for pid %1: %2").arg(pid).arg(debugEngineComError(hr));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CdbDebugEngine::startDebuggerWithExecutable(QString *errorMessage)
|
||||||
{
|
{
|
||||||
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
||||||
|
|
||||||
//if (!q->m_workingDir.isEmpty())
|
|
||||||
// m_gdbProc.setWorkingDirectory(q->m_workingDir);
|
|
||||||
//if (!q->m_environment.isEmpty())
|
|
||||||
// m_gdbProc.setEnvironment(q->m_environment);
|
|
||||||
|
|
||||||
DEBUG_CREATE_PROCESS_OPTIONS dbgopts;
|
DEBUG_CREATE_PROCESS_OPTIONS dbgopts;
|
||||||
memset(&dbgopts, 0, sizeof(dbgopts));
|
memset(&dbgopts, 0, sizeof(dbgopts));
|
||||||
dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
|
dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
|
||||||
@@ -199,32 +259,28 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
m_d->m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
m_d->m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
||||||
//m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
|
//m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
|
||||||
|
|
||||||
if (m_d->m_debuggerManager->startMode() == AttachExternal) {
|
// TODO console
|
||||||
qWarning("CdbDebugEngine: attach to process not yet implemented!");
|
const QString cmd = Core::Utils::AbstractProcess::createWinCommandline(filename, m_d->m_debuggerManager->m_processArgs);
|
||||||
return false;
|
if (debugCDB)
|
||||||
} else {
|
qDebug() << "Starting " << cmd;
|
||||||
QString cmd = Core::Utils::AbstractProcess::createWinCommandline(filename, m_d->m_debuggerManager->m_processArgs);
|
PCWSTR env = 0;
|
||||||
PCWSTR env = 0;
|
QByteArray envData;
|
||||||
QByteArray envData;
|
if (!m_d->m_debuggerManager->m_environment.empty()) {
|
||||||
if (!m_d->m_debuggerManager->m_environment.empty()) {
|
envData = Core::Utils::AbstractProcess::createWinEnvironment(Core::Utils::AbstractProcess::fixWinEnvironment(m_d->m_debuggerManager->m_environment));
|
||||||
envData = Core::Utils::AbstractProcess::createWinEnvironment(Core::Utils::AbstractProcess::fixWinEnvironment(m_d->m_debuggerManager->m_environment));
|
env = reinterpret_cast<PCWSTR>(envData.data());
|
||||||
env = reinterpret_cast<PCWSTR>(envData.data());
|
|
||||||
}
|
|
||||||
HRESULT hr = m_d->m_pDebugClient->CreateProcess2Wide(NULL,
|
|
||||||
const_cast<PWSTR>(cmd.utf16()),
|
|
||||||
&dbgopts,
|
|
||||||
sizeof(dbgopts),
|
|
||||||
m_d->m_debuggerManager->m_workingDir.utf16(),
|
|
||||||
env);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
//qWarning("CreateProcess2Wide failed");
|
|
||||||
m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const HRESULT hr = m_d->m_pDebugClient->CreateProcess2Wide(NULL,
|
||||||
m_d->m_debuggerManager->showStatusMessage(tr("Debugger Running"), -1);
|
const_cast<PWSTR>(cmd.utf16()),
|
||||||
startWatchTimer();
|
&dbgopts,
|
||||||
|
sizeof(dbgopts),
|
||||||
|
m_d->m_debuggerManager->m_workingDir.utf16(),
|
||||||
|
env);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
*errorMessage = tr("CreateProcess2Wide failed for '%1': %2").arg(cmd).arg(debugEngineComError(hr));
|
||||||
|
m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ protected:
|
|||||||
void timerEvent(QTimerEvent*);
|
void timerEvent(QTimerEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool startAttachDebugger(unsigned long pid, QString *errorMessage);
|
||||||
|
bool startDebuggerWithExecutable(QString *errorMessage);
|
||||||
void startWatchTimer();
|
void startWatchTimer();
|
||||||
void killWatchTimer();
|
void killWatchTimer();
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
#include "ui_attachremotedialog.h"
|
#include "ui_attachremotedialog.h"
|
||||||
#include "ui_startexternaldialog.h"
|
#include "ui_startexternaldialog.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
# include "dbgwinutils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
@@ -41,17 +45,11 @@
|
|||||||
#include <QtGui/QHeaderView>
|
#include <QtGui/QHeaderView>
|
||||||
#include <QtGui/QFileDialog>
|
#include <QtGui/QFileDialog>
|
||||||
#include <QtGui/QPushButton>
|
#include <QtGui/QPushButton>
|
||||||
|
#include <QtGui/QProxyModel>
|
||||||
#ifdef Q_OS_WINDOWS
|
#include <QtGui/QSortFilterProxyModel>
|
||||||
#include <windows.h>
|
|
||||||
#include <tlhelp32.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace Debugger::Internal;
|
using namespace Debugger::Internal;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// AttachCoreDialog
|
// AttachCoreDialog
|
||||||
@@ -100,34 +98,21 @@ void AttachCoreDialog::setCoreFile(const QString &fileName)
|
|||||||
m_ui->coreFileName->setPath(fileName);
|
m_ui->coreFileName->setPath(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// AttachExternalDialog
|
// process model helpers
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AttachExternalDialog::AttachExternalDialog(QWidget *parent)
|
static QStandardItemModel *createProcessModel(QObject *parent)
|
||||||
: QDialog(parent), m_ui(new Ui::AttachExternalDialog)
|
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
QStandardItemModel *rc = new QStandardItemModel(parent);
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
QStringList columns;
|
||||||
m_model = new QStandardItemModel(this);
|
columns << AttachExternalDialog::tr("Process ID")
|
||||||
|
<< AttachExternalDialog::tr("Name")
|
||||||
m_ui->procView->setSortingEnabled(true);
|
<< AttachExternalDialog::tr("State");
|
||||||
|
rc->setHorizontalHeaderLabels(columns);
|
||||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
return rc;
|
||||||
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
|
||||||
|
|
||||||
connect(m_ui->procView, SIGNAL(activated(QModelIndex)),
|
|
||||||
this, SLOT(procSelected(QModelIndex)));
|
|
||||||
|
|
||||||
rebuildProcessList();
|
|
||||||
}
|
|
||||||
|
|
||||||
AttachExternalDialog::~AttachExternalDialog()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isProcessName(const QString &procname)
|
static bool isProcessName(const QString &procname)
|
||||||
@@ -138,87 +123,122 @@ static bool isProcessName(const QString &procname)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProcData
|
bool operator<(const ProcData &p1, const ProcData &p2)
|
||||||
{
|
{
|
||||||
QString ppid;
|
return p1.name < p2.name;
|
||||||
QString name;
|
|
||||||
QString state;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void insertItem(QStandardItem *root, const QString &pid,
|
|
||||||
const QMap<QString, ProcData> &procs, QMap<QString, QStandardItem *> &known)
|
|
||||||
{
|
|
||||||
//qDebug() << "HANDLING " << pid;
|
|
||||||
QStandardItem *parent = 0;
|
|
||||||
const ProcData &proc = procs[pid];
|
|
||||||
if (1 || pid == "0") { // FIXME: a real tree is not-so-nice to search
|
|
||||||
parent = root;
|
|
||||||
} else {
|
|
||||||
if (!known.contains(proc.ppid))
|
|
||||||
insertItem(root, proc.ppid, procs, known);
|
|
||||||
parent = known[proc.ppid];
|
|
||||||
}
|
|
||||||
QList<QStandardItem *> row;
|
|
||||||
row.append(new QStandardItem(pid));
|
|
||||||
row.append(new QStandardItem(proc.name));
|
|
||||||
//row.append(new QStandardItem(proc.ppid));
|
|
||||||
row.append(new QStandardItem(proc.state));
|
|
||||||
parent->appendRow(row);
|
|
||||||
known[pid] = row[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachExternalDialog::rebuildProcessList()
|
// Determine UNIX processes by reading "/proc"
|
||||||
|
static QList<ProcData> unixProcessList()
|
||||||
{
|
{
|
||||||
QStringList procnames = QDir("/proc/").entryList();
|
QList<ProcData> rc;
|
||||||
if (procnames.isEmpty()) {
|
const QStringList procnames = QDir(QLatin1String("/proc/")).entryList();
|
||||||
m_ui->procView->hide();
|
if (procnames.isEmpty())
|
||||||
return;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
typedef QMap<QString, ProcData> Procs;
|
|
||||||
Procs procs;
|
|
||||||
|
|
||||||
foreach (const QString &procname, procnames) {
|
foreach (const QString &procname, procnames) {
|
||||||
if (!isProcessName(procname))
|
if (!isProcessName(procname))
|
||||||
continue;
|
continue;
|
||||||
QString filename = "/proc/" + procname + "/stat";
|
QString filename = QLatin1String("/proc/");
|
||||||
|
filename += procname;
|
||||||
|
filename += QLatin1String("/stat");
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
QStringList data = QString::fromLocal8Bit(file.readAll()).split(' ');
|
const QStringList data = QString::fromLocal8Bit(file.readAll()).split(' ');
|
||||||
//qDebug() << filename << data;
|
|
||||||
ProcData proc;
|
ProcData proc;
|
||||||
proc.name = data.at(1);
|
proc.name = data.at(1);
|
||||||
if (proc.name.startsWith('(') && proc.name.endsWith(')'))
|
if (proc.name.startsWith(QLatin1Char('(')) && proc.name.endsWith(QLatin1Char(')')))
|
||||||
proc.name = proc.name.mid(1, proc.name.size() - 2);
|
proc.name = proc.name.mid(1, proc.name.size() - 2);
|
||||||
proc.state = data.at(2);
|
proc.state = data.at(2);
|
||||||
proc.ppid = data.at(3);
|
proc.ppid = data.at(3);
|
||||||
procs[procname] = proc;
|
rc.push_back(proc);
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
m_model->clear();
|
static void populateProcessModel(QStandardItemModel *model)
|
||||||
QMap<QString, QStandardItem *> known;
|
{
|
||||||
for (Procs::const_iterator it = procs.begin(); it != procs.end(); ++it)
|
#ifdef Q_OS_WIN
|
||||||
insertItem(m_model->invisibleRootItem(), it.key(), procs, known);
|
QList<ProcData> processes = winProcessList();
|
||||||
m_model->setHeaderData(0, Qt::Horizontal, "Process ID", Qt::DisplayRole);
|
#else
|
||||||
m_model->setHeaderData(1, Qt::Horizontal, "Name", Qt::DisplayRole);
|
QList<ProcData> processes = unixProcessList();
|
||||||
//model->setHeaderData(2, Qt::Horizontal, "Parent", Qt::DisplayRole);
|
#endif
|
||||||
m_model->setHeaderData(2, Qt::Horizontal, "State", Qt::DisplayRole);
|
qStableSort(processes);
|
||||||
|
|
||||||
m_ui->procView->setModel(m_model);
|
if (const int rowCount = model->rowCount())
|
||||||
|
model->removeRows(0, rowCount);
|
||||||
|
|
||||||
|
QStandardItem *root = model->invisibleRootItem();
|
||||||
|
foreach(const ProcData &proc, processes) {
|
||||||
|
QList<QStandardItem *> row;
|
||||||
|
row.append(new QStandardItem(proc.ppid));
|
||||||
|
row.append(new QStandardItem(proc.name));
|
||||||
|
if (!proc.image.isEmpty())
|
||||||
|
row.back()->setToolTip(proc.image);
|
||||||
|
row.append(new QStandardItem(proc.state));
|
||||||
|
root->appendRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// AttachExternalDialog
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AttachExternalDialog::AttachExternalDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
m_ui(new Ui::AttachExternalDialog),
|
||||||
|
m_model(createProcessModel(this)),
|
||||||
|
m_proxyModel(new QSortFilterProxyModel(this))
|
||||||
|
{
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||||
|
|
||||||
|
m_proxyModel->setSourceModel(m_model);
|
||||||
|
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
m_proxyModel->setFilterKeyColumn(1);
|
||||||
|
m_ui->procView->setModel(m_proxyModel);
|
||||||
|
m_ui->procView->setSortingEnabled(true);
|
||||||
|
|
||||||
|
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
|
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
|
QPushButton *refreshButton = new QPushButton(tr("Refresh"));
|
||||||
|
connect(refreshButton, SIGNAL(clicked()), this, SLOT(rebuildProcessList()));
|
||||||
|
m_ui->buttonBox->addButton(refreshButton, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
|
connect(m_ui->procView, SIGNAL(activated(QModelIndex)),
|
||||||
|
this, SLOT(procSelected(QModelIndex)));
|
||||||
|
connect(m_ui->filterClearToolButton, SIGNAL(clicked()),
|
||||||
|
m_ui->filterLineEdit, SLOT(clear()));
|
||||||
|
connect(m_ui->filterLineEdit, SIGNAL(textChanged(QString)),
|
||||||
|
m_proxyModel, SLOT(setFilterFixedString(QString)));
|
||||||
|
|
||||||
|
rebuildProcessList();
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachExternalDialog::~AttachExternalDialog()
|
||||||
|
{
|
||||||
|
delete m_ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachExternalDialog::rebuildProcessList()
|
||||||
|
{
|
||||||
|
populateProcessModel(m_model);
|
||||||
m_ui->procView->expandAll();
|
m_ui->procView->expandAll();
|
||||||
m_ui->procView->resizeColumnToContents(0);
|
m_ui->procView->resizeColumnToContents(0);
|
||||||
m_ui->procView->resizeColumnToContents(1);
|
m_ui->procView->resizeColumnToContents(1);
|
||||||
m_ui->procView->sortByColumn(1, Qt::AscendingOrder);
|
m_ui->procView->sortByColumn(1, Qt::AscendingOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachExternalDialog::procSelected(const QModelIndex &index0)
|
void AttachExternalDialog::procSelected(const QModelIndex &proxyIndex)
|
||||||
{
|
{
|
||||||
|
const QModelIndex index0 = m_proxyModel->mapToSource(proxyIndex);
|
||||||
QModelIndex index = index0.sibling(index0.row(), 0);
|
QModelIndex index = index0.sibling(index0.row(), 0);
|
||||||
QStandardItem *item = m_model->itemFromIndex(index);
|
if (const QStandardItem *item = m_model->itemFromIndex(index)) {
|
||||||
if (!item)
|
m_ui->pidLineEdit->setText(item->text());
|
||||||
return;
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->animateClick();
|
||||||
m_ui->pidLineEdit->setText(item->text());
|
}
|
||||||
accept();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AttachExternalDialog::attachPID() const
|
int AttachExternalDialog::attachPID() const
|
||||||
@@ -226,22 +246,22 @@ int AttachExternalDialog::attachPID() const
|
|||||||
return m_ui->pidLineEdit->text().toInt();
|
return m_ui->pidLineEdit->text().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// AttachRemoteDialog
|
// AttachRemoteDialog
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AttachRemoteDialog::AttachRemoteDialog(QWidget *parent, const QString &pid)
|
AttachRemoteDialog::AttachRemoteDialog(QWidget *parent, const QString &pid) :
|
||||||
: QDialog(parent), m_ui(new Ui::AttachRemoteDialog)
|
QDialog(parent),
|
||||||
|
m_ui(new Ui::AttachRemoteDialog),
|
||||||
|
m_model(createProcessModel(this))
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||||
m_defaultPID = pid;
|
m_defaultPID = pid;
|
||||||
m_model = new QStandardItemModel(this);
|
|
||||||
|
|
||||||
|
m_ui->procView->setModel(m_model);
|
||||||
m_ui->procView->setSortingEnabled(true);
|
m_ui->procView->setSortingEnabled(true);
|
||||||
|
|
||||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
@@ -261,42 +281,7 @@ AttachRemoteDialog::~AttachRemoteDialog()
|
|||||||
|
|
||||||
void AttachRemoteDialog::rebuildProcessList()
|
void AttachRemoteDialog::rebuildProcessList()
|
||||||
{
|
{
|
||||||
QStringList procnames = QDir("/proc/").entryList();
|
populateProcessModel(m_model);
|
||||||
if (procnames.isEmpty()) {
|
|
||||||
m_ui->procView->hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef QMap<QString, ProcData> Procs;
|
|
||||||
Procs procs;
|
|
||||||
|
|
||||||
foreach (const QString &procname, procnames) {
|
|
||||||
if (!isProcessName(procname))
|
|
||||||
continue;
|
|
||||||
QString filename = "/proc/" + procname + "/stat";
|
|
||||||
QFile file(filename);
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
QStringList data = QString::fromLocal8Bit(file.readAll()).split(' ');
|
|
||||||
//qDebug() << filename << data;
|
|
||||||
ProcData proc;
|
|
||||||
proc.name = data.at(1);
|
|
||||||
if (proc.name.startsWith('(') && proc.name.endsWith(')'))
|
|
||||||
proc.name = proc.name.mid(1, proc.name.size() - 2);
|
|
||||||
proc.state = data.at(2);
|
|
||||||
proc.ppid = data.at(3);
|
|
||||||
procs[procname] = proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_model->clear();
|
|
||||||
QMap<QString, QStandardItem *> known;
|
|
||||||
for (Procs::const_iterator it = procs.begin(); it != procs.end(); ++it)
|
|
||||||
insertItem(m_model->invisibleRootItem(), it.key(), procs, known);
|
|
||||||
m_model->setHeaderData(0, Qt::Horizontal, "Process ID", Qt::DisplayRole);
|
|
||||||
m_model->setHeaderData(1, Qt::Horizontal, "Name", Qt::DisplayRole);
|
|
||||||
//model->setHeaderData(2, Qt::Horizontal, "Parent", Qt::DisplayRole);
|
|
||||||
m_model->setHeaderData(2, Qt::Horizontal, "State", Qt::DisplayRole);
|
|
||||||
|
|
||||||
m_ui->procView->setModel(m_model);
|
|
||||||
m_ui->procView->expandAll();
|
m_ui->procView->expandAll();
|
||||||
m_ui->procView->resizeColumnToContents(0);
|
m_ui->procView->resizeColumnToContents(0);
|
||||||
m_ui->procView->resizeColumnToContents(1);
|
m_ui->procView->resizeColumnToContents(1);
|
||||||
@@ -317,8 +302,6 @@ int AttachRemoteDialog::attachPID() const
|
|||||||
return m_ui->pidLineEdit->text().toInt();
|
return m_ui->pidLineEdit->text().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// StartExternalDialog
|
// StartExternalDialog
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
class QStandardItemModel;
|
class QStandardItemModel;
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class AttachCoreDialog;
|
class AttachCoreDialog;
|
||||||
@@ -50,6 +51,14 @@ QT_END_NAMESPACE
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
struct ProcData
|
||||||
|
{
|
||||||
|
QString ppid;
|
||||||
|
QString name;
|
||||||
|
QString image;
|
||||||
|
QString state;
|
||||||
|
};
|
||||||
|
|
||||||
class AttachCoreDialog : public QDialog
|
class AttachCoreDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -68,7 +77,6 @@ private:
|
|||||||
Ui::AttachCoreDialog *m_ui;
|
Ui::AttachCoreDialog *m_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class AttachExternalDialog : public QDialog
|
class AttachExternalDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -85,6 +93,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::AttachExternalDialog *m_ui;
|
Ui::AttachExternalDialog *m_ui;
|
||||||
|
QSortFilterProxyModel *m_proxyModel;
|
||||||
QStandardItemModel *m_model;
|
QStandardItemModel *m_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ extern IDebuggerEngine *createWinEngine(DebuggerManager *)
|
|||||||
#endif
|
#endif
|
||||||
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
|
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
|
||||||
|
|
||||||
DebuggerManager::DebuggerManager()
|
DebuggerManager::DebuggerManager() :
|
||||||
|
m_attachCoreAction(0)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -245,7 +246,6 @@ void DebuggerManager::init()
|
|||||||
m_registerHandler = new RegisterHandler;
|
m_registerHandler = new RegisterHandler;
|
||||||
registerView->setModel(m_registerHandler->model());
|
registerView->setModel(m_registerHandler->model());
|
||||||
|
|
||||||
|
|
||||||
m_watchHandler = new WatchHandler;
|
m_watchHandler = new WatchHandler;
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
@@ -295,8 +295,11 @@ void DebuggerManager::init()
|
|||||||
m_attachExternalAction = new QAction(this);
|
m_attachExternalAction = new QAction(this);
|
||||||
m_attachExternalAction->setText(tr("Attach to Running External Application..."));
|
m_attachExternalAction->setText(tr("Attach to Running External Application..."));
|
||||||
|
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
m_attachCoreAction = new QAction(this);
|
m_attachCoreAction = new QAction(this);
|
||||||
m_attachCoreAction->setText(tr("Attach to Core..."));
|
m_attachCoreAction->setText(tr("Attach to Core..."));
|
||||||
|
connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
|
||||||
|
#endif
|
||||||
|
|
||||||
m_continueAction = new QAction(this);
|
m_continueAction = new QAction(this);
|
||||||
m_continueAction->setText(tr("Continue"));
|
m_continueAction->setText(tr("Continue"));
|
||||||
@@ -366,8 +369,6 @@ void DebuggerManager::init()
|
|||||||
this, SLOT(startExternalApplication()));
|
this, SLOT(startExternalApplication()));
|
||||||
connect(m_attachExternalAction, SIGNAL(triggered()),
|
connect(m_attachExternalAction, SIGNAL(triggered()),
|
||||||
this, SLOT(attachExternalApplication()));
|
this, SLOT(attachExternalApplication()));
|
||||||
connect(m_attachCoreAction, SIGNAL(triggered()),
|
|
||||||
this, SLOT(attachCore()));
|
|
||||||
|
|
||||||
connect(m_stopAction, SIGNAL(triggered()),
|
connect(m_stopAction, SIGNAL(triggered()),
|
||||||
this, SLOT(interruptDebuggingRequest()));
|
this, SLOT(interruptDebuggingRequest()));
|
||||||
@@ -788,7 +789,7 @@ void DebuggerManager::attachCore()
|
|||||||
emit debuggingFinished();
|
emit debuggingFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out the debugger type of an exexcutable
|
// Figure out the debugger type of an executable
|
||||||
static bool determineDebuggerType(const QString &executable,
|
static bool determineDebuggerType(const QString &executable,
|
||||||
DebuggerManager::DebuggerType *dt,
|
DebuggerManager::DebuggerType *dt,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
@@ -820,6 +821,20 @@ static bool determineDebuggerType(const QString &executable,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Figure out the debugger type of a PID
|
||||||
|
static bool determineDebuggerType(int /* pid */,
|
||||||
|
DebuggerManager::DebuggerType *dt,
|
||||||
|
QString * /*errorMessage*/)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Preferably Windows debugger
|
||||||
|
*dt = winEngine ? DebuggerManager::WinDebugger : DebuggerManager::GdbDebugger;
|
||||||
|
#else
|
||||||
|
*dt = DebuggerManager::GdbDebugger;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
||||||
{
|
{
|
||||||
if (Debugger::Constants::Internal::debug)
|
if (Debugger::Constants::Internal::debug)
|
||||||
@@ -828,7 +843,8 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
|||||||
m_startMode = mode;
|
m_startMode = mode;
|
||||||
// FIXME: Clean up
|
// FIXME: Clean up
|
||||||
|
|
||||||
if (startMode() == StartExternal) {
|
switch (startMode()) {
|
||||||
|
case StartExternal: {
|
||||||
StartExternalDialog dlg(mainWindow());
|
StartExternalDialog dlg(mainWindow());
|
||||||
dlg.setExecutableFile(
|
dlg.setExecutableFile(
|
||||||
configValue(QLatin1String("LastExternalExecutableFile")).toString());
|
configValue(QLatin1String("LastExternalExecutableFile")).toString());
|
||||||
@@ -844,7 +860,9 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
|||||||
m_processArgs = dlg.executableArguments().split(' ');
|
m_processArgs = dlg.executableArguments().split(' ');
|
||||||
m_workingDir = QString();
|
m_workingDir = QString();
|
||||||
m_attachedPID = -1;
|
m_attachedPID = -1;
|
||||||
} else if (startMode() == AttachExternal) {
|
}
|
||||||
|
break;
|
||||||
|
case AttachExternal: {
|
||||||
AttachExternalDialog dlg(mainWindow());
|
AttachExternalDialog dlg(mainWindow());
|
||||||
if (dlg.exec() != QDialog::Accepted)
|
if (dlg.exec() != QDialog::Accepted)
|
||||||
return false;
|
return false;
|
||||||
@@ -857,7 +875,9 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
|||||||
tr("Cannot attach to PID 0"));
|
tr("Cannot attach to PID 0"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (startMode() == StartInternal) {
|
}
|
||||||
|
break;
|
||||||
|
case StartInternal:
|
||||||
if (m_executable.isEmpty()) {
|
if (m_executable.isEmpty()) {
|
||||||
QString startDirectory = m_executable;
|
QString startDirectory = m_executable;
|
||||||
if (m_executable.isEmpty()) {
|
if (m_executable.isEmpty()) {
|
||||||
@@ -881,7 +901,8 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
|||||||
//m_processArgs = sd.processArgs.join(QLatin1String(" "));
|
//m_processArgs = sd.processArgs.join(QLatin1String(" "));
|
||||||
m_attachedPID = 0;
|
m_attachedPID = 0;
|
||||||
}
|
}
|
||||||
} else if (startMode() == AttachCore) {
|
break;
|
||||||
|
case AttachCore: {
|
||||||
AttachCoreDialog dlg(mainWindow());
|
AttachCoreDialog dlg(mainWindow());
|
||||||
dlg.setExecutableFile(
|
dlg.setExecutableFile(
|
||||||
configValue(QLatin1String("LastExternalExecutableFile")).toString());
|
configValue(QLatin1String("LastExternalExecutableFile")).toString());
|
||||||
@@ -899,12 +920,17 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
|||||||
m_workingDir = QString();
|
m_workingDir = QString();
|
||||||
m_attachedPID = -1;
|
m_attachedPID = -1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
emit debugModeRequested();
|
emit debugModeRequested();
|
||||||
|
|
||||||
DebuggerType type;
|
DebuggerType type;
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
if (!determineDebuggerType(m_executable, &type, &errorMessage)) {
|
const bool hasDebugger = startMode() == AttachExternal ?
|
||||||
|
determineDebuggerType(m_attachedPID, &type, &errorMessage) :
|
||||||
|
determineDebuggerType(m_executable, &type, &errorMessage);
|
||||||
|
if (!hasDebugger) {
|
||||||
QMessageBox::warning(mainWindow(), tr("Warning"),
|
QMessageBox::warning(mainWindow(), tr("Warning"),
|
||||||
tr("Cannot debug '%1': %2").arg(m_executable, errorMessage));
|
tr("Cannot debug '%1': %2").arg(m_executable, errorMessage));
|
||||||
return false;
|
return false;
|
||||||
@@ -1142,7 +1168,8 @@ void DebuggerManager::setStatus(int status)
|
|||||||
|
|
||||||
m_startExternalAction->setEnabled(!started && !starting);
|
m_startExternalAction->setEnabled(!started && !starting);
|
||||||
m_attachExternalAction->setEnabled(!started && !starting);
|
m_attachExternalAction->setEnabled(!started && !starting);
|
||||||
m_attachCoreAction->setEnabled(!started && !starting);
|
if (m_attachCoreAction)
|
||||||
|
m_attachCoreAction->setEnabled(!started && !starting);
|
||||||
m_watchAction->setEnabled(ready);
|
m_watchAction->setEnabled(ready);
|
||||||
m_breakAction->setEnabled(true);
|
m_breakAction->setEnabled(true);
|
||||||
|
|
||||||
|
|||||||
@@ -443,15 +443,15 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_mes
|
|||||||
Constants::STARTEXTERNAL, globalcontext);
|
Constants::STARTEXTERNAL, globalcontext);
|
||||||
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
||||||
|
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
cmd = am->registerAction(m_manager->m_attachExternalAction,
|
cmd = am->registerAction(m_manager->m_attachExternalAction,
|
||||||
Constants::ATTACHEXTERNAL, globalcontext);
|
Constants::ATTACHEXTERNAL, globalcontext);
|
||||||
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
||||||
|
|
||||||
cmd = am->registerAction(m_manager->m_attachCoreAction,
|
if (m_manager->m_attachCoreAction) {
|
||||||
Constants::ATTACHCORE, globalcontext);
|
cmd = am->registerAction(m_manager->m_attachCoreAction,
|
||||||
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
Constants::ATTACHCORE, globalcontext);
|
||||||
#endif
|
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
||||||
|
}
|
||||||
|
|
||||||
cmd = am->registerAction(m_manager->m_continueAction,
|
cmd = am->registerAction(m_manager->m_continueAction,
|
||||||
ProjectExplorer::Constants::DEBUG, QList<int>() << m_gdbRunningContext);
|
ProjectExplorer::Constants::DEBUG, QList<int>() << m_gdbRunningContext);
|
||||||
|
|||||||
79
src/plugins/debugger/win/dbgwinutils.cpp
Normal file
79
src/plugins/debugger/win/dbgwinutils.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at qt-sales@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "winutils.h"
|
||||||
|
#include "debuggerdialogs.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
#ifdef USE_PSAPI
|
||||||
|
# include <psapi.h>
|
||||||
|
#endif
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
#ifdef USE_PSAPI
|
||||||
|
static inline QString imageName(DWORD processId)
|
||||||
|
{
|
||||||
|
QString rc;
|
||||||
|
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION , FALSE, processId);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return rc;
|
||||||
|
WCHAR buffer[MAX_PATH];
|
||||||
|
if (GetProcessImageFileName(handle, buffer, MAX_PATH))
|
||||||
|
rc = QString::fromUtf16(buffer);
|
||||||
|
CloseHandle(handle);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QList<ProcData> winProcessList()
|
||||||
|
{
|
||||||
|
QList<ProcData> rc;
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe;
|
||||||
|
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (snapshot == INVALID_HANDLE_VALUE)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
for (bool hasNext = Process32First(snapshot, &pe); hasNext; hasNext = Process32Next(snapshot, &pe)) {
|
||||||
|
ProcData procData;
|
||||||
|
procData.ppid = QString::number(pe.th32ProcessID);
|
||||||
|
procData.name = QString::fromUtf16(pe.szExeFile);
|
||||||
|
#ifdef USE_PSAPI
|
||||||
|
procData.image = imageName(pe.th32ProcessID);
|
||||||
|
#endif
|
||||||
|
rc.push_back(procData);
|
||||||
|
}
|
||||||
|
CloseHandle(snapshot);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/plugins/debugger/win/dbgwinutils.h
Normal file
44
src/plugins/debugger/win/dbgwinutils.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at qt-sales@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _DBG_WINDUTILS_H
|
||||||
|
#define _DBG_WINDUTILS_H
|
||||||
|
|
||||||
|
#include <QtCore/QList>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
struct ProcData; // debuggerdialogs, used by the process listing dialogs
|
||||||
|
|
||||||
|
QList<ProcData> winProcessList();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
INCLUDEPATH+=$$PWD
|
INCLUDEPATH+=$$PWD
|
||||||
SOURCES += $$PWD/peutils.cpp
|
SOURCES += $$PWD/peutils.cpp \
|
||||||
HEADERS += $$PWD/peutils.h
|
$$PWD/dbgwinutils.cpp
|
||||||
|
HEADERS += $$PWD/peutils.h \
|
||||||
|
$$PWD/dbgwinutils.h
|
||||||
|
|||||||
Reference in New Issue
Block a user