54
54
public class ValgrindRemoteProxyLaunchDelegate extends ValgrindLaunchConfigurationDelegate {
56
private static final String VALGRIND_CMD = "valgrind"; //$NON-NLS-1$
58
private ConfigUtils configUtils;
60
public ValgrindRemoteProxyLaunchDelegate() {
64
private static final String VERSION_OPT = "--version"; //$NON-NLS-1$
66
private String whichVersion(IProject project) {
67
String cmdArray[] = new String[2];
68
cmdArray[0] = VALGRIND_CMD;
69
cmdArray[1] = VERSION_OPT;
73
Process p = RuntimeProcessFactory.getFactory().exec(cmdArray, project);
75
BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
76
String commandOutput = stdout.readLine();
80
} catch (IOException e) {
85
private static final String VERSION_PREFIX = "valgrind-"; //$NON-NLS-1$
86
private static final char VERSION_DELIMITER = '-';
87
private static final Version MIN_VER = ValgrindLaunchPlugin.VER_3_3_0;
89
private Version getValgrindVersion(IProject project) throws CoreException {
90
Version valgrindVersion;
91
String verString = whichVersion(project);
93
if (verString == null || verString.equals(EMPTY_STRING)){
94
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, Messages.getString("ValgrindLaunchPlugin.Couldn't_determine_version"))); //$NON-NLS-1$
97
verString = verString.replace(VERSION_PREFIX, ""); //$NON-NLS-1$
99
if (verString.indexOf(VERSION_DELIMITER) > 0) {
100
verString = verString.substring(0, verString.indexOf(VERSION_DELIMITER));
102
if (verString.length() > 0) {
103
valgrindVersion = Version.parseVersion(verString);
106
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, Messages.getString("ValgrindLaunchPlugin.Couldn't_determine_version"))); //$NON-NLS-1$
109
// check for minimum supported version
110
if (valgrindVersion.compareTo(MIN_VER) < 0) {
111
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, NLS.bind(Messages.getString("ValgrindLaunchPlugin.Error_min_version"), valgrindVersion.toString(), MIN_VER.toString()))); //$NON-NLS-1$
113
return valgrindVersion;
118
public void launch(final ILaunchConfiguration config, String mode,
119
final ILaunch launch, IProgressMonitor m) throws CoreException {
121
m = new NullProgressMonitor();
124
// Clear process as we wait on it to be instantiated
127
SubMonitor monitor = SubMonitor.convert(m,
128
Messages.getString("ValgrindRemoteLaunchDelegate.task_name"), 10); //$NON-NLS-1$
129
// check for cancellation
130
if (monitor.isCanceled()) {
134
this.config = config;
135
this.launch = launch;
137
// remove any output from previous run
138
ValgrindUIPlugin.getDefault().resetView();
139
// reset stored launch data
140
getPlugin().setCurrentLaunchConfiguration(null);
141
getPlugin().setCurrentLaunch(null);
143
this.configUtils = new ConfigUtils(config);
144
IProject project = ConfigUtils.getProject(configUtils.getProjectName());
145
URI exeURI = new URI(configUtils.getExecutablePath());
146
RemoteConnection exeRC = new RemoteConnection(exeURI);
148
String valgrindPathString = RuntimeProcessFactory.getFactory().whichCommand(VALGRIND_CMD, project);
149
IPath valgrindFullPath = Path.fromOSString(valgrindPathString);
150
boolean copyExecutable = configUtils.getCopyExecutable();
151
if (copyExecutable) {
152
URI copyExeURI = new URI(configUtils.getCopyFromExecutablePath());
153
RemoteConnection copyExeRC = new RemoteConnection(copyExeURI);
154
IRemoteFileProxy copyExeRFP = copyExeRC.getRmtFileProxy();
155
IFileStore copyExeFS = copyExeRFP.getResource(copyExeURI.getPath());
156
IRemoteFileProxy exeRFP = exeRC.getRmtFileProxy();
157
IFileStore exeFS = exeRFP.getResource(exeURI.getPath());
158
IFileInfo exeFI = exeFS.fetchInfo();
159
if (exeFI.isDirectory()) {
160
// Assume the user wants to copy the file to the given directory, using
161
// the same filename as the "copy from" executable.
162
IPath copyExePath = Path.fromOSString(copyExeURI.getPath());
163
IPath newExePath = Path.fromOSString(exeURI.getPath()).append(copyExePath.lastSegment());
164
// update the exeURI with the new path.
165
exeURI = new URI(exeURI.getScheme(), exeURI.getAuthority(), newExePath.toString(), exeURI.getQuery(), exeURI.getFragment());
166
exeFS = exeRFP.getResource(exeURI.getPath());
168
copyExeFS.copy(exeFS, EFS.OVERWRITE | EFS.SHALLOW, new SubProgressMonitor(monitor, 1));
169
// Note: assume that we don't need to create a new exeRC since the
170
// scheme and authority remain the same between the original exeURI and the new one.
172
valgrindVersion = getValgrindVersion(project);
173
IPath remoteBinFile = Path.fromOSString(exeURI.getPath());
174
String configWorkingDir = configUtils.getWorkingDirectory();
175
IFileStore workingDir;
176
if(configWorkingDir == null){
177
// If no working directory was provided, use the directory containing the
178
// the executable as the working directory.
179
IPath workingDirPath = remoteBinFile.removeLastSegments(1);
180
IRemoteFileProxy workingDirRFP = exeRC.getRmtFileProxy();
181
workingDir = workingDirRFP.getResource(workingDirPath.toOSString());
183
URI workingDirURI = new URI(configUtils.getWorkingDirectory());
184
RemoteConnection workingDirRC = new RemoteConnection(workingDirURI);
185
IRemoteFileProxy workingDirRFP = workingDirRC.getRmtFileProxy();
186
workingDir = workingDirRFP.getResource(workingDirURI.getPath());
189
IPath remoteLogDir = Path.fromOSString("/tmp/"); //$NON-NLS-1$
190
outputPath = remoteLogDir.append("eclipse-valgrind-" + System.currentTimeMillis()); //$NON-NLS-1$
192
exeRC.createFolder(outputPath, new SubProgressMonitor(monitor, 1));
194
// create/empty local output directory
195
IValgrindOutputDirectoryProvider provider = getPlugin().getOutputDirectoryProvider();
196
IPath localOutputDir = null;
198
localOutputDir = provider.getOutputPath();
199
createDirectory(localOutputDir);
200
} catch (IOException e2) {
201
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, IStatus.OK,
202
"", e2)); //$NON-NLS-1$
205
// tool that was launched
206
toolID = getTool(config);
207
// ask tool extension for arguments
208
dynamicDelegate = getDynamicDelegate(toolID);
210
String[] valgrindArgs = getValgrindArgumentsArray(config);
211
String[] executableArgs = getProgramArgumentsArray(config);
212
String[] allArgs = new String[executableArgs.length + valgrindArgs.length + 2];
215
allArgs[idx++] = VALGRIND_CMD;
216
for (String valgrindArg : valgrindArgs) {
217
allArgs[idx++] = valgrindArg;
219
allArgs[idx++] = remoteBinFile.toOSString();
220
for (String executableArg : executableArgs) {
221
allArgs[idx++] = executableArg;
224
Process p = RuntimeProcessFactory.getFactory().exec(allArgs, new String[0], workingDir, project);
226
int state = p.waitFor();
228
if (state != IRemoteCommandLauncher.OK) {
229
abort("valgrind launcher exited with status " + state + ". See IRemoteCommandLauncher for details.\n",
230
null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
234
if (p.exitValue() != 0) {
237
StringBuilder valgrindOutSB = new StringBuilder();
238
BufferedReader valgrindOut = new BufferedReader(new InputStreamReader(p.getInputStream()));
239
while((line = valgrindOut.readLine()) != null ){
240
valgrindOutSB.append(line);
243
StringBuilder valgrindErrSB = new StringBuilder();
244
BufferedReader valgrindErr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
245
while((line = valgrindErr.readLine()) != null ){
246
valgrindErrSB.append(line);
249
abort("Standard ouput: " + valgrindOutSB.toString() +
250
"\nStandard error: " + valgrindErrSB.toString(),
251
null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
254
// move remote log files to local directory
255
exeRC.download(outputPath, localOutputDir, new SubProgressMonitor(monitor, 1));
257
// remove remote log dir and all files under it
258
exeRC.delete(outputPath, new SubProgressMonitor(monitor, 1));
260
// store these for use by other classes
261
getPlugin().setCurrentLaunchConfiguration(config);
262
getPlugin().setCurrentLaunch(launch);
264
// parse Valgrind logs
265
IValgrindMessage[] messages = parseLogs(localOutputDir);
267
// create launch summary string to distinguish this launch
268
launchStr = createLaunchStr(valgrindFullPath);
271
ValgrindUIPlugin.getDefault().createView(launchStr, toolID);
273
ValgrindViewPart view = ValgrindUIPlugin.getDefault().getView();
274
view.setMessages(messages);
277
// pass off control to extender
278
dynamicDelegate.handleLaunch(config, launch, localOutputDir, monitor.newChild(2));
280
// initialize tool-specific part of view
281
dynamicDelegate.initializeView(view.getDynamicView(), launchStr, monitor.newChild(1));
284
ValgrindUIPlugin.getDefault().refreshView();
287
ValgrindUIPlugin.getDefault().showView();
290
} catch (URISyntaxException e) {
291
abort(e.getLocalizedMessage(), null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
292
} catch (IOException e) {
293
abort(e.getLocalizedMessage(), null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
294
} catch (RemoteConnectionException e) {
295
abort(e.getLocalizedMessage(), null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
296
} catch (InterruptedException e) {
297
abort(e.getLocalizedMessage(), null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
304
protected String createLaunchStr(IPath valgrindPath) throws CoreException {
305
String projectName = configUtils.getProjectName();
306
IProject project = ConfigUtils.getProject(projectName);
307
URI projectURI = project.getLocationURI();
309
String host = projectURI.getHost();
311
// Host might be null since it's not needed for a well-formed URI. Try authority instead
313
host = projectURI.getAuthority();
316
// If authority is also null, use a generic name
320
location = "remote host";
322
location = projectURI.getScheme() + "://" + host;
325
return config.getName()
326
+ " [" + getPlugin().getToolName(toolID) + "]" + " " + valgrindPath.toString() + " on " + location; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
330
protected String getPluginID() {
331
return ValgrindLaunchPlugin.PLUGIN_ID;
334
public void onError(Throwable t) {
335
// for now do nothing
56
private static final String VALGRIND_CMD = "valgrind"; //$NON-NLS-1$
58
private ConfigUtils configUtils;
60
public ValgrindRemoteProxyLaunchDelegate() {
64
private static final String VERSION_OPT = "--version"; //$NON-NLS-1$
66
private String whichVersion(IProject project) {
67
String cmdArray[] = new String[2];
68
cmdArray[0] = VALGRIND_CMD;
69
cmdArray[1] = VERSION_OPT;
73
Process p = RuntimeProcessFactory.getFactory().exec(cmdArray,
76
try (BufferedReader stdout = new BufferedReader(
77
new InputStreamReader(p.getInputStream()))) {
78
return stdout.readLine();
80
} catch (IOException e) {
85
private static final String VERSION_PREFIX = "valgrind-"; //$NON-NLS-1$
86
private static final char VERSION_DELIMITER = '-';
87
private static final Version MIN_VER = ValgrindLaunchPlugin.VER_3_3_0;
89
private Version getValgrindVersion(IProject project) throws CoreException {
90
Version valgrindVersion;
91
String verString = whichVersion(project);
93
if (verString == null || verString.isEmpty()){
94
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, Messages.getString("ValgrindLaunchPlugin.Couldn't_determine_version"))); //$NON-NLS-1$
97
verString = verString.replace(VERSION_PREFIX, ""); //$NON-NLS-1$
99
if (verString.indexOf(VERSION_DELIMITER) > 0) {
100
verString = verString.substring(0, verString.indexOf(VERSION_DELIMITER));
102
if (!verString.isEmpty()) {
103
valgrindVersion = Version.parseVersion(verString);
105
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, Messages.getString("ValgrindLaunchPlugin.Couldn't_determine_version"))); //$NON-NLS-1$
108
// check for minimum supported version
109
if (valgrindVersion.compareTo(MIN_VER) < 0) {
110
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, NLS.bind(Messages.getString("ValgrindLaunchPlugin.Error_min_version"), valgrindVersion.toString(), MIN_VER.toString()))); //$NON-NLS-1$
112
return valgrindVersion;
117
public void launch(final ILaunchConfiguration config, String mode,
118
final ILaunch launch, IProgressMonitor m) throws CoreException {
120
m = new NullProgressMonitor();
123
// Clear process as we wait on it to be instantiated
126
SubMonitor monitor = SubMonitor.convert(m,
127
Messages.getString("ValgrindRemoteLaunchDelegate.task_name"), 10); //$NON-NLS-1$
128
// check for cancellation
129
if (monitor.isCanceled()) {
133
this.config = config;
134
this.launch = launch;
136
// remove any output from previous run
137
ValgrindUIPlugin.getDefault().resetView();
138
// reset stored launch data
139
getPlugin().setCurrentLaunchConfiguration(null);
140
getPlugin().setCurrentLaunch(null);
142
this.configUtils = new ConfigUtils(config);
143
IProject project = configUtils.getProject();
144
URI exeURI = new URI(configUtils.getExecutablePath());
145
RemoteConnection exeRC = new RemoteConnection(exeURI);
147
String valgrindPathString = RuntimeProcessFactory.getFactory().whichCommand(VALGRIND_CMD, project);
148
IPath valgrindFullPath = Path.fromOSString(valgrindPathString);
149
boolean copyExecutable = configUtils.getCopyExecutable();
150
if (copyExecutable) {
151
URI copyExeURI = new URI(configUtils.getCopyFromExecutablePath());
152
RemoteConnection copyExeRC = new RemoteConnection(copyExeURI);
153
IRemoteFileProxy copyExeRFP = copyExeRC.getRmtFileProxy();
154
IFileStore copyExeFS = copyExeRFP.getResource(copyExeURI.getPath());
155
IRemoteFileProxy exeRFP = exeRC.getRmtFileProxy();
156
IFileStore exeFS = exeRFP.getResource(exeURI.getPath());
157
IFileInfo exeFI = exeFS.fetchInfo();
158
if (exeFI.isDirectory()) {
159
// Assume the user wants to copy the file to the given directory, using
160
// the same filename as the "copy from" executable.
161
IPath copyExePath = Path.fromOSString(copyExeURI.getPath());
162
IPath newExePath = Path.fromOSString(exeURI.getPath()).append(copyExePath.lastSegment());
163
// update the exeURI with the new path.
164
exeURI = new URI(exeURI.getScheme(), exeURI.getAuthority(), newExePath.toString(), exeURI.getQuery(), exeURI.getFragment());
165
exeFS = exeRFP.getResource(exeURI.getPath());
167
copyExeFS.copy(exeFS, EFS.OVERWRITE | EFS.SHALLOW, new SubProgressMonitor(monitor, 1));
168
// Note: assume that we don't need to create a new exeRC since the
169
// scheme and authority remain the same between the original exeURI and the new one.
171
valgrindVersion = getValgrindVersion(project);
172
IPath remoteBinFile = Path.fromOSString(exeURI.getPath());
173
String configWorkingDir = configUtils.getWorkingDirectory();
174
IFileStore workingDir;
175
if(configWorkingDir == null){
176
// If no working directory was provided, use the directory containing the
177
// the executable as the working directory.
178
IPath workingDirPath = remoteBinFile.removeLastSegments(1);
179
IRemoteFileProxy workingDirRFP = exeRC.getRmtFileProxy();
180
workingDir = workingDirRFP.getResource(workingDirPath.toOSString());
182
URI workingDirURI = new URI(configUtils.getWorkingDirectory());
183
RemoteConnection workingDirRC = new RemoteConnection(workingDirURI);
184
IRemoteFileProxy workingDirRFP = workingDirRC.getRmtFileProxy();
185
workingDir = workingDirRFP.getResource(workingDirURI.getPath());
188
IPath remoteLogDir = Path.fromOSString("/tmp/"); //$NON-NLS-1$
189
outputPath = remoteLogDir.append("eclipse-valgrind-" + System.currentTimeMillis()); //$NON-NLS-1$
191
exeRC.createFolder(outputPath, new SubProgressMonitor(monitor, 1));
193
// create/empty local output directory
194
IValgrindOutputDirectoryProvider provider = getPlugin().getOutputDirectoryProvider();
195
IPath localOutputDir = null;
197
localOutputDir = provider.getOutputPath();
198
createDirectory(localOutputDir);
199
} catch (IOException e2) {
200
throw new CoreException(new Status(IStatus.ERROR, ValgrindLaunchPlugin.PLUGIN_ID, IStatus.OK,
201
"", e2)); //$NON-NLS-1$
204
// tool that was launched
205
toolID = getTool(config);
206
// ask tool extension for arguments
207
dynamicDelegate = getDynamicDelegate(toolID);
209
String[] valgrindArgs = getValgrindArgumentsArray(config);
210
String[] executableArgs = getProgramArgumentsArray(config);
211
String[] allArgs = new String[executableArgs.length + valgrindArgs.length + 2];
214
allArgs[idx++] = VALGRIND_CMD;
215
for (String valgrindArg : valgrindArgs) {
216
allArgs[idx++] = valgrindArg;
218
allArgs[idx++] = remoteBinFile.toOSString();
219
for (String executableArg : executableArgs) {
220
allArgs[idx++] = executableArg;
223
Process p = RuntimeProcessFactory.getFactory().exec(allArgs, new String[0], workingDir, project);
225
int state = p.waitFor();
227
if (state != IRemoteCommandLauncher.OK) {
228
abort(Messages.getString("ValgrindLaunchConfigurationDelegate.Launch_exited_status") + " " //$NON-NLS-1$ //$NON-NLS-2$
229
+ state + ". " + NLS.bind(Messages.getString("ValgrindRemoteProxyLaunchDelegate.see_reference"), "IRemoteCommandLauncher") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
230
+ "\n", //$NON-NLS-1$
231
null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
235
if (p.exitValue() != 0) {
238
StringBuilder valgrindOutSB = new StringBuilder();
239
BufferedReader valgrindOut = new BufferedReader(new InputStreamReader(p.getInputStream()));
240
while((line = valgrindOut.readLine()) != null ){
241
valgrindOutSB.append(line);
244
StringBuilder valgrindErrSB = new StringBuilder();
245
BufferedReader valgrindErr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
246
while((line = valgrindErr.readLine()) != null ){
247
valgrindErrSB.append(line);
250
abort(NLS.bind("ValgrindRemoteProxyLaunchDelegate.Stdout", valgrindOutSB.toString()) + //$NON-NLS-1$
251
"\n" + NLS.bind("ValgrindRemoteProxyLaunchDelegate.Stderr", valgrindErrSB.toString()), //$NON-NLS-1$ //$NON-NLS-2$
252
null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
255
// move remote log files to local directory
256
exeRC.download(outputPath, localOutputDir, new SubProgressMonitor(monitor, 1));
258
// remove remote log dir and all files under it
259
exeRC.delete(outputPath, new SubProgressMonitor(monitor, 1));
261
// store these for use by other classes
262
getPlugin().setCurrentLaunchConfiguration(config);
263
getPlugin().setCurrentLaunch(launch);
265
// parse Valgrind logs
266
IValgrindMessage[] messages = parseLogs(localOutputDir);
268
// create launch summary string to distinguish this launch
269
launchStr = createLaunchStr(valgrindFullPath);
272
ValgrindUIPlugin.getDefault().createView(launchStr, toolID);
274
ValgrindViewPart view = ValgrindUIPlugin.getDefault().getView();
275
view.setMessages(messages);
278
// pass off control to extender
279
dynamicDelegate.handleLaunch(config, launch, localOutputDir, monitor.newChild(2));
281
// initialize tool-specific part of view
282
dynamicDelegate.initializeView(view.getDynamicView(), launchStr, monitor.newChild(1));
285
ValgrindUIPlugin.getDefault().refreshView();
288
ValgrindUIPlugin.getDefault().showView();
291
} catch (URISyntaxException|IOException|RemoteConnectionException|InterruptedException e) {
292
abort(e.getLocalizedMessage(), null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
299
private String createLaunchStr(IPath valgrindPath) throws CoreException {
300
IProject project = configUtils.getProject();
301
URI projectURI = project.getLocationURI();
303
String host = projectURI.getHost();
305
// Host might be null since it's not needed for a well-formed URI. Try authority instead
307
host = projectURI.getAuthority();
310
// If authority is also null, use a generic name
314
location = "remote host"; //$NON-NLS-1$
316
location = projectURI.getScheme() + "://" + host; //$NON-NLS-1$
319
return config.getName()
320
+ " [" + getPlugin().getToolName(toolID) + "]" + " " + valgrindPath.toString() + " on " + location; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
324
protected String getPluginID() {
325
return ValgrindLaunchPlugin.PLUGIN_ID;