aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/valgrind/memchecktool.cpp
diff options
context:
space:
mode:
authorHannes Domani <ssbssa@yahoo.de>2017-12-14 20:12:41 +0100
committerHannes Domani <ssbssa@yahoo.de>2018-01-16 18:50:59 +0000
commit848cece0b2bf8b25cc7703e093795d20fe537612 (patch)
treea1fda8844baeea802de9960e44077d3d2e75d028 /src/plugins/valgrind/memchecktool.cpp
parent15ed2691bf62a24be9cf15be6e5b2afa1fb0a102 (diff)
Valgrind: Run heob process with debugger
Change-Id: Ie026033b04dce73c8f4d7a4adb42f9c08c53cccd Reviewed-by: André Hartmann <aha_1980@gmx.de> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src/plugins/valgrind/memchecktool.cpp')
-rw-r--r--src/plugins/valgrind/memchecktool.cpp109
1 files changed, 96 insertions, 13 deletions
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index 9bd184fd4e..a95a17d54e 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -475,13 +475,13 @@ public:
QString arguments() const;
QString xmlName() const;
+ bool attach() const;
private:
void updateEnabled();
private:
QLineEdit *m_xmlEdit = nullptr;
- QCheckBox *m_pidWaitCheck = nullptr;
QComboBox *m_handleExceptionCombo = nullptr;
QComboBox *m_pageProtectionCombo = nullptr;
QCheckBox *m_freedProtectionCheck = nullptr;
@@ -489,13 +489,14 @@ private:
QComboBox *m_leakDetailCombo = nullptr;
QSpinBox *m_leakSizeSpin = nullptr;
QComboBox *m_leakRecordingCombo = nullptr;
+ QCheckBox *m_attachCheck = nullptr;
QLineEdit *m_extraArgsEdit = nullptr;
};
class HeobData : public QObject
{
public:
- HeobData(MemcheckTool *mcTool, const QString &xmlPath);
+ HeobData(MemcheckTool *mcTool, const QString &xmlPath, Kit *kit, bool attach);
~HeobData();
bool createErrorPipe(DWORD heobPid);
@@ -504,6 +505,10 @@ public:
private:
void processFinished();
+ void sendHeobAttachPid(DWORD pid);
+ void debugStarted();
+ void debugStopped();
+
private:
HANDLE m_errorPipe = INVALID_HANDLE_VALUE;
OVERLAPPED m_ov;
@@ -511,6 +516,9 @@ private:
QWinEventNotifier *m_processFinishedNotifier = nullptr;
MemcheckTool *m_mcTool = nullptr;
QString m_xmlPath;
+ Kit *m_kit = nullptr;
+ bool m_attach = false;
+ RunControl *m_runControl = nullptr;
};
#endif
@@ -708,10 +716,11 @@ void MemcheckTool::heobAction()
StandardRunnable sr;
Abi abi;
bool hasLocalRc = false;
+ Kit *kit = nullptr;
if (Project *project = SessionManager::startupProject()) {
if (Target *target = project->activeTarget()) {
if (RunConfiguration *rc = target->activeRunConfiguration()) {
- if (Kit *kit = target->kit()) {
+ if (kit = target->kit()) {
abi = ToolChainKitInformation::targetAbi(kit);
const Runnable runnable = rc->runnable();
@@ -828,7 +837,7 @@ void MemcheckTool::heobAction()
}
// heob finished signal handler
- HeobData *hd = new HeobData(this, xmlPath);
+ HeobData *hd = new HeobData(this, xmlPath, kit, dialog.attach());
if (!hd->createErrorPipe(pi.dwProcessId)) {
delete hd;
hd = nullptr;
@@ -1140,9 +1149,6 @@ HeobDialog::HeobDialog(QWidget *parent) :
xmlLayout->addWidget(m_xmlEdit);
layout->addLayout(xmlLayout);
- m_pidWaitCheck = new QCheckBox(tr("show process ID and wait"));
- layout->addWidget(m_pidWaitCheck);
-
QHBoxLayout *handleExceptionLayout = new QHBoxLayout;
QLabel *handleExceptionLabel = new QLabel(tr("handle exceptions:"));
handleExceptionLayout->addWidget(handleExceptionLabel);
@@ -1212,6 +1218,9 @@ HeobDialog::HeobDialog(QWidget *parent) :
leakRecordingLayout->addWidget(m_leakRecordingCombo);
layout->addLayout(leakRecordingLayout);
+ m_attachCheck = new QCheckBox(tr("Run with debugger"));
+ layout->addWidget(m_attachCheck);
+
QHBoxLayout *extraArgsLayout = new QHBoxLayout;
QLabel *extraArgsLabel = new QLabel(tr("extra arguments:"));
extraArgsLayout->addWidget(extraArgsLabel);
@@ -1247,9 +1256,6 @@ QString HeobDialog::arguments() const
if (!xml.isEmpty())
args += " -x" + xml;
- int pidWait = m_pidWaitCheck->isChecked() ? 1 : 0;
- args += QString(" -P%1").arg(pidWait);
-
int handleException = m_handleExceptionCombo->currentIndex();
args += QString(" -h%1").arg(handleException);
@@ -1283,6 +1289,11 @@ QString HeobDialog::xmlName() const
return m_xmlEdit->text().replace(' ', '_');
}
+bool HeobDialog::attach() const
+{
+ return m_attachCheck->isChecked();
+}
+
void HeobDialog::updateEnabled()
{
bool enableHeob = m_handleExceptionCombo->currentIndex() < 2;
@@ -1299,8 +1310,8 @@ void HeobDialog::updateEnabled()
m_freedProtectionCheck->setEnabled(enablePageProtection);
}
-HeobData::HeobData(MemcheckTool *mcTool, const QString &xmlPath)
- : m_mcTool(mcTool), m_xmlPath(xmlPath), m_ov(), m_data()
+HeobData::HeobData(MemcheckTool *mcTool, const QString &xmlPath, Kit *kit, bool attach)
+ : m_mcTool(mcTool), m_xmlPath(xmlPath), m_kit(kit), m_attach(attach), m_ov(), m_data()
{
}
@@ -1316,7 +1327,7 @@ HeobData::~HeobData()
bool HeobData::createErrorPipe(DWORD heobPid)
{
const QString pipeName = QString("\\\\.\\Pipe\\heob.error.%1").arg(upperHexNum(heobPid));
- DWORD access = PIPE_ACCESS_INBOUND;
+ DWORD access = m_attach ? PIPE_ACCESS_DUPLEX : PIPE_ACCESS_INBOUND;
m_errorPipe = CreateNamedPipe(reinterpret_cast<LPCWSTR>(pipeName.utf16()),
access | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE, 1, 1024, 1024, 0, NULL);
@@ -1370,6 +1381,12 @@ enum
HEOB_PID_ATTACH = 0x10000000,
};
+enum
+{
+ HEOB_CONTROL_NONE,
+ HEOB_CONTROL_ATTACH,
+};
+
void HeobData::processFinished()
{
m_processFinishedNotifier->setEnabled(false);
@@ -1378,6 +1395,31 @@ void HeobData::processFinished()
bool needErrorMsg = true;
DWORD didread;
if (GetOverlappedResult(m_errorPipe, &m_ov, &didread, TRUE) && didread == sizeof(m_data)) {
+ if (m_data[0] >= HEOB_PID_ATTACH) {
+ m_runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE);
+ auto debugger = new DebuggerRunTool(m_runControl, m_kit);
+ debugger->setAttachPid(ProcessHandle(m_data[1]));
+ debugger->setRunControlName(tr("Process %1").arg(m_data[1]));
+ debugger->setInferiorDevice(DeviceKitInformation::device(m_kit));
+ debugger->setStartMode(AttachExternal);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setContinueAfterAttach(true);
+
+ HANDLE p = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, m_data[1]);
+ if (p != NULL) {
+ wchar_t path[MAX_PATH];
+ DWORD pathLen = MAX_PATH;
+ if (QueryFullProcessImageName(p, 0, path, &pathLen))
+ debugger->setInferiorExecutable(QString::fromWCharArray(path));
+ CloseHandle(p);
+ }
+
+ connect(m_runControl, &RunControl::started, this, &HeobData::debugStarted);
+ connect(m_runControl, &RunControl::stopped, this, &HeobData::debugStopped);
+ debugger->startRunControl();
+ return;
+ }
+
switch (m_data[0]) {
case HEOB_OK:
exitMsg = tr("Process finished with exit code %1 (0x%2).").arg(m_data[1]).arg(upperHexNum(m_data[1]));
@@ -1446,6 +1488,47 @@ void HeobData::processFinished()
deleteLater();
}
+
+void HeobData::sendHeobAttachPid(DWORD pid)
+{
+ m_runControl->disconnect(this);
+
+ m_data[0] = HEOB_CONTROL_ATTACH;
+ m_data[1] = pid;
+ DWORD e = 0;
+ if (WriteFile(m_errorPipe, m_data, sizeof(m_data), NULL, &m_ov)
+ || (e = GetLastError()) == ERROR_IO_PENDING) {
+ DWORD didwrite;
+ if (GetOverlappedResult(m_errorPipe, &m_ov, &didwrite, TRUE)) {
+ if (didwrite == sizeof(m_data)) {
+ if (ReadFile(m_errorPipe, m_data, sizeof(m_data), NULL, &m_ov)
+ || (e = GetLastError()) == ERROR_IO_PENDING) {
+ m_processFinishedNotifier->setEnabled(true);
+ return;
+ }
+ } else {
+ e = ERROR_BAD_LENGTH;
+ }
+ } else {
+ e = GetLastError();
+ }
+ }
+
+ const QString msg = tr("heob: Failure in process attach handshake (%1)").arg(qt_error_string(e));
+ TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
+ TaskHub::requestPopup();
+ deleteLater();
+}
+
+void HeobData::debugStarted()
+{
+ sendHeobAttachPid(GetCurrentProcessId());
+}
+
+void HeobData::debugStopped()
+{
+ sendHeobAttachPid(0);
+}
#endif
} // namespace Internal