1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

[249227] New TracingConsole solution to allow for GDB traces to be printed.

This commit is contained in:
Marc Khouzam 2009-02-28 08:26:31 +00:00
parent 0f18d800c1
commit 4b1e7ea794
11 changed files with 553 additions and 1 deletions

View file

@ -18,7 +18,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.cdt.ui, org.eclipse.cdt.ui,
org.eclipse.ui.ide, org.eclipse.ui.ide,
org.eclipse.core.variables, org.eclipse.core.variables,
org.eclipse.core.expressions org.eclipse.core.expressions,
org.eclipse.ui.console
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui.actions;x-internal:=true, Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui.actions;x-internal:=true,

View file

@ -36,6 +36,8 @@ command.uncall.name = Uncall
command.uncall.description = Perform Uncall command.uncall.description = Perform Uncall
command.uncall.label = Uncall command.uncall.label = Uncall
gdbPreferencePage.name = GDB
launchTab.main.name=Main launchTab.main.name=Main
launchTab.arguments.name=Arguments launchTab.arguments.name=Arguments
launchTab.debugger.name=Debugger launchTab.debugger.name=Debugger

View file

@ -632,5 +632,20 @@
type="org.eclipse.ui.IWorkbenchPart"> type="org.eclipse.ui.IWorkbenchPart">
</propertyTester> </propertyTester>
</extension> </extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
category="org.eclipse.cdt.dsf.debug.ui.preferences"
class="org.eclipse.cdt.dsf.gdb.internal.ui.preferences.GdbDebugPreferencePage"
id="org.eclipse.cdt.dsf.gdb.ui.preferences"
name="%gdbPreferencePage.name">
</page>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer
class="org.eclipse.cdt.dsf.gdb.internal.ui.preferences.GdbPreferenceInitializer">
</initializer>
</extension>
</plugin> </plugin>

View file

@ -11,6 +11,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui; package org.eclipse.cdt.dsf.gdb.internal.ui;
import org.eclipse.cdt.dsf.gdb.internal.ui.tracing.TracingConsoleManager;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -37,6 +38,7 @@ public class GdbUIPlugin extends AbstractUIPlugin {
private static BundleContext fgBundleContext; private static BundleContext fgBundleContext;
private static TracingConsoleManager fTracingConsoleManager;
/** /**
* The constructor * The constructor
*/ */
@ -52,6 +54,9 @@ public class GdbUIPlugin extends AbstractUIPlugin {
fgBundleContext = context; fgBundleContext = context;
super.start(context); super.start(context);
plugin = this; plugin = this;
fTracingConsoleManager = new TracingConsoleManager();
fTracingConsoleManager.startup();
} }
/* /*
@ -60,6 +65,8 @@ public class GdbUIPlugin extends AbstractUIPlugin {
*/ */
@Override @Override
public void stop(BundleContext context) throws Exception { public void stop(BundleContext context) throws Exception {
fTracingConsoleManager.shutdown();
disposeAdapterSets(); disposeAdapterSets();
plugin = null; plugin = null;
super.stop(context); super.stop(context);

View file

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
/**
* A preference page for settings that are currently only supported in GDB.
*/
public class GdbDebugPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
public GdbDebugPreferencePage() {
super(FLAT);
IPreferenceStore store= GdbUIPlugin.getDefault().getPreferenceStore();
setPreferenceStore(store);
setDescription(MessagesForPreferences.GdbDebugPreferencePage_description);
}
public void init(IWorkbench workbench) {
}
@Override
public void createControl(Composite parent) {
super.createControl(parent);
PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IGdbDebugPreferenceConstants.PREFERENCE_PAGE);
}
@Override
protected void createFieldEditors() {
final Composite parent= getFieldEditorParent();
final GridLayout layout= new GridLayout();
layout.marginWidth= 0;
parent.setLayout(layout);
Group tracesGroup= new Group(parent, SWT.NONE);
tracesGroup.setText(MessagesForPreferences.GdbDebugPreferencePage_traces_label);
GridLayout groupLayout= new GridLayout(3, false);
tracesGroup.setLayout(groupLayout);
tracesGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
BooleanFieldEditor traces= new BooleanFieldEditor(
IGdbDebugPreferenceConstants.PREF_TRACES_ENABLE,
MessagesForPreferences.GdbDebugPreferencePage_enableTraces_label,
tracesGroup);
traces.fillIntoGrid(tracesGroup, 3);
addField(traces);
// need to set layout again
tracesGroup.setLayout(groupLayout);
}
@Override
protected void adjustGridLayout() {
// do nothing
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;
/**
* Initialize the GDB preferences.
*/
public class GdbPreferenceInitializer extends AbstractPreferenceInitializer {
@Override
public void initializeDefaultPreferences() {
IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
store.setDefault(IGdbDebugPreferenceConstants.PREF_TRACES_ENABLE, true);
}
}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
import org.eclipse.debug.ui.IDebugUIConstants;
/**
* @noimplement This interface is not intended to be implemented by clients.
* @since 2.0
*/
public interface IGdbDebugPreferenceConstants {
/**
* Debug UI plug-in identifier (value <code>"org.eclipse.cdt.dsf.gdb.ui"</code>).
*/
public static final String PLUGIN_ID = "org.eclipse.cdt.dsf.gdb.ui"; //$NON-NLS-1$;
/**
* Boolean preference whether to enable GDB traces. Default is <code>true</code>.
*
*/
public static final String PREF_TRACES_ENABLE = "tracesEnable"; //$NON-NLS-1$
/**
* Help prefixes.
*/
public static final String PREFIX = IDebugUIConstants.PLUGIN_ID + "."; //$NON-NLS-1$
public static final String PREFERENCE_PAGE= PREFIX + "preference_page_context"; //$NON-NLS-1$
}

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
import org.eclipse.osgi.util.NLS;
/**
* Preference strings.
*/
class MessagesForPreferences extends NLS {
private static final String BUNDLE_NAME= "org.eclipse.cdt.dsf.gdb.internal.ui.preferences.messages"; //$NON-NLS-1$
public static String GdbDebugPreferencePage_description;
public static String GdbDebugPreferencePage_traces_label;
public static String GdbDebugPreferencePage_enableTraces_label;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class);
}
private MessagesForPreferences() {
}
}

View file

@ -0,0 +1,14 @@
###############################################################################
# Copyright (c) 2009 Ericsson and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Ericsson - initial API and implementation
###############################################################################
GdbDebugPreferencePage_description=General settings for GDB Debugging
GdbDebugPreferencePage_traces_label=Traces
GdbDebugPreferencePage_enableTraces_label=Enable GDB traces

View file

@ -0,0 +1,182 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracing;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlInitializedDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IOConsole;
/**
* A console that is used to print traces. The console is attached to a launch.
*
* Any input to this console is read and discarded, since this console should be
* read-only. We don't actually make the console read-only because it is nice
* for the user to be able to add delimiters such as empty lines within the traces.
*/
public class TracingConsole extends IOConsole {
private ILaunch fLaunch;
private OutputStream fTracingStream = null;
private DsfSession fSession = null;
private String fLabel = ""; //$NON-NLS-1$
public TracingConsole(ILaunch launch, String label) {
super("", null, null, true); //$NON-NLS-1$
fLaunch = launch;
fTracingStream = newOutputStream();
fSession = ((GdbLaunch)launch).getSession();
fLabel = label;
resetName();
// Start a job to swallow all the input from the user
new InputReadJob().schedule();
// This is needed if the service has already been created.
// For example, if we turn on tracing after a launch is started.
setStreamInService();
}
@Override
protected void init() {
super.init();
fSession.addServiceEventListener(this, null);
}
@Override
protected void dispose() {
try {
fTracingStream.close();
} catch (IOException e) {
}
super.dispose();
}
public ILaunch getLaunch() { return fLaunch; }
private void setStreamInService() {
try {
fSession.getExecutor().submit(new DsfRunnable() {
public void run() {
DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId());
IGDBControl control = tracker.getService(IGDBControl.class);
tracker.dispose();
if (control != null) {
// Special method that need not be called on the executor
control.setTracingStream(fTracingStream);
}
}
});
} catch (RejectedExecutionException e) {
}
}
protected String computeName() {
String label = fLabel;
ILaunchConfiguration config = fLaunch.getLaunchConfiguration();
if (config != null && !DebugUITools.isPrivate(config)) {
String type = null;
try {
type = config.getType().getName();
} catch (CoreException e) {
}
StringBuffer buffer = new StringBuffer();
buffer.append(config.getName());
if (type != null) {
buffer.append(" ["); //$NON-NLS-1$
buffer.append(type);
buffer.append("] "); //$NON-NLS-1$
}
buffer.append(label);
label = buffer.toString();
}
if (fLaunch.isTerminated()) {
return "<terminated> " + label;
}
return label;
}
public void resetName() {
final String newName = computeName();
String name = getName();
if (!name.equals(newName)) {
Runnable r = new Runnable() {
public void run() {
setName(newName);
}
};
PlatformUI.getWorkbench().getDisplay().asyncExec(r);
}
}
@DsfServiceEventHandler
public final void eventDispatched(ICommandControlInitializedDMEvent event) {
// Now that the service is started, we can set the stream.
// We won't receive this event if we enable tracing after a launch
// has been started.
setStreamInService();
}
/**
* A reading Job which will prevent the input stream
* from filling up. We don't actually do anything with
* the data we read, since the Trace console should not
* accept input.
*
* But instead of making the console read-only, we allow
* the user to type things to allow for comments to be
* inserted within the traces.
*/
private class InputReadJob extends Job {
{
setSystem(true);
}
InputReadJob() {
super("Traces Input Job"); //$NON-NLS-1$
}
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
byte[] b = new byte[1024];
int read = 0;
while (getInputStream() != null && read >= 0) {
// Read the input and swallow it.
read = getInputStream().read(b);
}
} catch (IOException e) {
}
return Status.OK_STATUS;
}
}
}

View file

@ -0,0 +1,158 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracing;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.internal.ui.preferences.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.launching.ITracedLaunch;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
/**
* A tracing console manager which adds and removes tracing consoles
* based on launch events and preference events.
*/
public class TracingConsoleManager implements ILaunchesListener2, IPropertyChangeListener {
/**
* Member to keep track of the preference.
* We keep it up-to-date by registering as an IPropertyChangeListener
*/
private boolean fTracingEnabled = false;
/**
* Start the tracing console. We don't do this in a constructor, because
* we need to use <code>this</code>.
*/
public void startup() {
GdbUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
fTracingEnabled = store.getBoolean(IGdbDebugPreferenceConstants.PREF_TRACES_ENABLE);
if (fTracingEnabled) {
toggleTracing(true);
}
}
public void shutdown() {
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
GdbUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
removeAllConsoles();
}
protected void toggleTracing(boolean enabled) {
if (enabled) {
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
addAllConsoles();
} else {
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
removeAllConsoles();
}
}
protected void addAllConsoles() {
ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
for (ILaunch launch : launches) {
addConsole(launch);
}
}
protected void removeAllConsoles() {
ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
for (ILaunch launch : launches) {
removeConsole(launch);
}
}
public void launchesAdded(ILaunch[] launches) {
for (ILaunch launch : launches) {
addConsole(launch);
}
}
public void launchesChanged(ILaunch[] launches) {
}
public void launchesRemoved(ILaunch[] launches) {
for (ILaunch launch : launches) {
removeConsole(launch);
}
}
public void launchesTerminated(ILaunch[] launches) {
for (ILaunch launch : launches) {
// Since we already had a console, don't get rid of it
// just yet. Simply rename it to show it is terminated.
renameConsole(launch);
}
}
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(IGdbDebugPreferenceConstants.PREF_TRACES_ENABLE)) {
fTracingEnabled = (Boolean)event.getNewValue();
toggleTracing(fTracingEnabled);
}
}
protected void addConsole(ILaunch launch) {
// Tracing consoles are only added to ITracingLaunches
if (launch instanceof ITracedLaunch) {
// Make sure we didn't already add this console
if (getConsole(launch) == null) {
if (launch.isTerminated() == false) {
// Create and new tracing console.
TracingConsole console = new TracingConsole(launch, "gdb traces");
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{console});
} // else we don't display a new console for a terminated launch
}
}
}
protected void removeConsole(ILaunch launch) {
if (launch instanceof ITracedLaunch) {
TracingConsole console = getConsole(launch);
if (console != null) {
ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[]{console});
}
}
}
protected void renameConsole(ILaunch launch) {
if (launch instanceof ITracedLaunch) {
TracingConsole console = getConsole(launch);
if (console != null) {
console.resetName();
}
}
}
private TracingConsole getConsole(ILaunch launch) {
IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
IConsole[] consoles = manager.getConsoles();
for (IConsole console : consoles) {
if (console instanceof TracingConsole) {
TracingConsole tracingConsole = (TracingConsole)console;
if (tracingConsole.getLaunch().equals(launch)) {
return tracingConsole;
}
}
}
return null;
}
}