@@ -70,60 +70,30 @@ bool PerfRecord::runPerf(bool elevatePrivileges, const QStringList& perfOptions,
70
70
m_perfControlFifo.close ();
71
71
m_perfRecordProcess->kill ();
72
72
}
73
- m_perfRecordProcess = std::make_unique<QProcess>(this );
74
- m_perfRecordProcess->setProcessChannelMode (QProcess::MergedChannels);
75
73
76
- const auto outputFileInfo = QFileInfo (outputPath);
77
- const auto folderPath = outputFileInfo.dir ().path ();
78
- const auto folderInfo = QFileInfo (folderPath);
79
- if (!folderInfo.exists ()) {
80
- emit recordingFailed (tr (" Folder '%1' does not exist." ).arg (folderPath));
81
- return false ;
82
- }
83
- if (!folderInfo.isDir ()) {
84
- emit recordingFailed (tr (" '%1' is not a folder." ).arg (folderPath));
85
- return false ;
86
- }
87
- if (!folderInfo.isWritable ()) {
88
- emit recordingFailed (tr (" Folder '%1' is not writable." ).arg (folderPath));
89
- return false ;
90
- }
91
-
92
- connect (m_perfRecordProcess.get (), static_cast <void (QProcess::*)(int , QProcess::ExitStatus)>(&QProcess::finished),
93
- this , [this ](int exitCode, QProcess::ExitStatus exitStatus) {
94
- Q_UNUSED (exitStatus)
74
+ m_outputPath = outputPath;
75
+ m_userTerminated = false ;
95
76
96
- const auto outputFileInfo = QFileInfo (m_outputPath);
97
- if ((exitCode == EXIT_SUCCESS || (exitCode == SIGTERM && m_userTerminated) || outputFileInfo.size () > 0 )
98
- && outputFileInfo.exists ()) {
99
- if (exitCode != EXIT_SUCCESS && !m_userTerminated) {
100
- emit debuggeeCrashed ();
101
- }
102
- emit recordingFinished (m_outputPath);
103
- } else {
104
- emit recordingFailed (tr (" Failed to record perf data, error code %1." ).arg (exitCode));
105
- }
106
- m_userTerminated = false ;
107
- });
77
+ if (m_host->isLocal ()) {
78
+ return runPerfLocal (elevatePrivileges, perfOptions, outputPath, workingDirectory);
79
+ } else {
80
+ return runPerfRemote (perfOptions, outputPath, workingDirectory);
81
+ }
82
+ }
108
83
109
- connect (m_perfRecordProcess.get (), &QProcess::errorOccurred, this , [this ](QProcess::ProcessError error) {
110
- Q_UNUSED (error)
111
- if (!m_userTerminated) {
112
- emit recordingFailed (m_perfRecordProcess->errorString ());
113
- }
114
- });
84
+ bool PerfRecord::runPerfLocal (bool elevatePrivileges, const QStringList& perfOptions, const QString& outputPath,
85
+ const QString& workingDirectory)
86
+ {
87
+ m_perfRecordProcess = std::make_unique<QProcess>(this );
88
+ m_perfRecordProcess->setProcessChannelMode (QProcess::MergedChannels);
115
89
116
- connect (m_perfRecordProcess.get (), &QProcess::started, this ,
117
- [this ] { emit recordingStarted (m_perfRecordProcess->program (), m_perfRecordProcess->arguments ()); });
90
+ connectRecordingProcessErrors ();
118
91
119
92
connect (m_perfRecordProcess.get (), &QProcess::readyRead, this , [this ]() {
120
93
const auto output = QString::fromUtf8 (m_perfRecordProcess->readAll ());
121
94
emit recordingOutput (output);
122
95
});
123
96
124
- m_outputPath = outputPath;
125
- m_userTerminated = false ;
126
-
127
97
if (!workingDirectory.isEmpty ()) {
128
98
m_perfRecordProcess->setWorkingDirectory (workingDirectory);
129
99
}
@@ -160,6 +130,36 @@ bool PerfRecord::runPerf(bool elevatePrivileges, const QStringList& perfOptions,
160
130
return true ;
161
131
}
162
132
133
+ bool PerfRecord::runPerfRemote (const QStringList& perfOptions, const QString& outputPath,
134
+ const QString& workingDirectory)
135
+ {
136
+ m_perfRecordProcess = m_host->remoteDevice ()->runPerf (workingDirectory, perfOptions);
137
+
138
+ auto output = new QFile (outputPath, m_perfRecordProcess.get ());
139
+ if (!output->open (QIODevice::WriteOnly)) {
140
+ emit recordingFailed (QStringLiteral (" Failed to create output file: %1" ).arg (outputPath));
141
+ return false ;
142
+ }
143
+
144
+ connect (m_perfRecordProcess.get (), &QProcess::readyReadStandardOutput, m_perfRecordProcess.get (),
145
+ [process = m_perfRecordProcess.get (), output] {
146
+ auto data = process->readAllStandardOutput ();
147
+ output->write (data);
148
+ });
149
+ connect (m_perfRecordProcess.get (), &QProcess::readyReadStandardError, m_perfRecordProcess.get (),
150
+ [this ] { emit recordingOutput (QString::fromUtf8 (m_perfRecordProcess->readAllStandardError ())); });
151
+
152
+ connect (m_perfRecordProcess.get (), qOverload<int , QProcess::ExitStatus>(&QProcess::finished), this , [output] {
153
+ output->close ();
154
+ output->deleteLater ();
155
+ });
156
+
157
+ connectRecordingProcessErrors ();
158
+
159
+ m_perfRecordProcess->start ();
160
+ return true ;
161
+ }
162
+
163
163
void PerfRecord::record (const QStringList& perfOptions, const QString& outputPath, bool elevatePrivileges,
164
164
const QStringList& pids)
165
165
{
@@ -245,3 +245,33 @@ bool PerfRecord::actuallyElevatePrivileges(bool elevatePrivileges) const
245
245
const auto capabilities = m_host->perfCapabilities ();
246
246
return elevatePrivileges && capabilities.canElevatePrivileges && !capabilities.privilegesAlreadyElevated ;
247
247
}
248
+
249
+ void PerfRecord::connectRecordingProcessErrors ()
250
+ {
251
+ connect (m_perfRecordProcess.get (), qOverload<int , QProcess::ExitStatus>(&QProcess::finished), this ,
252
+ [this ](int exitCode, QProcess::ExitStatus exitStatus) {
253
+ Q_UNUSED (exitStatus)
254
+
255
+ const auto outputFileInfo = QFileInfo (m_outputPath);
256
+ if ((exitCode == EXIT_SUCCESS || (exitCode == SIGTERM && m_userTerminated) || outputFileInfo.size () > 0 )
257
+ && outputFileInfo.exists ()) {
258
+ if (exitCode != EXIT_SUCCESS && !m_userTerminated) {
259
+ emit debuggeeCrashed ();
260
+ }
261
+ emit recordingFinished (m_outputPath);
262
+ } else {
263
+ emit recordingFailed (tr (" Failed to record perf data, error code %1." ).arg (exitCode));
264
+ }
265
+ m_userTerminated = false ;
266
+ });
267
+
268
+ connect (m_perfRecordProcess.get (), &QProcess::errorOccurred, this , [this ](QProcess::ProcessError error) {
269
+ Q_UNUSED (error)
270
+ if (!m_userTerminated) {
271
+ emit recordingFailed (m_perfRecordProcess->errorString ());
272
+ }
273
+ });
274
+
275
+ connect (m_perfRecordProcess.get (), &QProcess::started, this ,
276
+ [this ] { emit recordingStarted (m_perfRecordProcess->program (), m_perfRecordProcess->arguments ()); });
277
+ }
0 commit comments