1
/*******************************************************************************
2
* Copyright (c) 2009 Red Hat, Inc.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Red Hat - initial API and implementation
10
*******************************************************************************/
12
package org.eclipse.linuxtools.internal.callgraph.launch;
14
import java.io.BufferedWriter;
16
import java.io.FileReader;
17
import java.io.FileWriter;
18
import java.io.IOException;
20
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.IConfigurationElement;
22
import org.eclipse.core.runtime.IExtensionRegistry;
23
import org.eclipse.core.runtime.IProgressMonitor;
24
import org.eclipse.core.runtime.NullProgressMonitor;
25
import org.eclipse.core.runtime.Platform;
26
import org.eclipse.core.runtime.SubMonitor;
27
import org.eclipse.debug.core.ILaunch;
28
import org.eclipse.debug.core.ILaunchConfiguration;
29
import org.eclipse.debug.core.IStreamListener;
30
import org.eclipse.debug.core.model.IProcess;
31
import org.eclipse.debug.core.model.IStreamMonitor;
32
import org.eclipse.linuxtools.internal.callgraph.core.DocWriter;
33
import org.eclipse.linuxtools.internal.callgraph.core.Helper;
34
import org.eclipse.linuxtools.internal.callgraph.core.LaunchConfigurationConstants;
35
import org.eclipse.linuxtools.internal.callgraph.core.PluginConstants;
36
import org.eclipse.linuxtools.internal.callgraph.core.SystemTapCommandGenerator;
37
import org.eclipse.linuxtools.internal.callgraph.core.SystemTapErrorHandler;
38
import org.eclipse.linuxtools.internal.callgraph.core.SystemTapParser;
39
import org.eclipse.linuxtools.internal.callgraph.core.SystemTapUIErrorMessages;
40
import org.eclipse.linuxtools.profiling.launch.ProfileLaunchConfigurationDelegate;
41
import org.eclipse.ui.console.TextConsole;
44
* Delegate for Stap scripts. The Delegate generates part of the command string
45
* and schedules a job to finish generation of the command and execute.
48
public class SystemTapLaunchConfigurationDelegate extends
49
ProfileLaunchConfigurationDelegate {
51
private static final String TEMP_ERROR_OUTPUT =
52
PluginConstants.getDefaultOutput() + "stapTempError.error"; //$NON-NLS-1$
54
private File temporaryScript = null;
55
private String arguments = ""; //$NON-NLS-1$
56
private String scriptPath = ""; //$NON-NLS-1$
57
private String binaryPath = ""; //$NON-NLS-1$
58
private String outputPath = ""; //$NON-NLS-1$
59
private boolean needsBinary = false; // Set to false if we want to use SystemTap
60
private boolean needsArguments = false;
61
@SuppressWarnings("unused")
62
private boolean useColour = false;
63
private String binaryArguments = ""; //$NON-NLS-1$
64
private String partialCommand = ""; //$NON-NLS-1$
65
private String stap = ""; //$NON-NLS-1$
68
protected String getPluginID() {
73
* Sets strings to blank, booleans to false and everything else to null
75
private void initialize() {
76
temporaryScript = null;
77
arguments = ""; //$NON-NLS-1$
78
scriptPath = ""; //$NON-NLS-1$
79
binaryPath = ""; //$NON-NLS-1$
80
outputPath = ""; //$NON-NLS-1$
81
needsBinary = false; // Set to false if we want to use SystemTap
82
needsArguments = false;
84
binaryArguments = ""; //$NON-NLS-1$
88
public void launch(ILaunchConfiguration config, String mode,
89
ILaunch launch, IProgressMonitor m) throws CoreException {
92
m = new NullProgressMonitor();
94
SubMonitor monitor = SubMonitor.convert(m,
95
"SystemTap runtime monitor", 5); //$NON-NLS-1$
98
// check for cancellation
99
if (monitor.isCanceled()) {
106
if (config.getAttribute(LaunchConfigurationConstants.USE_COLOUR,
107
LaunchConfigurationConstants.DEFAULT_USE_COLOUR))
109
if (!config.getAttribute(LaunchConfigurationConstants.ARGUMENTS,
110
LaunchConfigurationConstants.DEFAULT_ARGUMENTS).equals(
111
LaunchConfigurationConstants.DEFAULT_ARGUMENTS)) {
112
arguments = config.getAttribute(
113
LaunchConfigurationConstants.ARGUMENTS,
114
LaunchConfigurationConstants.DEFAULT_ARGUMENTS);
115
needsArguments = true;
117
if (!config.getAttribute(LaunchConfigurationConstants.BINARY_PATH,
118
LaunchConfigurationConstants.DEFAULT_BINARY_PATH).equals(
119
LaunchConfigurationConstants.DEFAULT_BINARY_PATH)) {
120
binaryPath = config.getAttribute(
121
LaunchConfigurationConstants.BINARY_PATH,
122
LaunchConfigurationConstants.DEFAULT_BINARY_PATH);
125
if (!config.getAttribute(LaunchConfigurationConstants.BINARY_ARGUMENTS,
126
LaunchConfigurationConstants.DEFAULT_BINARY_ARGUMENTS).equals(
127
LaunchConfigurationConstants.DEFAULT_BINARY_ARGUMENTS)) {
128
binaryArguments = config.getAttribute(
129
LaunchConfigurationConstants.BINARY_ARGUMENTS,
130
LaunchConfigurationConstants.DEFAULT_BINARY_ARGUMENTS);
132
if (!config.getAttribute(LaunchConfigurationConstants.SCRIPT_PATH,
133
LaunchConfigurationConstants.DEFAULT_SCRIPT_PATH).equals(
134
LaunchConfigurationConstants.DEFAULT_SCRIPT_PATH)) {
135
scriptPath = config.getAttribute(
136
LaunchConfigurationConstants.SCRIPT_PATH,
137
LaunchConfigurationConstants.DEFAULT_SCRIPT_PATH);
139
// Generate script if needed
140
if (config.getAttribute(LaunchConfigurationConstants.NEED_TO_GENERATE,
141
LaunchConfigurationConstants.DEFAULT_NEED_TO_GENERATE)) {
142
temporaryScript = new File(scriptPath);
143
temporaryScript.delete();
145
temporaryScript.createNewFile();
146
FileWriter fstream = new FileWriter(temporaryScript);
147
BufferedWriter out = new BufferedWriter(fstream);
148
out.write(config.getAttribute(
149
LaunchConfigurationConstants.GENERATED_SCRIPT,
150
LaunchConfigurationConstants.DEFAULT_GENERATED_SCRIPT));
152
} catch (IOException e1) {
153
e1.printStackTrace();
157
stap = config.getAttribute(LaunchConfigurationConstants.COMMAND,
158
PluginConstants.STAP_PATH);
161
* Generate partial command
163
partialCommand = ConfigurationOptionsSetter.setOptions(config);
165
outputPath = config.getAttribute(
166
LaunchConfigurationConstants.OUTPUT_PATH,
167
PluginConstants.getDefaultOutput());
168
partialCommand += "-o " + outputPath; //$NON-NLS-1$
170
// check for cancellation
171
if ( !testOutput(outputPath) || monitor.isCanceled() ) {
172
SystemTapUIErrorMessages mess = new SystemTapUIErrorMessages(Messages.getString("SystemTapLaunchConfigurationDelegate.0"), //$NON-NLS-1$
173
Messages.getString("SystemTapLaunchConfigurationDelegate.1"), Messages.getString("SystemTapLaunchConfigurationDelegate.2") + outputPath + //$NON-NLS-1$ //$NON-NLS-2$
174
Messages.getString("SystemTapLaunchConfigurationDelegate.3")); //$NON-NLS-1$
179
finishLaunch(launch, config, m, true);
183
* Returns the current SystemTap command, or returns an error message.
186
public String getCommand() {
187
if (cmd.length() > 0)
190
return Messages.getString("SystemTapLaunchConfigurationDelegate.NoCommand"); //$NON-NLS-1$
193
private void finishLaunch(ILaunch launch, ILaunchConfiguration config,
194
IProgressMonitor monitor, boolean retry) {
197
// Check for cancellation
198
if (monitor.isCanceled() || launch == null) {
203
// set the default source locator if required
204
setDefaultSourceLocator(launch, config);
209
String parserClass = config.getAttribute(LaunchConfigurationConstants.PARSER_CLASS,
210
LaunchConfigurationConstants.DEFAULT_PARSER_CLASS);
211
IExtensionRegistry reg = Platform.getExtensionRegistry();
212
IConfigurationElement[] extensions = reg
213
.getConfigurationElementsFor(PluginConstants.PARSER_RESOURCE,
214
PluginConstants.PARSER_NAME,
216
if (extensions == null || extensions.length < 1) {
217
SystemTapUIErrorMessages mess = new SystemTapUIErrorMessages(Messages.getString("SystemTapLaunchConfigurationDelegate.InvalidParser1"), //$NON-NLS-1$
218
Messages.getString("SystemTapLaunchConfigurationDelegate.InvalidParser1"), //$NON-NLS-1$ //$NON-NLS-2$
219
Messages.getString("SystemTapLaunchConfigurationDelegate.InvalidParser2") + //$NON-NLS-1$
220
Messages.getString("SystemTapLaunchConfigurationDelegate.InvalidParser3") + parserClass); //$NON-NLS-1$
225
IConfigurationElement element = extensions[0];
226
SystemTapParser parser =
227
(SystemTapParser) element.createExecutableExtension(PluginConstants.ATTR_CLASS);
230
parser.setViewID(config.getAttribute(LaunchConfigurationConstants.VIEW_CLASS,
231
LaunchConfigurationConstants.VIEW_CLASS));
232
parser.setSourcePath(outputPath);
233
parser.setMonitor(SubMonitor.convert(monitor));
234
parser.setDone(false);
235
parser.setSecondaryID(config.getAttribute(LaunchConfigurationConstants.SECONDARY_VIEW_ID,
236
LaunchConfigurationConstants.DEFAULT_SECONDARY_VIEW_ID));
238
parser.setKillButtonEnabled(true);
240
if (element.getAttribute(PluginConstants.ATTR_REALTIME).equals(PluginConstants.VAL_TRUE)) {
241
parser.setRealTime(true);
249
IProcess process = createProcess(config, launch);
253
StreamListener s = new StreamListener();
254
process.getStreamsProxy().getErrorStreamMonitor().addListener(s);
256
while (!process.isTerminated()) {
258
if ((monitor != null && monitor.isCanceled()) || parser.isDone()) {
266
parser.setKillButtonEnabled(false);
268
if (process.getExitValue() != 0) {
270
//exit code for command not found
271
if (process.getExitValue() == 127){
272
SystemTapUIErrorMessages errorDialog = new SystemTapUIErrorMessages(
273
Messages.getString("SystemTapLaunchConfigurationDelegate.CallGraphGenericError"), //$NON-NLS-1$
274
Messages.getString("SystemTapLaunchConfigurationDelegate.CallGraphGenericError"), //$NON-NLS-1$
275
Messages.getString("SystemTapLaunchConfigurationDelegate.stapNotFound")); //$NON-NLS-1$
277
errorDialog.schedule();
279
SystemTapErrorHandler errorHandler = new SystemTapErrorHandler();
281
//Prepare stap information
282
errorHandler.appendToLog(config.getName() + Messages.getString("SystemTapLaunchConfigurationDelegate.stap_command") + cmd+ PluginConstants.NEW_LINE + PluginConstants.NEW_LINE);//$NON-NLS-1$
284
//Handle error from TEMP_ERROR_OUTPUT
285
errorHandler.handle(monitor, new FileReader(TEMP_ERROR_OUTPUT)); //$NON-NLS-1$
286
if ((monitor != null && monitor.isCanceled()))
289
errorHandler.finishHandling(monitor, scriptPath);
290
if (errorHandler.isErrorRecognized()) {
291
SystemTapUIErrorMessages errorDialog = new SystemTapUIErrorMessages(
292
Messages.getString("SystemTapLaunchConfigurationDelegate.CallGraphGenericError"), //$NON-NLS-1$
293
Messages.getString("SystemTapLaunchConfigurationDelegate.CallGraphGenericError"), //$NON-NLS-1$
294
errorHandler.getErrorMessage());
296
errorDialog.schedule();
302
if (! element.getAttribute(PluginConstants.ATTR_REALTIME).equals(PluginConstants.VAL_TRUE)) { //$NON-NLS-1$ //$NON-NLS-2$
305
//Parser already scheduled, but double-check
312
String message = generateErrorMessage(config.getName(), binaryArguments);
314
DocWriter dw = new DocWriter(Messages.getString("SystemTapLaunchConfigurationDelegate.DocWriterName"), //$NON-NLS-1$
315
((TextConsole)Helper.getConsoleByName(config.getName())), message);
318
} catch (IOException e) {
320
} catch (InterruptedException e) {
322
} catch (CoreException e) {
330
private String generateErrorMessage(String configName, String binaryCommand) {
331
String output = ""; //$NON-NLS-1$
333
if (binaryCommand == null || binaryCommand.length() < 0) {
334
output = PluginConstants.NEW_LINE +
335
PluginConstants.NEW_LINE + "-------------" + //$NON-NLS-1$
336
PluginConstants.NEW_LINE +
337
Messages.getString("SystemTapLaunchConfigurationDelegate.Relaunch10") //$NON-NLS-1$
338
+ configName + PluginConstants.NEW_LINE +
339
Messages.getString("SystemTapLaunchConfigurationDelegate.Relaunch8") + //$NON-NLS-1$
340
Messages.getString("SystemTapLaunchConfigurationDelegate.Relaunch9") + //$NON-NLS-1$
341
"configuration in Profile As --> Profile Configurations." + //$NON-NLS-1$
342
PluginConstants.NEW_LINE + PluginConstants.NEW_LINE;
344
output = PluginConstants.NEW_LINE
345
+ PluginConstants.NEW_LINE +"-------------" //$NON-NLS-1$
346
+ PluginConstants.NEW_LINE
347
+ Messages.getString("SystemTapLaunchConfigurationDelegate.EndMessage1") //$NON-NLS-1$
348
+ configName + PluginConstants.NEW_LINE +
349
Messages.getString("SystemTapLaunchConfigurationDelegate.EndMessage2") //$NON-NLS-1$
350
+ binaryCommand + PluginConstants.NEW_LINE +
351
Messages.getString("SystemTapLaunchConfigurationDelegate.EndMessage3") + //$NON-NLS-1$
352
Messages.getString("SystemTapLaunchConfigurationDelegate.EndMessage4") + //$NON-NLS-1$
353
Messages.getString("SystemTapLaunchConfigurationDelegate.EndMessage5") + //$NON-NLS-1$
354
PluginConstants.NEW_LINE + PluginConstants.NEW_LINE;
360
private class StreamListener implements IStreamListener{
362
private BufferedWriter bw;
364
public StreamListener() throws IOException {
365
File file = new File(TEMP_ERROR_OUTPUT);
367
file.createNewFile();
368
bw = Helper.setBufferedWriter(TEMP_ERROR_OUTPUT); //$NON-NLS-1$
373
public void streamAppended(String text, IStreamMonitor monitor) {
375
if (text.length() < 1) return;
377
if (counter < PluginConstants.MAX_ERRORS)
379
} catch (IOException e) {
384
public void close() throws IOException {
390
public String generateCommand(ILaunchConfiguration config) {
391
// Generate the command
392
cmd = SystemTapCommandGenerator.generateCommand(scriptPath, binaryPath,
393
partialCommand, needsBinary, needsArguments, arguments, binaryArguments, stap);