-
Notifications
You must be signed in to change notification settings - Fork 0
/
VgdbComm.cpp
151 lines (108 loc) · 2.51 KB
/
VgdbComm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// VgdbComm.cpp
// Implements the VgdbComm class representing an interface to communicate with a vgdb
#include "Globals.h"
#include "VgdbComm.h"
#include <QDebug>
#include "ProcessReader.h"
#include "ParseInteger.h"
#ifdef _WIN32
#define VALGRIND_EXECUTABLE_NAME "valgrind.cmd"
#define VGDB_EXECUTABLE_NAME "vgdb.cmd"
#else
#define VALGRIND_EXECUTABLE_NAME "valgrind"
#define VGDB_EXECUTABLE_NAME "vgdb"
#endif
bool VgdbComm::checkAvailability()
{
QByteArray stdOut, stdErr;
return (runVgdbCommand(QStringList() << "--help", stdOut, stdErr) == 0);
}
std::vector<VgdbComm::InstanceDesc> VgdbComm::listRunningInstances()
{
QByteArray stdOut, stdErr;
if (runVgdbCommand(QStringList() << "-l", stdOut, stdErr) != 1)
{
// No running instances of valgrind at all
return std::vector<InstanceDesc>();
}
// Parse stdOut for individual instances:
/*
Example output:
use --pid=24397 for /usr/bin/valgrind.bin --tool=massif top
use --pid=24411 for /usr/bin/valgrind.bin --tool=massif top
*/
std::vector<InstanceDesc> res;
for (const auto & line: stdOut.split('\n'))
{
if (!line.startsWith("use --pid="))
{
continue;
}
if (!line.contains(" --tool=massif "))
{
continue;
}
auto idxFor = line.indexOf(" for ");
if (idxFor < 0)
{
continue;
}
auto idxSpace = line.indexOf(' ', 10);
InstanceDesc d;
if (!parseInteger(line.data() + 10, d.first, idxSpace - 10))
{
continue;
}
d.second = QString::fromUtf8(line.data() + idxFor + 5);
res.push_back(std::move(d));
}
return res;
}
bool VgdbComm::captureSnapshot(
quint64 a_InstancePid,
const QString & a_FileName,
QByteArray & a_StdOut,
QByteArray & a_StdErr
)
{
auto exitCode = runVgdbCommand(QStringList()
<< QString::fromUtf8("--pid=%1").arg(a_InstancePid)
<< "detailed_snapshot"
<< a_FileName,
a_StdOut, a_StdErr
);
return (exitCode == 0);
}
qint64 VgdbComm::launchNewInstance(
const QString & a_Executable,
const QString & a_Parameters,
const QString & a_StartFolder
)
{
qint64 pid = 0;
if (!QProcess::startDetached(
VALGRIND_EXECUTABLE_NAME,
QStringList()
<< "--tool=massif"
<< a_Executable
<< a_Parameters,
a_StartFolder,
&pid
))
{
return -1;
}
return pid;
}
int VgdbComm::runVgdbCommand(const QStringList & a_Command, QByteArray & a_StdOut, QByteArray & a_StdErr)
{
QProcess proc;
ProcessReader reader(proc, a_StdOut, a_StdErr);
proc.start(VGDB_EXECUTABLE_NAME, a_Command);
reader.waitForFinished();
if (reader.hasHadError())
{
return -1;
}
return proc.exitCode();
}