Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 208645 Details for
Bug 361934
Provide timeout for gdb commands
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Improved patch
Timeout.patch (text/plain), 81.60 KB, created by
Nobody - feel free to take it
on 2011-12-20 17:00:15 EST
(
hide
)
Description:
Improved patch
Filename:
MIME Type:
Creator:
Nobody - feel free to take it
Created:
2011-12-20 17:00:15 EST
Size:
81.60 KB
patch
obsolete
>From 8ee32271b891062ac9dc51f1b7de403345f837f7 Tue, 20 Dec 2011 16:35:06 -0500 >From: Mikhail Khodjaiants <mikhailkhod@googlemail.com> >Date: Tue, 20 Dec 2011 16:33:54 -0500 >Subject: [PATCH] Bug 361934 - Provide timeout for gdb commands > >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/wizban/adv_to_settings_wiz.png b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/wizban/adv_to_settings_wiz.png >new file mode 100755 >index 0000000..7229ca0 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/wizban/adv_to_settings_wiz.png >Binary files differ >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml >index 0f152c7..20d4fc4 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml >@@ -475,4 +475,13 @@ > </enablement> > </toggleTargetFactory> > </extension> >+ <extension >+ point="org.eclipse.debug.core.statusHandlers"> >+ <statusHandler >+ class="org.eclipse.cdt.dsf.gdb.internal.ui.GdbStatusHandler" >+ code="20001" >+ id="org.eclipse.cdt.dsf.gdb.ui.statusHandler" >+ plugin="org.eclipse.cdt.dsf.gdb"> >+ </statusHandler> >+ </extension> > </plugin> >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbStatusHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbStatusHandler.java >new file mode 100644 >index 0000000..3bbd639 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbStatusHandler.java >@@ -0,0 +1,66 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.internal.ui; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.debug.core.IStatusHandler; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Shell; >+ >+public class GdbStatusHandler implements IStatusHandler { >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.debug.core.IStatusHandler#handleStatus(org.eclipse.core.runtime.IStatus, java.lang.Object) >+ */ >+ @Override >+ public Object handleStatus( final IStatus status, Object source ) throws CoreException { >+ Runnable runnable = null; >+ if ( status.getSeverity() == IStatus.ERROR ) { >+ runnable = new Runnable() { >+ >+ @Override >+ public void run() { >+ Shell parent = GdbUIPlugin.getActiveWorkbenchShell(); >+ if ( parent != null ) >+ MessageDialog.openError( parent, Messages.GdbStatusHandler_Error, status.getMessage() ); >+ } >+ }; >+ } >+ else if ( status.getSeverity() == IStatus.WARNING ) { >+ runnable = new Runnable() { >+ >+ @Override >+ public void run() { >+ Shell parent = GdbUIPlugin.getActiveWorkbenchShell(); >+ if ( parent != null ) >+ MessageDialog.openWarning( parent, Messages.GdbStatusHandler_Warning, status.getMessage() ); >+ } >+ }; >+ } >+ else if ( status.getSeverity() == IStatus.INFO ) { >+ runnable = new Runnable() { >+ >+ @Override >+ public void run() { >+ Shell parent = GdbUIPlugin.getActiveWorkbenchShell(); >+ if ( parent != null ) >+ MessageDialog.openInformation( parent, Messages.GdbStatusHandler_Information, status.getMessage() ); >+ } >+ }; >+ } >+ if ( runnable != null ) >+ Display.getDefault().asyncExec( runnable ); >+ return null; >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java >index 2aedaeb..fc275cf 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java >@@ -22,6 +22,9 @@ > import org.eclipse.debug.core.ILaunch; > import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.preference.IPreferenceStore; >+import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.jface.resource.ImageRegistry; >+import org.eclipse.swt.graphics.Image; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.IWorkbenchPage; > import org.eclipse.ui.IWorkbenchWindow; >@@ -227,4 +230,32 @@ > } > } > >+ /* (non-Javadoc) >+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry) >+ */ >+ @Override >+ protected void initializeImageRegistry( ImageRegistry reg ) { >+ super.initializeImageRegistry( reg ); >+ declareImages( reg ); >+ } >+ >+ /** >+ * Returns an image descriptor for the image file at the given >+ * plug-in relative path >+ * >+ * @param path the path >+ * @return the image descriptor >+ */ >+ public static ImageDescriptor getImageDescriptor(String path) { >+ return imageDescriptorFromPlugin(PLUGIN_ID, path); >+ } >+ >+ public static Image getImage( String key ) { >+ return getDefault().getImageRegistry().get( key ); >+ } >+ >+ private void declareImages( ImageRegistry reg ) { >+ reg.put( IGdbUIConstants.IMG_WIZBAN_ADVANCED_TIMEOUT_SETTINGS, >+ getImageDescriptor( "icons/full/wizban/adv_to_settings_wiz.png" ) ); //$NON-NLS-1$ >+ } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/IGdbUIConstants.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/IGdbUIConstants.java >new file mode 100644 >index 0000000..3a10e92 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/IGdbUIConstants.java >@@ -0,0 +1,28 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.internal.ui; >+ >+/** >+ * @noimplement This interface is not intended to be implemented by clients. >+ * >+ * @since 4.1 >+ */ >+public interface IGdbUIConstants { >+ >+ /** >+ * Plug-in identifier (value <code>"org.eclipse.cdt.dsf.gdb.ui"</code>). >+ */ >+ public static final String PLUGIN_ID = GdbUIPlugin.PLUGIN_ID; >+ >+ /** image identifier. */ >+ public static final String IMG_WIZBAN_ADVANCED_TIMEOUT_SETTINGS = PLUGIN_ID + ".imageAdvancedTimeoutSettings"; //$NON-NLS-1$ >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/Messages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/Messages.java >new file mode 100644 >index 0000000..d2bcc33 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/Messages.java >@@ -0,0 +1,31 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.internal.ui; >+ >+import org.eclipse.osgi.util.NLS; >+ >+public class Messages extends NLS { >+ private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.gdb.internal.ui.Messages"; //$NON-NLS-1$ >+ >+ public static String GdbStatusHandler_Error; >+ >+ public static String GdbStatusHandler_Information; >+ >+ public static String GdbStatusHandler_Warning; >+ static { >+ // initialize resource bundle >+ NLS.initializeMessages( BUNDLE_NAME, Messages.class ); >+ } >+ >+ private Messages() { >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/Messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/Messages.properties >new file mode 100644 >index 0000000..df1647e >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/Messages.properties >@@ -0,0 +1,3 @@ >+GdbStatusHandler_Error=Error >+GdbStatusHandler_Information=Information >+GdbStatusHandler_Warning=Warning >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/GdbDebugPreferencePage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/GdbDebugPreferencePage.java >index 6993e02..62f0b6a 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/GdbDebugPreferencePage.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/GdbDebugPreferencePage.java >@@ -13,25 +13,60 @@ > package org.eclipse.cdt.dsf.gdb.internal.ui.preferences; > > import java.io.File; >+import java.util.LinkedList; >+import java.util.List; >+import java.util.Map; >+import java.util.Set; > >+import org.eclipse.cdt.dsf.debug.internal.ui.preferences.IntegerWithBooleanFieldEditor; > import org.eclipse.cdt.dsf.debug.internal.ui.preferences.StringWithBooleanFieldEditor; > import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; > import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; >-import org.eclipse.cdt.dsf.gdb.internal.ui.launching.LaunchUIMessages; >+import org.eclipse.cdt.dsf.gdb.internal.ui.IGdbUIConstants; >+import org.eclipse.cdt.dsf.gdb.service.command.CustomTimeoutsMap; >+import org.eclipse.jface.dialogs.IDialogConstants; >+import org.eclipse.jface.dialogs.TitleAreaDialog; > import org.eclipse.jface.preference.BooleanFieldEditor; > import org.eclipse.jface.preference.FieldEditorPreferencePage; > import org.eclipse.jface.preference.IPreferenceStore; > import org.eclipse.jface.preference.IntegerFieldEditor; > import org.eclipse.jface.preference.StringFieldEditor; >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.util.PropertyChangeEvent; >+import org.eclipse.jface.viewers.CellEditor; >+import org.eclipse.jface.viewers.ColumnLabelProvider; >+import org.eclipse.jface.viewers.ColumnViewer; >+import org.eclipse.jface.viewers.DoubleClickEvent; >+import org.eclipse.jface.viewers.EditingSupport; >+import org.eclipse.jface.viewers.ICellEditorListener; >+import org.eclipse.jface.viewers.ICellEditorValidator; >+import org.eclipse.jface.viewers.IDoubleClickListener; >+import org.eclipse.jface.viewers.ISelectionChangedListener; >+import org.eclipse.jface.viewers.IStructuredContentProvider; >+import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.SelectionChangedEvent; >+import org.eclipse.jface.viewers.StructuredSelection; >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.TableViewerColumn; >+import org.eclipse.jface.viewers.TextCellEditor; >+import org.eclipse.jface.viewers.Viewer; >+import org.eclipse.jface.window.Window; > import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.ControlAdapter; >+import org.eclipse.swt.events.ControlEvent; > import org.eclipse.swt.events.SelectionAdapter; > import org.eclipse.swt.events.SelectionEvent; >+import org.eclipse.swt.graphics.Rectangle; > import org.eclipse.swt.layout.GridData; > import org.eclipse.swt.layout.GridLayout; > import org.eclipse.swt.widgets.Button; > import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.FileDialog; > import org.eclipse.swt.widgets.Group; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableColumn; > import org.eclipse.ui.IWorkbench; > import org.eclipse.ui.IWorkbenchPreferencePage; > import org.eclipse.ui.PlatformUI; >@@ -41,6 +76,7 @@ > */ > @SuppressWarnings("restriction") > public class GdbDebugPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { >+ > /** > * A vehicle in order to be able to register a selection listener with > * a {@link BooleanFieldEditor}. >@@ -58,19 +94,418 @@ > } > } > >+ class AdvancedTimeoutSettingsDialog extends TitleAreaDialog { >+ >+ class CommandTimeoutEntry { >+ >+ String fCommand; >+ Integer fTimeout; >+ >+ CommandTimeoutEntry( String command, Integer timeout ) { >+ fCommand = command; >+ fTimeout = timeout; >+ } >+ } >+ >+ class CellEditorListener implements ICellEditorListener { >+ >+ CellEditor fEditor; >+ >+ public CellEditorListener( CellEditor editor ) { >+ super(); >+ fEditor = editor; >+ } >+ >+ @Override >+ public void editorValueChanged( boolean oldValidState, boolean newValidState ) { >+ if ( newValidState ) { >+ setErrorMessage( null ); >+ } >+ else { >+ setErrorMessage( fEditor.getErrorMessage() ); >+ } >+ updateDialogButtons(); >+ } >+ >+ @Override >+ public void cancelEditor() { >+ } >+ >+ @Override >+ public void applyEditorValue() { >+ validate(); >+ updateDialogButtons(); >+ } >+ }; >+ >+ abstract class AbstractEditingSupport extends EditingSupport { >+ >+ public AbstractEditingSupport( ColumnViewer viewer ) { >+ super( viewer ); >+ } >+ >+ @Override >+ protected void setValue( Object element, Object value ) { >+ if ( element instanceof CommandTimeoutEntry && value instanceof String ) { >+ if ( processValue( (CommandTimeoutEntry)element, (String)value ) ) { >+ fViewer.refresh( element ); >+ validate(); >+ updateDialogButtons(); >+ } >+ } >+ } >+ >+ @Override >+ protected Object getValue( Object element ) { >+ if ( element instanceof CommandTimeoutEntry ) { >+ return doGetValue( (CommandTimeoutEntry)element ); >+ } >+ return null; >+ } >+ >+ @Override >+ protected CellEditor getCellEditor( Object element ) { >+ final CellEditor editor = new TextCellEditor( (Composite)getViewer().getControl() ); >+ editor.setValidator( getValidator() ); >+ editor.addListener( new CellEditorListener( editor ) ); >+ return editor; >+ } >+ >+ @Override >+ protected boolean canEdit( Object element ) { >+ return ( element instanceof CommandTimeoutEntry ); >+ } >+ >+ abstract boolean processValue( CommandTimeoutEntry entry, String value ); >+ >+ abstract Object doGetValue( CommandTimeoutEntry entry ); >+ >+ abstract ICellEditorValidator getValidator(); >+ }; >+ >+ private TableViewer fViewer; >+ private Button fAddButton; >+ private Button fDeleteButton; >+ >+ private List<CommandTimeoutEntry> fEntries; >+ >+ final private ICellEditorValidator fCommandValidator = new ICellEditorValidator() { >+ >+ @Override >+ public String isValid( Object value ) { >+ if ( value instanceof String && ((String)value).trim().length() == 0 ) { >+ return MessagesForPreferences.GdbDebugPreferencePage_Command_field_can_not_be_empty; >+ } >+ return null; >+ } >+ }; >+ >+ final private ICellEditorValidator fTimeoutValidator = new ICellEditorValidator() { >+ >+ @Override >+ public String isValid( Object value ) { >+ if ( value instanceof String ) { >+ try { >+ int intValue = Integer.decode( (String)value ).intValue(); >+ if ( intValue < 0 ) >+ return MessagesForPreferences.GdbDebugPreferencePage_Timeout_value_can_not_be_negative; >+ } >+ catch( NumberFormatException e ) { >+ return MessagesForPreferences.GdbDebugPreferencePage_Invalid_timeout_value; >+ } >+ } >+ return null; >+ } >+ }; >+ >+ AdvancedTimeoutSettingsDialog( Shell parentShell, Set<Map.Entry<String, Integer>> entries ) { >+ super( parentShell ); >+ setShellStyle(getShellStyle() | SWT.RESIZE); >+ fEntries = new LinkedList<CommandTimeoutEntry>(); >+ for ( Map.Entry<String, Integer> entry : entries ) { >+ fEntries.add( new CommandTimeoutEntry( entry.getKey(), entry.getValue() ) ); >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite) >+ */ >+ @Override >+ protected Control createDialogArea( Composite parent ) { >+ getShell().setText( MessagesForPreferences.GdbDebugPreferencePage_Anvanced_Timeout_Settings ); >+ setTitle( MessagesForPreferences.GdbDebugPreferencePage_Advanced_timeout_dialog_title ); >+ setTitleImage( GdbUIPlugin.getImage( IGdbUIConstants.IMG_WIZBAN_ADVANCED_TIMEOUT_SETTINGS ) ); >+ setMessage( MessagesForPreferences.GdbDebugPreferencePage_Advanced_timeout_dialog_message ); >+ >+ Composite control = (Composite)super.createDialogArea( parent ); >+ Composite comp = new Composite( control, SWT.NONE ); >+ GridData gd = new GridData( SWT.FILL, SWT.FILL, true, true ); >+ comp.setLayout( new GridLayout( 2, false ) ); >+ comp.setLayoutData( gd ); >+ >+ fViewer = new TableViewer( comp, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER ); >+ final Table table = fViewer.getTable(); >+ gd = new GridData( SWT.FILL, SWT.FILL, true, true ); >+ table.setLayoutData( gd ); >+ >+ fViewer.addDoubleClickListener( new IDoubleClickListener() { >+ @Override >+ public void doubleClick( DoubleClickEvent event ) { >+ okPressed(); >+ } >+ } ); >+ >+ fViewer.addSelectionChangedListener( new ISelectionChangedListener() { >+ >+ @Override >+ public void selectionChanged( SelectionChangedEvent event ) { >+ updateDialogButtons(); >+ } >+ } ); >+ >+ Composite btnComp = new Composite( comp, SWT.NONE ); >+ btnComp.setLayout( new GridLayout() ); >+ btnComp.setLayoutData( new GridData( SWT.RIGHT, SWT.TOP, false, false ) ); >+ >+ fAddButton = new Button( btnComp, SWT.PUSH ); >+ fAddButton.setText( MessagesForPreferences.GdbDebugPreferencePage_Add_button ); >+ fAddButton.setFont( JFaceResources.getDialogFont() ); >+ setButtonLayoutData( fAddButton ); >+ fAddButton.addSelectionListener( new SelectionAdapter() { >+ >+ @Override >+ public void widgetSelected( SelectionEvent e ) { >+ addNewEntry(); >+ } >+ } ); >+ >+ fDeleteButton = new Button( btnComp, SWT.PUSH ); >+ fDeleteButton.setText( MessagesForPreferences.GdbDebugPreferencePage_Delete_button ); >+ fDeleteButton.setFont( JFaceResources.getDialogFont() ); >+ setButtonLayoutData( fDeleteButton ); >+ fDeleteButton.addSelectionListener( new SelectionAdapter() { >+ >+ @Override >+ public void widgetSelected( SelectionEvent e ) { >+ deleteEntries(); >+ } >+ } ); >+ >+ table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) ); >+ table.setHeaderVisible( true ); >+ table.setLinesVisible( true ); >+ >+ TableViewerColumn commandColumn = new TableViewerColumn( fViewer, SWT.LEFT ); >+ commandColumn.getColumn().setText( MessagesForPreferences.GdbDebugPreferencePage_Command_column_name ); >+ commandColumn.setLabelProvider( createCommandLabelProvider() ); >+ commandColumn.setEditingSupport( createCommandEditingSupport( fViewer ) ); >+ >+ TableViewerColumn timeoutColumn = new TableViewerColumn( fViewer, SWT.LEFT ); >+ timeoutColumn.getColumn().setText( MessagesForPreferences.GdbDebugPreferencePage_Timeout_column_name ); >+ timeoutColumn.setLabelProvider( createTimeoutLabelProvider() ); >+ timeoutColumn.setEditingSupport( createTimeoutEditingSupport( fViewer ) ); >+ >+ fViewer.setContentProvider( createCustomTimeoutsContentProvider() ); >+ >+ table.addControlListener( new ControlAdapter() { >+ >+ @Override >+ public void controlResized( ControlEvent e ) { >+ Rectangle area = table.getClientArea(); >+ if ( area.width > 0 ) { >+ TableColumn[] cols = table.getColumns(); >+ cols[0].setWidth( area.width * 50 / 100 ); >+ cols[1].setWidth( area.width * 50 / 100 ); >+ table.removeControlListener( this ); >+ } >+ } >+ } ); >+ >+ fViewer.setInput( fEntries ); >+ >+ updateDialogButtons(); >+ >+ return control; >+ } >+ >+ void updateDialogButtons() { >+ if ( fViewer != null && fDeleteButton != null ) { >+ fDeleteButton.setEnabled( !fViewer.getSelection().isEmpty() ); >+ } >+ Button okButton = getButton( IDialogConstants.OK_ID ); >+ if ( okButton != null ) >+ okButton.setEnabled( getErrorMessage() == null ); >+ } >+ >+ void addNewEntry() { >+ CommandTimeoutEntry newEntry = new CommandTimeoutEntry( "", Integer.valueOf( 0 ) ); //$NON-NLS-1$ >+ fEntries.add( newEntry ); >+ fViewer.refresh(); >+ fViewer.setSelection( new StructuredSelection( newEntry ) ); >+ validateEntry( newEntry ); >+ updateDialogButtons(); >+ fViewer.editElement( newEntry, 0 ); >+ } >+ >+ void deleteEntries() { >+ IStructuredSelection sel = (IStructuredSelection)fViewer.getSelection(); >+ if ( !sel.isEmpty() ) >+ fEntries.removeAll( sel.toList() ); >+ fViewer.refresh(); >+ validate(); >+ updateDialogButtons(); >+ } >+ >+ CustomTimeoutsMap getResult() { >+ CustomTimeoutsMap map = new CustomTimeoutsMap(); >+ for ( CommandTimeoutEntry entry : fEntries ) { >+ map.put( entry.fCommand, entry.fTimeout ); >+ } >+ return map; >+ } >+ >+ void validate() { >+ for ( CommandTimeoutEntry entry : fEntries ) { >+ validateEntry( entry ); >+ } >+ } >+ >+ void validateEntry( CommandTimeoutEntry entry ) { >+ String errorMessage = fCommandValidator.isValid( entry.fCommand ); >+ setErrorMessage( ( errorMessage != null ) ? >+ errorMessage : fTimeoutValidator.isValid( entry.fTimeout.toString() ) ); >+ } >+ >+ IStructuredContentProvider createCustomTimeoutsContentProvider() { >+ return new IStructuredContentProvider() { >+ >+ @Override >+ public void inputChanged( Viewer viewer, Object oldInput, Object newInput ) { >+ } >+ >+ @Override >+ public void dispose() { >+ } >+ >+ @Override >+ public Object[] getElements( Object inputElement ) { >+ if ( inputElement instanceof List<?> ) { >+ @SuppressWarnings( "unchecked" ) >+ List<CommandTimeoutEntry> list = (List<CommandTimeoutEntry>)inputElement; >+ return list.toArray( new Object[list.size()] ); >+ } >+ return null; >+ } >+ }; >+ } >+ >+ ColumnLabelProvider createCommandLabelProvider() { >+ return new ColumnLabelProvider() { >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) >+ */ >+ @Override >+ public String getText( Object element ) { >+ if ( element instanceof CommandTimeoutEntry ) { >+ return ((CommandTimeoutEntry)element).fCommand; >+ } >+ return super.getText( element ); >+ } >+ }; >+ } >+ >+ ColumnLabelProvider createTimeoutLabelProvider() { >+ return new ColumnLabelProvider() { >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) >+ */ >+ @Override >+ public String getText( Object element ) { >+ if ( element instanceof CommandTimeoutEntry ) { >+ return ((CommandTimeoutEntry)element).fTimeout.toString(); >+ } >+ return super.getText( element ); >+ } >+ }; >+ } >+ >+ EditingSupport createCommandEditingSupport( ColumnViewer viewer ) { >+ return new AbstractEditingSupport( viewer ) { >+ >+ @Override >+ boolean processValue( CommandTimeoutEntry entry, String value ) { >+ entry.fCommand = value; >+ return true; >+ } >+ >+ @Override >+ Object doGetValue( CommandTimeoutEntry entry ) { >+ return entry.fCommand; >+ } >+ >+ @Override >+ ICellEditorValidator getValidator() { >+ return fCommandValidator; >+ } >+ }; >+ } >+ >+ EditingSupport createTimeoutEditingSupport( ColumnViewer viewer ) { >+ return new AbstractEditingSupport( viewer ) { >+ >+ @Override >+ boolean processValue( CommandTimeoutEntry entry, String value ) { >+ try { >+ entry.fTimeout = Integer.decode( value ); >+ return true; >+ } >+ catch( NumberFormatException e ) { >+ // Shouldn't happen, validator takes care of this case. >+ } >+ return false; >+ } >+ >+ @Override >+ Object doGetValue( CommandTimeoutEntry entry ) { >+ return entry.fTimeout.toString(); >+ } >+ >+ @Override >+ ICellEditorValidator getValidator() { >+ return fTimeoutValidator; >+ } >+ }; >+ } >+ } >+ >+ private IntegerWithBooleanFieldEditor fCommandTimeoutField; >+ private Button fTimeoutAdvancedButton; >+ >+ private CustomTimeoutsMap fCustomTimeouts; >+ > public GdbDebugPreferencePage() { > super(FLAT); > IPreferenceStore store= GdbUIPlugin.getDefault().getPreferenceStore(); > setPreferenceStore(store); > setDescription(MessagesForPreferences.GdbDebugPreferencePage_description); >+ fCustomTimeouts = new CustomTimeoutsMap(); > } > > public void init(IWorkbench workbench) { > } > > @Override >+ protected void initialize() { >+ super.initialize(); >+ initializeCustomTimeouts(); >+ } >+ >+ @Override > public void createControl(Composite parent) { > super.createControl(parent); >+ updateTimeoutButtons(); > PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), > GdbUIPlugin.PLUGIN_ID + ".dsfgdb_preference_page"); //$NON-NLS-1$ > } >@@ -90,44 +525,46 @@ > > final StringFieldEditor stringFieldEditorCommand = new StringFieldEditor( > IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND, >- LaunchUIMessages.getString("GDBDebuggerPage.gdb_debugger"), //$NON-NLS-1$ >+ "GDB debugger:", //$NON-NLS-1$ > group1); > > stringFieldEditorCommand.fillIntoGrid(group1, 2); > addField(stringFieldEditorCommand); > Button browsebutton = new Button(group1, SWT.PUSH); >- browsebutton.setText(LaunchUIMessages.getString("GDBDebuggerPage.gdb_browse")); //$NON-NLS-1$ >+ browsebutton.setText("&Browse..."); //$NON-NLS-1$ > browsebutton.addSelectionListener(new SelectionAdapter() { > @Override > public void widgetSelected(SelectionEvent e) { >- handleBrowseButtonSelected(LaunchUIMessages.getString("GDBDebuggerPage.gdb_browse_dlg_title"), //$NON-NLS-1$ >+ handleBrowseButtonSelected("GDB Debugger", //$NON-NLS-1$ > stringFieldEditorCommand); > } > }); >+ setButtonLayoutData( browsebutton ); > > final StringFieldEditor stringFieldEditorGdbInit = new StringFieldEditor( > IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT, >- LaunchUIMessages.getString("GDBDebuggerPage.gdb_command_file"), //$NON-NLS-1$ >+ "GDB command file:", //$NON-NLS-1$ > group1); > > stringFieldEditorGdbInit.fillIntoGrid(group1, 2); > addField(stringFieldEditorGdbInit); > browsebutton = new Button(group1, SWT.PUSH); >- browsebutton.setText(LaunchUIMessages.getString("GDBDebuggerPage.gdb_browse")); //$NON-NLS-1$ >+ browsebutton.setText("&Browse..."); //$NON-NLS-1$ > browsebutton.addSelectionListener(new SelectionAdapter() { > @Override > public void widgetSelected(SelectionEvent e) { >- handleBrowseButtonSelected(LaunchUIMessages.getString("GDBDebuggerPage.gdb_cmdfile_dlg_title"), //$NON-NLS-1$ >+ handleBrowseButtonSelected("GDB Command File", //$NON-NLS-1$ > stringFieldEditorGdbInit); > } > }); >+ setButtonLayoutData( browsebutton ); > > final StringWithBooleanFieldEditor enableStopAtMain = new StringWithBooleanFieldEditor( > IGdbDebugPreferenceConstants.PREF_DEFAULT_STOP_AT_MAIN, > IGdbDebugPreferenceConstants.PREF_DEFAULT_STOP_AT_MAIN_SYMBOL, >- LaunchUIMessages.getString("CDebuggerTab.Stop_at_main_on_startup"), //$NON-NLS-1$ >+ "Stop on startup at:", //$NON-NLS-1$ > group1); >- enableStopAtMain.fillIntoGrid(group1, 2); >+ enableStopAtMain.fillIntoGrid(group1, 3); > addField(enableStopAtMain); > > // final StringFieldEditor stopAtMainSymbol = new StringFieldEditor( >@@ -144,9 +581,29 @@ > // } > // }); > >+ fCommandTimeoutField = new IntegerWithBooleanFieldEditor( >+ IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, >+ IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, >+ MessagesForPreferences.GdbDebugPreferencePage_Command_timeout, >+ group1); >+ fCommandTimeoutField.setValidRange(1, Integer.MAX_VALUE); >+ fCommandTimeoutField.fillIntoGrid(group1, 2); >+ addField(fCommandTimeoutField); >+ >+ fTimeoutAdvancedButton = new Button(group1, SWT.PUSH); >+ fTimeoutAdvancedButton.setText(MessagesForPreferences.GdbDebugPreferencePage_Advanced_button); >+ fTimeoutAdvancedButton.addSelectionListener(new SelectionAdapter() { >+ @Override >+ public void widgetSelected(SelectionEvent e) { >+ handleAdvancedButtonSelected( >+ "GDB Debugger"); //$NON-NLS-1$ >+ } >+ }); >+ setButtonLayoutData( fTimeoutAdvancedButton ); >+ > final ListenableBooleanFieldEditor enableNonStop= new ListenableBooleanFieldEditor( > IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP, >- LaunchUIMessages.getString("GDBDebuggerPage.nonstop_mode"), //$NON-NLS-1$ >+ "Non-stop mode (Note: Requires non-stop GDB)", //$NON-NLS-1$ > SWT.NONE, group1); > enableNonStop.fillIntoGrid(group1, 3); > addField(enableNonStop); >@@ -285,8 +742,56 @@ > stringFieldEditor.setStringValue(res); > } > >+ private void handleAdvancedButtonSelected(String dialogTitle) { >+ AdvancedTimeoutSettingsDialog dialog = >+ new AdvancedTimeoutSettingsDialog( getShell(), fCustomTimeouts.entrySet() ); >+ if ( dialog.open() == Window.OK ) { >+ fCustomTimeouts = dialog.getResult(); >+ } >+ } >+ > @Override > protected void adjustGridLayout() { > // do nothing > } >+ >+ @Override >+ public void propertyChange( PropertyChangeEvent event ) { >+ if ( event.getSource().equals( fCommandTimeoutField ) && event.getNewValue() instanceof Boolean ) { >+ fTimeoutAdvancedButton.setEnabled( ((Boolean)event.getNewValue()).booleanValue() ); >+ } >+ super.propertyChange( event ); >+ } >+ >+ @Override >+ protected void performDefaults() { >+ IPreferenceStore store = getPreferenceStore(); >+ if ( store != null ) { >+ String memento = store.getDefaultString( IGdbDebugPreferenceConstants.PREF_COMMAND_CUSTOM_TIMEOUTS ); >+ fCustomTimeouts.initializeFromMemento( memento ); >+ } >+ super.performDefaults(); >+ updateTimeoutButtons(); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performOk() >+ */ >+ @Override >+ public boolean performOk() { >+ getPreferenceStore().setValue( IGdbDebugPreferenceConstants.PREF_COMMAND_CUSTOM_TIMEOUTS, fCustomTimeouts.getMemento() ); >+ return super.performOk(); >+ } >+ >+ private void updateTimeoutButtons() { >+ fTimeoutAdvancedButton.setEnabled( fCommandTimeoutField.getBooleanValue() ); >+ } >+ >+ private void initializeCustomTimeouts() { >+ IPreferenceStore store = getPreferenceStore(); >+ if ( store != null ) { >+ String memento = store.getString( IGdbDebugPreferenceConstants.PREF_COMMAND_CUSTOM_TIMEOUTS ); >+ fCustomTimeouts.initializeFromMemento( memento ); >+ } >+ } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.java >index 43f3099..212b32b 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.java >@@ -17,6 +17,11 @@ > * Preference strings. > */ > class MessagesForPreferences extends NLS { >+ public static String GdbDebugPreferencePage_Add_button; >+ public static String GdbDebugPreferencePage_Advanced_button; >+ public static String GdbDebugPreferencePage_Advanced_timeout_dialog_message; >+ public static String GdbDebugPreferencePage_Advanced_timeout_dialog_title; >+ public static String GdbDebugPreferencePage_Anvanced_Timeout_Settings; > public static String GdbDebugPreferencePage_description; > public static String GdbDebugPreferencePage_traces_label; > public static String GdbDebugPreferencePage_enableTraces_label; >@@ -24,6 +29,9 @@ > public static String GdbDebugPreferencePage_maxGdbTraces_label; > public static String GdbDebugPreferencePage_termination_label; > public static String GdbDebugPreferencePage_autoTerminateGdb_label; >+ public static String GdbDebugPreferencePage_Command_column_name; >+ public static String GdbDebugPreferencePage_Command_field_can_not_be_empty; >+ public static String GdbDebugPreferencePage_Command_timeout; > public static String GdbDebugPreferencePage_hover_label; > public static String GdbDebugPreferencePage_useInspectorHover_label; > /** @since 2.2 */ >@@ -36,6 +44,10 @@ > public static String GdbDebugPreferencePage_initialChildCountLimitForCollections_label; > /** @since 2.2 */ > public static String GdbDebugPreferencePage_defaults_label; >+ public static String GdbDebugPreferencePage_Delete_button; >+ public static String GdbDebugPreferencePage_Invalid_timeout_value; >+ public static String GdbDebugPreferencePage_Timeout_column_name; >+ public static String GdbDebugPreferencePage_Timeout_value_can_not_be_negative; > static { > // initialize resource bundle > NLS.initializeMessages(MessagesForPreferences.class.getName(), MessagesForPreferences.class); >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.properties >index 849a567..7995404 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.properties >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/preferences/MessagesForPreferences.properties >@@ -10,6 +10,7 @@ > # Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121) > ############################################################################### > >+GdbDebugPreferencePage_Add_button=Add > GdbDebugPreferencePage_description=General settings for GDB Debugging > > GdbDebugPreferencePage_traces_label=Traces >@@ -17,6 +18,9 @@ > GdbDebugPreferencePage_maxGdbTraces_label=Limit GDB traces output (number of characters): > GdbDebugPreferencePage_termination_label=Termination > GdbDebugPreferencePage_autoTerminateGdb_label=Terminate GDB when last process exits >+GdbDebugPreferencePage_Command_column_name=GDB/MI Command >+GdbDebugPreferencePage_Command_field_can_not_be_empty='Command' field can not be empty >+GdbDebugPreferencePage_Command_timeout=Command timeout (ms): > > GdbDebugPreferencePage_hover_label=Debug Text Hover > GdbDebugPreferencePage_useInspectorHover_label=Use enhanced debug hover >@@ -27,3 +31,12 @@ > GdbDebugPreferencePage_initialChildCountLimitForCollections_label=For collections, initially limit child count to > > GdbDebugPreferencePage_defaults_label=Debug Configurations Defaults >+GdbDebugPreferencePage_Delete_button=Delete >+GdbDebugPreferencePage_Invalid_timeout_value=Invalid timeout value >+GdbDebugPreferencePage_Timeout_column_name=Timeout(ms) >+GdbDebugPreferencePage_Timeout_value_can_not_be_negative=Timeout value can not be negative >+ >+GdbDebugPreferencePage_Advanced_button=&Advanced... >+GdbDebugPreferencePage_Advanced_timeout_dialog_message=Specify commands and corresponding timeout values (use '0' for 'no timeout'). >+GdbDebugPreferencePage_Advanced_timeout_dialog_title=Add/delete/modify custom timeouts for GDB/MI commands >+GdbDebugPreferencePage_Anvanced_Timeout_Settings=Advanced Timeout Settings >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/.options b/dsf-gdb/org.eclipse.cdt.dsf.gdb/.options >index 28eeb8b..b9256ae 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/.options >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/.options >@@ -1 +1,2 @@ > org.eclipse.cdt.dsf.gdb/debug = false >+org.eclipse.cdt.dsf.gdb/debug/timeouts = false >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java >index c1ecd5e..8bac8d8 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java >@@ -23,12 +23,16 @@ > > public static final String PREFIX = GdbPlugin.PLUGIN_ID + "."; //$NON-NLS-1$ > >+ /** >+ * Status code for which a UI handler is registered. >+ * @since 4.1 >+ */ >+ public static final int STATUS_HANDLER_CODE = 20001; >+ > /** > * Attribute key to be added to the IProcess associated with an IMIContainerDMContext. > * The value should be the groupId as returned by {@link IMIContainerDMContext#getGroupId()} > */ > public static final String INFERIOR_GROUPID_ATTR = PREFIX + "inferiorGroupId"; //$NON-NLS-1$ >- >- > } > >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugPreferenceConstants.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugPreferenceConstants.java >index acc6243..5aca077 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugPreferenceConstants.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugPreferenceConstants.java >@@ -87,6 +87,30 @@ > public static final String PREF_DEFAULT_NON_STOP = "defaultNonStop"; //$NON-NLS-1$ > > /** >+ * The value is an boolean specifying whether the timeout is used for GDB commands. >+ * @since 4.1 >+ */ >+ public static final String PREF_COMMAND_TIMEOUT = "commandTimeout"; //$NON-NLS-1$ >+ >+ /** >+ * The value is an integer specifying the timeout value (milliseconds) for GDB commands. >+ * @since 4.1 >+ */ >+ public static final String PREF_COMMAND_TIMEOUT_VALUE = "commandTimeoutValue"; //$NON-NLS-1$ >+ >+ /** >+ * The value is a string specifying the list of GDB/MI commands with custom timeout values. >+ * @since 4.1 >+ */ >+ public static final String PREF_COMMAND_CUSTOM_TIMEOUTS = "commandTimeoutSpecials"; //$NON-NLS-1$ >+ >+ /** >+ * Default default value for <code>PREF_COMMAND_TIMEOUT</code>; >+ * @since 4.1 >+ */ >+ public static final int COMMAND_TIMEOUT_VALUE_DEFAULT = 10000; >+ >+ /** > * Help prefixes. > */ > public static final String PREFIX = GdbPlugin.PLUGIN_ID + "."; //$NON-NLS-1$ >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPreferenceInitializer.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPreferenceInitializer.java >index e9403f1..92d0a08 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPreferenceInitializer.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPreferenceInitializer.java >@@ -38,5 +38,7 @@ > node.putBoolean(IGdbDebugPreferenceConstants.PREF_DEFAULT_STOP_AT_MAIN, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT); > node.put(IGdbDebugPreferenceConstants.PREF_DEFAULT_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT); > node.putBoolean(IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP, IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT); >+ node.putBoolean(IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, false); >+ node.putInt(IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, IGdbDebugPreferenceConstants.COMMAND_TIMEOUT_VALUE_DEFAULT); > } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/Messages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/Messages.java >new file mode 100644 >index 0000000..9ffb413 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/Messages.java >@@ -0,0 +1,27 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.internal; >+ >+import org.eclipse.osgi.util.NLS; >+ >+public class Messages extends NLS { >+ private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.gdb.internal.Messages"; //$NON-NLS-1$ >+ >+ public static String DefaultGdbCommandTimeoutPolicy_Session_is_terminated; >+ static { >+ // initialize resource bundle >+ NLS.initializeMessages( BUNDLE_NAME, Messages.class ); >+ } >+ >+ private Messages() { >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/Messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/Messages.properties >new file mode 100644 >index 0000000..83e8828 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/Messages.properties >@@ -0,0 +1,12 @@ >+####################################################################################### >+# Copyright (c) 2011 Mentor Graphics 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: >+# Mentor Graphics - Initial API and implementation >+####################################################################################### >+ >+DefaultGdbCommandTimeoutPolicy_Session_is_terminated=Session is terminated.\nReason: %s >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java >index 699795a..498eb75 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java >@@ -35,6 +35,7 @@ > import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; > import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlockRetrieval; > import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; >+import org.eclipse.cdt.dsf.gdb.service.command.IGdbCommandTimeoutService.ICommandTimedOutDMEvent; > import org.eclipse.cdt.dsf.mi.service.IMIProcesses; > import org.eclipse.cdt.dsf.mi.service.MIProcesses; > import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess; >@@ -293,4 +294,12 @@ > } > super.launchRemoved(launch); > } >+ >+ /** >+ * @since 4.1 >+ */ >+ @DsfServiceEventHandler >+ public void eventDispatched(ICommandTimedOutDMEvent event) { >+ shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null)); >+ } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java >index 43e253a..120e16e 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java >@@ -25,10 +25,11 @@ > import org.eclipse.cdt.dsf.debug.service.IRegisters; > import org.eclipse.cdt.dsf.debug.service.IRunControl; > import org.eclipse.cdt.dsf.debug.service.ISourceLookup; >-import org.eclipse.cdt.dsf.debug.service.IStack; > import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; >+import org.eclipse.cdt.dsf.debug.service.IStack; > import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; > import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl; >+import org.eclipse.cdt.dsf.gdb.service.command.IGdbCommandTimeoutService; > import org.eclipse.cdt.dsf.mi.service.CSourceLookup; > import org.eclipse.cdt.dsf.mi.service.IMIBackend; > import org.eclipse.cdt.dsf.mi.service.IMIProcesses; >@@ -123,6 +124,16 @@ > requestMonitor.done(); > } > }}, >+ new Step() { @Override >+ public void execute(RequestMonitor requestMonitor) { >+ IGdbCommandTimeoutService timeoutService = fLaunch.getServiceFactory().createService(IGdbCommandTimeoutService.class, fSession); >+ // Note that for older versions of GDB, we don't support tracing, so there is no trace service. >+ if (timeoutService != null) { >+ timeoutService.initialize(requestMonitor); >+ } else { >+ requestMonitor.done(); >+ } >+ }}, > }; > > DsfSession fSession; >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java >index 8af2b96..1f32c5d 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java >@@ -29,6 +29,8 @@ > import org.eclipse.cdt.dsf.gdb.service.command.GDBControl; > import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0; > import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_2; >+import org.eclipse.cdt.dsf.gdb.service.command.GdbCommandTimeoutService; >+import org.eclipse.cdt.dsf.gdb.service.command.IGdbCommandTimeoutService; > import org.eclipse.cdt.dsf.mi.service.CSourceLookup; > import org.eclipse.cdt.dsf.mi.service.IMIBackend; > import org.eclipse.cdt.dsf.mi.service.MIBreakpoints; >@@ -83,12 +85,16 @@ > return (V)createBackendGDBService(session, (ILaunchConfiguration)arg); > } > } >- } else if (IGDBTraceControl.class.isAssignableFrom(clazz)) { >+ } >+ else if (IGDBTraceControl.class.isAssignableFrom(clazz)) { > for (Object arg : optionalArguments) { > if (arg instanceof ILaunchConfiguration) { > return (V)createTraceControlService(session, (ILaunchConfiguration)arg); > } > } >+ } >+ else if (IGdbCommandTimeoutService.class.isAssignableFrom(clazz)) { >+ return (V)createCommandTimeoutService(session); > } > > return super.createService(clazz, session); >@@ -205,4 +211,11 @@ > // in those older GDB versions. Also, gdbserver only supports tracing starting with 7.2 > return null; > } >+ >+ /** >+ * @since 4.1 >+ */ >+ protected IGdbCommandTimeoutService createCommandTimeoutService(DsfSession session) { >+ return new GdbCommandTimeoutService(session); >+ } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/CustomTimeoutsMap.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/CustomTimeoutsMap.java >new file mode 100644 >index 0000000..77cc518 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/CustomTimeoutsMap.java >@@ -0,0 +1,78 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.service.command; >+ >+import java.util.HashMap; >+import java.util.Map; >+import java.util.StringTokenizer; >+ >+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.MultiStatus; >+import org.eclipse.core.runtime.Status; >+ >+/** >+ * @since 4.1 >+ */ >+public class CustomTimeoutsMap extends HashMap<String, Integer> { >+ >+ public CustomTimeoutsMap() { >+ super(); >+ } >+ >+ public CustomTimeoutsMap( CustomTimeoutsMap map ) { >+ super( map ); >+ } >+ >+ private static final long serialVersionUID = -8281280275781904870L; >+ >+ public String getMemento() { >+ StringBuilder sb = new StringBuilder(); >+ for ( Map.Entry<String, Integer> entry : entrySet() ) { >+ sb.append( entry.getKey() ); >+ sb.append( ',' ); >+ sb.append( entry.getValue().intValue() ); >+ sb.append( ';' ); >+ } >+ return sb.toString(); >+ } >+ >+ public void initializeFromMemento( String memento ) { >+ clear(); >+ StringTokenizer st = new StringTokenizer( memento, ";" ); //$NON-NLS-1$ >+ MultiStatus ms = new MultiStatus( GdbPlugin.PLUGIN_ID, 0, "Error initializing custom timeouts", null ); >+ while( st.hasMoreTokens() ) { >+ String token = st.nextToken(); >+ String[] tokenParts = token.split( "," ); //$NON-NLS-1$ >+ if ( tokenParts.length == 2 && tokenParts[0].length() > 0 && tokenParts[0].length() > 0 ) { >+ try { >+ put( tokenParts[0], Integer.valueOf( tokenParts[1] ) ); >+ } >+ catch( NumberFormatException e ) { >+ ms.add( new Status( >+ IStatus.ERROR, >+ GdbPlugin.PLUGIN_ID, >+ String.format( "Invalid custom timeout value for '%s'.", tokenParts[0] ) ) ); >+ } >+ } >+ else { >+ ms.add( new Status( >+ IStatus.ERROR, >+ GdbPlugin.PLUGIN_ID, >+ "Invalid custom timeout data." ) ); >+ } >+ } >+ if ( !ms.isOK() ) { >+ GdbPlugin.getDefault().getLog().log( ms ); >+ } >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/DefaultGdbCommandTimeoutPolicy.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/DefaultGdbCommandTimeoutPolicy.java >new file mode 100644 >index 0000000..8563a89 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/DefaultGdbCommandTimeoutPolicy.java >@@ -0,0 +1,115 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.service.command; >+ >+import org.eclipse.cdt.dsf.concurrent.DsfRunnable; >+import org.eclipse.cdt.dsf.concurrent.RequestMonitor; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; >+import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants; >+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; >+import org.eclipse.cdt.dsf.gdb.internal.Messages; >+import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl; >+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.IStatus; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.debug.core.DebugPlugin; >+import org.eclipse.debug.core.IStatusHandler; >+ >+/** >+ * Default implementation of the command timeout policy. >+ * If a command is timed out it sets the command's status to >+ * 'error' and terminate the session. >+ * >+ * @since 4.1 >+ */ >+public class DefaultGdbCommandTimeoutPolicy implements ICommandTimeoutPolicy { >+ >+ private DsfSession fSession; >+ private AbstractMIControl fCommandControl; >+ >+ public DefaultGdbCommandTimeoutPolicy( DsfSession session, AbstractMIControl commandControl ) { >+ super(); >+ fSession = session; >+ fCommandControl = commandControl; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.gdb.service.command.ICommandTimeoutPolicy#commandTimedOut(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) >+ */ >+ @Override >+ public void commandTimedOut( ICommandToken token ) { >+ String commandText = token.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ final String errorMessage = String.format( "Command '%s' is timed out", commandText ); //$NON-NLS-1$ >+ fCommandControl.commandFailed( token, errorMessage ); >+ >+ fSession.getExecutor().execute( new DsfRunnable() { >+ >+ @Override >+ public void run() { >+ DsfServicesTracker tracker = new DsfServicesTracker( GdbPlugin.getBundleContext(), fSession.getId() ); >+ IGDBControl gdbControl = tracker.getService( IGDBControl.class ); >+ tracker.dispose(); >+ >+ if ( gdbControl != null ) { >+ gdbControl.terminate( new RequestMonitor( fSession.getExecutor(), null ) { >+ >+ @Override >+ protected void handleErrorOrWarning() { >+ GdbPlugin.getDefault().getLog().log( getStatus() ); >+ super.handleErrorOrWarning(); >+ }; >+ } ); >+ >+ // If the timeout occurs while the launch sequence is being executed the error >+ // will be reported using the launcher's error reporting mechanism. >+ if ( fCommandControl instanceof IGDBControlExtension >+ && ((IGDBControlExtension)fCommandControl).isInitialized() ) { >+ IStatus status = new Status( >+ IStatus.ERROR, >+ GdbPlugin.PLUGIN_ID, >+ IGdbDebugConstants.STATUS_HANDLER_CODE, >+ String.format( Messages.DefaultGdbCommandTimeoutPolicy_Session_is_terminated, errorMessage ), >+ null ); >+ IStatusHandler statusHandler = DebugPlugin.getDefault().getStatusHandler( status ); >+ if ( statusHandler != null ) { >+ try { >+ statusHandler.handleStatus( status, null ); >+ } >+ catch( CoreException e ) { >+ GdbPlugin.getDefault().getLog().log( e.getStatus() ); >+ } >+ } >+ } >+ } >+ } >+ } ); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.gdb.service.command.ICommandTimeoutPolicy#dispose() >+ */ >+ @Override >+ public void dispose() { >+ } >+ >+ protected DsfSession getSession() { >+ return fSession; >+ } >+ >+ protected AbstractMIControl getCommandControl() { >+ return fCommandControl; >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java >index 926b948..90974b4 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java >@@ -58,6 +58,7 @@ > import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; > 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.NullProgressMonitor; > import org.eclipse.core.runtime.Status; >@@ -72,7 +73,7 @@ > * - CLI console support,<br> > * - inferior process status tracking.<br> > */ >-public class GDBControl extends AbstractMIControl implements IGDBControl { >+public class GDBControl extends AbstractMIControl implements IGDBControl, IGDBControlExtension { > > /** > * Event indicating that the back end process has started. >@@ -105,6 +106,10 @@ > private AbstractCLIProcess fCLIProcess; > > private boolean fTerminated; >+ >+ private Sequence fInitializationSequence; >+ >+ private boolean fInitialized = false; > > /** > * @since 3.0 >@@ -282,20 +287,22 @@ > } catch (CoreException e) {} > > // We need a RequestMonitorWithProgress, if we don't have one, we create one. >- RequestMonitorWithProgress progressRm; >- if (rm instanceof RequestMonitorWithProgress) { >- progressRm = (RequestMonitorWithProgress)rm; >- } else { >- progressRm = new RequestMonitorWithProgress(getExecutor(), new NullProgressMonitor()) { >- @Override >- protected void handleCompleted() { >- rm.setStatus(getStatus()); >- rm.done(); >- } >- }; >- } >+ IProgressMonitor monitor = (rm instanceof RequestMonitorWithProgress) ? >+ ((RequestMonitorWithProgress)rm).getProgressMonitor() : new NullProgressMonitor(); >+ RequestMonitorWithProgress progressRm = new RequestMonitorWithProgress(getExecutor(), monitor) { >+ >+ @Override >+ protected void handleCompleted() { >+ fInitializationSequence = null; >+ fInitialized = true; >+ rm.setStatus(getStatus()); >+ rm.done(); >+ } >+ }; > >- ImmediateExecutor.getInstance().execute(getCompleteInitializationSequence(attributes, progressRm)); >+ fInitializationSequence = getCompleteInitializationSequence(attributes, progressRm); >+ >+ ImmediateExecutor.getInstance().execute(fInitializationSequence); > } > > /** >@@ -459,4 +466,12 @@ > public void setPrintPythonErrors(boolean enabled, RequestMonitor rm) { > rm.done(); > } >+ >+ /** >+ * @since 4.1 >+ */ >+ @Override >+ public boolean isInitialized() { >+ return fInitialized; >+ } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java >index 09c8cce..d23b6fe 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java >@@ -56,6 +56,7 @@ > import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; > 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.NullProgressMonitor; > import org.eclipse.core.runtime.Status; >@@ -70,7 +71,7 @@ > * - CLI console support,<br> > * - inferior process status tracking.<br> > */ >-public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { >+public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl, IGDBControlExtension { > > /** > * Event indicating that the back end process has started. >@@ -105,6 +106,10 @@ > private List<String> fFeatures = new ArrayList<String>(); > > private boolean fTerminated; >+ >+ private Sequence fInitializationSequence; >+ >+ private boolean fInitialized = false; > > /** > * @since 3.0 >@@ -295,20 +300,22 @@ > } catch (CoreException e) {} > > // We need a RequestMonitorWithProgress, if we don't have one, we create one. >- RequestMonitorWithProgress progressRm; >- if (rm instanceof RequestMonitorWithProgress) { >- progressRm = (RequestMonitorWithProgress)rm; >- } else { >- progressRm = new RequestMonitorWithProgress(getExecutor(), new NullProgressMonitor()) { >- @Override >- protected void handleCompleted() { >- rm.setStatus(getStatus()); >- rm.done(); >- } >- }; >- } >+ IProgressMonitor monitor = (rm instanceof RequestMonitorWithProgress) ? >+ ((RequestMonitorWithProgress)rm).getProgressMonitor() : new NullProgressMonitor(); >+ RequestMonitorWithProgress progressRm = new RequestMonitorWithProgress(getExecutor(), monitor) { >+ >+ @Override >+ protected void handleCompleted() { >+ fInitializationSequence = null; >+ fInitialized = true; >+ rm.setStatus(getStatus()); >+ rm.done(); >+ } >+ }; > >- ImmediateExecutor.getInstance().execute(getCompleteInitializationSequence(attributes, progressRm)); >+ fInitializationSequence = getCompleteInitializationSequence(attributes, progressRm); >+ >+ ImmediateExecutor.getInstance().execute(fInitializationSequence); > } > > /** >@@ -487,4 +494,12 @@ > getCommandFactory().createCLIMaintenance(fControlDmc, subCommand), > new DataRequestMonitor<MIInfo>(getExecutor(), rm)); > } >+ >+ /** >+ * @since 4.1 >+ */ >+ @Override >+ public boolean isInitialized() { >+ return fInitialized; >+ } > } >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GdbCommandTimeoutService.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GdbCommandTimeoutService.java >new file mode 100644 >index 0000000..8d8bc78 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GdbCommandTimeoutService.java >@@ -0,0 +1,472 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.service.command; >+ >+import java.util.Hashtable; >+import java.util.concurrent.BlockingQueue; >+import java.util.concurrent.LinkedBlockingQueue; >+ >+import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; >+import org.eclipse.cdt.dsf.concurrent.RequestMonitor; >+import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; >+import org.eclipse.cdt.dsf.debug.service.command.ICommand; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandResult; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; >+import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; >+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; >+import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl; >+import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand; >+import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; >+import org.eclipse.cdt.dsf.service.AbstractDsfService; >+import org.eclipse.cdt.dsf.service.DsfSession; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.core.runtime.preferences.IEclipsePreferences; >+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; >+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; >+import org.eclipse.core.runtime.preferences.InstanceScope; >+import org.osgi.framework.BundleContext; >+ >+/** >+ * Command timeout service. Registers itself as a command listener and monitors >+ * the execution time. If the execution of a command takes more time than expected >+ * the service activates the timeout policy {@link ICommandTimeoutPolicy}. >+ * >+ * @since 4.1 >+ */ >+public class GdbCommandTimeoutService extends AbstractDsfService implements IGdbCommandTimeoutService, IPreferenceChangeListener { >+ >+ public final static boolean DEBUG = "true".equals( Platform.getDebugOption( "org.eclipse.cdt.dsf.gdb/debug/timeouts" ) ); //$NON-NLS-1$//$NON-NLS-2$ >+ >+ class CommandTimedOutDMEvent extends AbstractDMEvent<ICommandControlDMContext> implements ICommandTimedOutDMEvent { >+ >+ private ICommandToken fCommandToken; >+ >+ CommandTimedOutDMEvent( ICommandControlDMContext context, ICommandToken commandToken ) { >+ super( context ); >+ fCommandToken = commandToken; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.gdb.service.command.IGdbCommandTimeoutService.ICommandTimedOutDMEvent#getCommand() >+ */ >+ @Override >+ public ICommandToken getCommand() { >+ return fCommandToken; >+ } >+ } >+ >+ class QueueEntry { >+ long fTimestamp; >+ ICommandToken fCommandToken; >+ >+ QueueEntry( long timestamp, ICommandToken commandToken ) { >+ super(); >+ fTimestamp = timestamp; >+ fCommandToken = commandToken; >+ } >+ >+ /* (non-Javadoc) >+ * @see java.lang.Object#equals(java.lang.Object) >+ */ >+ @Override >+ public boolean equals( Object obj ) { >+ // We purposely ignore the timestamp here to make the removing >+ // of a command token from the queue simple. >+ // See org.eclipse.cdt.dsf.gdb.service.command.GdbCommandTimeoutService#commandRemoved() >+ // and org.eclipse.cdt.dsf.gdb.service.command.GdbCommandTimeoutService#commandDone(). >+ if ( obj instanceof QueueEntry ) { >+ return fCommandToken.equals( ((QueueEntry)obj).fCommandToken ); >+ } >+ return false; >+ } >+ } >+ >+ enum TimerThreadState { >+ INITIALIZING, >+ RUNNING, >+ HALTED, >+ SHUTDOWN >+ } >+ >+ /** >+ * >+ */ >+ class TimerThread extends Thread { >+ >+ private BlockingQueue<QueueEntry> fQueue; >+ private int fWaitTimeout = IGdbDebugPreferenceConstants.COMMAND_TIMEOUT_VALUE_DEFAULT; >+ private TimerThreadState fState = TimerThreadState.INITIALIZING; >+ >+ TimerThread( BlockingQueue<QueueEntry> queue, int timeout ) { >+ super(); >+ fQueue = queue; >+ setWaitTimout( timeout ); >+ } >+ >+ /* (non-Javadoc) >+ * @see java.lang.Thread#run() >+ */ >+ @Override >+ public void run() { >+ setState( ( getWaitTimeout() > 0 ) ? >+ TimerThreadState.RUNNING : TimerThreadState.HALTED ); >+ doRun(); >+ } >+ >+ private void doRun() { >+ if ( fState == TimerThreadState.HALTED ) { >+ halted(); >+ } >+ else { >+ running(); >+ } >+ } >+ >+ private void halted() { >+ try { >+ synchronized( TimerThread.this ) { >+ wait(); >+ } >+ } >+ catch( InterruptedException e ) { >+ doRun(); >+ } >+ } >+ >+ private void running() { >+ try { >+ while( fState == TimerThreadState.RUNNING ) { >+ long timeout = getWaitTimeout(); >+ QueueEntry entry = fQueue.peek(); >+ if ( entry != null ) { >+ // Calculate the time elapsed since the execution of this command started >+ // and compare it with the command's timeout value. >+ // If the elapsed time is greater or equal than the timeout value the command >+ // is marked as timed out. Otherwise, schedule the next check when the timeout >+ // expires. >+ long commandTimeout = getTimeoutForCommand( entry.fCommandToken.getCommand() ); >+ >+ if ( DEBUG ) { >+ String commandText = entry.fCommandToken.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ printDebugMessage( String.format( "Processing command '%s', command timeout is %d", //$NON-NLS-1$ >+ commandText, Long.valueOf( commandTimeout ) ) ); >+ } >+ >+ long elapsedTime = System.currentTimeMillis() - entry.fTimestamp; >+ if ( commandTimeout <= elapsedTime ) { >+ processTimedOutCommand( entry.fCommandToken ); >+ fQueue.remove( entry ); >+ } >+ else { >+ timeout = Math.min( timeout, commandTimeout - elapsedTime ); >+ >+ if ( DEBUG ) { >+ String commandText = entry.fCommandToken.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ printDebugMessage( String.format( "Setting timeout %d for command '%s'", Long.valueOf( timeout ), commandText ) ); //$NON-NLS-1$ >+ } >+ } >+ } >+ synchronized( TimerThread.this ) { >+ wait( timeout ); >+ } >+ if ( isInterrupted() ) { >+ doRun(); >+ } >+ } >+ } >+ catch( InterruptedException e ) { >+ doRun(); >+ } >+ } >+ >+ void shutdown() { >+ setState( TimerThreadState.SHUTDOWN ); >+ interrupt(); >+ } >+ >+ void haltProcessing() { >+ setState( TimerThreadState.HALTED ); >+ interrupt(); >+ } >+ >+ void resumeProcessing() { >+ setState( TimerThreadState.RUNNING ); >+ interrupt(); >+ } >+ >+ void setWaitTimout( int waitTimeout ) { >+ fWaitTimeout = waitTimeout; >+ if ( DEBUG ) >+ printDebugMessage( String.format( "Wait timeout is set to %d", Integer.valueOf( fWaitTimeout ) ) ); //$NON-NLS-1$ >+ } >+ >+ int getWaitTimeout() { >+ return fWaitTimeout; >+ } >+ >+ void setState( TimerThreadState state ) { >+ fState = state; >+ } >+ } >+ >+ private AbstractMIControl fCommandControl; >+ private ICommandTimeoutPolicy fTimeoutPolicy; >+ private int fTimeout = 30; >+ private TimerThread fTimerThread; >+ private BlockingQueue<QueueEntry> fCommandQueue = new LinkedBlockingQueue<QueueEntry>(); >+ private CustomTimeoutsMap fCustomTimeouts = new CustomTimeoutsMap(); >+ >+ public GdbCommandTimeoutService( DsfSession session ) { >+ super( session ); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor) >+ */ >+ @Override >+ public void initialize( final RequestMonitor requestMonitor ) { >+ super.initialize( new RequestMonitor( ImmediateExecutor.getInstance(), requestMonitor ) { >+ @Override >+ protected void handleSuccess() { >+ doInitialize( requestMonitor ); >+ } >+ } ); >+ } >+ >+ private void doInitialize( final RequestMonitor requestMonitor ) { >+ fCommandControl = getServicesTracker().getService( AbstractMIControl.class ); >+ if ( fCommandControl != null ) { >+ IEclipsePreferences node = InstanceScope.INSTANCE.getNode( GdbPlugin.PLUGIN_ID ); >+ >+ fTimeout = Platform.getPreferencesService().getInt( >+ GdbPlugin.PLUGIN_ID, >+ IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, >+ IGdbDebugPreferenceConstants.COMMAND_TIMEOUT_VALUE_DEFAULT, >+ null ); >+ >+ fCustomTimeouts.initializeFromMemento( Platform.getPreferencesService().getString( >+ GdbPlugin.PLUGIN_ID, >+ IGdbDebugPreferenceConstants.PREF_COMMAND_CUSTOM_TIMEOUTS, >+ "", //$NON-NLS-1$ >+ null ) ); >+ >+ node.addPreferenceChangeListener( this ); >+ >+ fCommandControl.addCommandListener( this ); >+ >+ fTimeoutPolicy = getTimeoutPolicy(); >+ >+ fTimerThread = new TimerThread( fCommandQueue, calculateWaitTimeout() ); >+ fTimerThread.start(); >+ } >+ >+ register( >+ new String[] { >+ IGdbCommandTimeoutService.class.getName(), >+ GdbCommandTimeoutService.class.getName(), >+ }, >+ new Hashtable<String, String>() ); >+ >+ requestMonitor.done(); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.service.AbstractDsfService#shutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor) >+ */ >+ @Override >+ public void shutdown( RequestMonitor rm ) { >+ if ( fCommandControl != null ) { >+ fTimerThread.shutdown(); >+ InstanceScope.INSTANCE.getNode( GdbPlugin.PLUGIN_ID ).removePreferenceChangeListener( this ); >+ fCommandControl.removeCommandListener( this ); >+ fCommandQueue.clear(); >+ fCustomTimeouts.clear(); >+ if ( fTimeoutPolicy != null ) { >+ fTimeoutPolicy.dispose(); >+ } >+ } >+ super.shutdown( rm ); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandQueued(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) >+ */ >+ @Override >+ public void commandQueued( ICommandToken token ) { >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandSent(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) >+ */ >+ @Override >+ public void commandSent( ICommandToken token ) { >+ int commandTimeout = getTimeoutForCommand( token.getCommand() ); >+ if ( DEBUG ) { >+ String commandText = token.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ printDebugMessage( String.format( "Command '%s' sent, timeout = %d", commandText, Integer.valueOf( commandTimeout ) ) ); //$NON-NLS-1$ >+ } >+ if ( commandTimeout == 0 ) >+ // Skip commands with no timeout >+ return; >+ try { >+ fCommandQueue.put( new QueueEntry( System.currentTimeMillis(), token ) ); >+ } >+ catch( InterruptedException e ) { >+ // ignore >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandRemoved(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) >+ */ >+ @Override >+ public void commandRemoved( ICommandToken token ) { >+ fCommandQueue.remove( new QueueEntry( 0, token ) ); >+ if ( DEBUG ) { >+ String commandText = token.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ printDebugMessage( String.format( "Command '%s' removed", commandText ) ); //$NON-NLS-1$ >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandDone(org.eclipse.cdt.dsf.debug.service.command.ICommandToken, org.eclipse.cdt.dsf.debug.service.command.ICommandResult) >+ */ >+ @Override >+ public void commandDone( ICommandToken token, ICommandResult result ) { >+ fCommandQueue.remove( new QueueEntry( 0, token ) ); >+ if ( DEBUG ) { >+ String commandText = token.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ printDebugMessage( String.format( "Command '%s' done", commandText ) ); //$NON-NLS-1$ >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) >+ */ >+ @Override >+ public void preferenceChange( PreferenceChangeEvent event ) { >+ String property = event.getKey(); >+ if ( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT.equals( property ) ) { >+ if ( event.getNewValue() == null || !event.getNewValue().equals( event.getOldValue() ) ) { >+ updateWaitTimeout(); >+ fTimerThread.setState( ( fTimerThread.getWaitTimeout() > 0 ) ? >+ TimerThreadState.RUNNING : TimerThreadState.HALTED ); >+ fTimerThread.interrupt(); >+ } >+ } >+ else if ( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE.equals( property ) ) { >+ if ( !event.getNewValue().equals( event.getOldValue() ) ) { >+ try { >+ fTimeout = Integer.parseInt( event.getNewValue().toString() ); >+ updateWaitTimeout(); >+ fTimerThread.setState( ( fTimerThread.getWaitTimeout() > 0 ) ? >+ TimerThreadState.RUNNING : TimerThreadState.HALTED ); >+ fTimerThread.interrupt(); >+ } >+ catch( NumberFormatException e ) { >+ GdbPlugin.getDefault().getLog().log( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Invlaid timeout value" ) ); //$NON-NLS-1$ >+ } >+ } >+ } >+ else if ( IGdbDebugPreferenceConstants.PREF_COMMAND_CUSTOM_TIMEOUTS.equals( property ) ) { >+ if ( event.getNewValue() instanceof String ) { >+ fCustomTimeouts.initializeFromMemento( (String)event.getNewValue() ); >+ } >+ else if ( event.getNewValue() == null ) { >+ fCustomTimeouts.clear(); >+ } >+ updateWaitTimeout(); >+ fTimerThread.setState( ( fTimerThread.getWaitTimeout() > 0 ) ? >+ TimerThreadState.RUNNING : TimerThreadState.HALTED ); >+ fTimerThread.interrupt(); >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.cdt.dsf.service.AbstractDsfService#getBundleContext() >+ */ >+ @Override >+ protected BundleContext getBundleContext() { >+ return GdbPlugin.getBundleContext(); >+ } >+ >+ protected int getTimeoutForCommand( ICommand<? extends ICommandResult> command ) { >+ if ( !(command instanceof MICommand<?>) ) >+ return 0; >+ @SuppressWarnings( "unchecked" ) >+ Integer timeout = fCustomTimeouts.get( ((MICommand<? extends MIInfo>)command).getOperation() ); >+ return ( timeout != null ) ? timeout.intValue() : fTimeout; >+ } >+ >+ protected void processTimedOutCommand( ICommandToken token ) { >+ if ( DEBUG ) { >+ String commandText = token.getCommand().toString(); >+ if ( commandText.endsWith( "\n" ) ) //$NON-NLS-1$ >+ commandText = commandText.substring( 0, commandText.length() - 1 ); >+ printDebugMessage( String.format( "Command '%s' is timed out", commandText ) ); //$NON-NLS-1$ >+ } >+ >+ if ( fTimeoutPolicy != null ) { >+ fTimeoutPolicy.commandTimedOut( token ); >+ } >+ >+ getSession().dispatchEvent( >+ new CommandTimedOutDMEvent( fCommandControl.getContext(), token ), >+ getProperties() ); >+ } >+ >+ private void updateWaitTimeout() { >+ fTimerThread.setWaitTimout( calculateWaitTimeout() ); >+ } >+ >+ private boolean isTimeoutEnabled() { >+ return Platform.getPreferencesService().getBoolean( >+ GdbPlugin.PLUGIN_ID, >+ IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, >+ false, >+ null ); >+ } >+ >+ protected ICommandTimeoutPolicy getTimeoutPolicy() { >+ return new DefaultGdbCommandTimeoutPolicy( getSession(), fCommandControl ); >+ } >+ >+ private void printDebugMessage( String message ) { >+ System.out.println( String.format( "[%s] %s", GdbPlugin.getDebugTime(), message ) ); //$NON-NLS-1$ >+ } >+ >+ private int calculateWaitTimeout() { >+ int waitTimeout = 0; >+ if ( isTimeoutEnabled() ) { >+ waitTimeout = fTimeout; >+ for ( Integer t : fCustomTimeouts.values() ) { >+ if ( t.intValue() > 0 ) { >+ waitTimeout = Math.min( waitTimeout, t.intValue() ); >+ } >+ } >+ } >+ return waitTimeout; >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/ICommandTimeoutPolicy.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/ICommandTimeoutPolicy.java >new file mode 100644 >index 0000000..0dcc004 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/ICommandTimeoutPolicy.java >@@ -0,0 +1,24 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.service.command; >+ >+import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; >+ >+/** >+ * @since 4.1 >+ */ >+public interface ICommandTimeoutPolicy { >+ >+ public void commandTimedOut( ICommandToken token ); >+ >+ public void dispose(); >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControlExtension.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControlExtension.java >new file mode 100644 >index 0000000..bafeeef >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControlExtension.java >@@ -0,0 +1,20 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.service.command; >+ >+/** >+ * @since 4.1 >+ */ >+public interface IGDBControlExtension extends IGDBControl { >+ >+ boolean isInitialized(); >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGdbCommandTimeoutService.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGdbCommandTimeoutService.java >new file mode 100644 >index 0000000..1ed61e5 >--- /dev/null >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGdbCommandTimeoutService.java >@@ -0,0 +1,35 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Mentor Graphics 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: >+ * Mentor Graphics - Initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.cdt.dsf.gdb.service.command; >+ >+import org.eclipse.cdt.dsf.datamodel.IDMEvent; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandListener; >+import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; >+import org.eclipse.cdt.dsf.service.IDsfService; >+ >+/** >+ * @since 4.1 >+ */ >+public interface IGdbCommandTimeoutService extends IDsfService, ICommandListener { >+ >+ /** >+ * Indicates that a command in the given command control is timed out. >+ */ >+ public interface ICommandTimedOutDMEvent extends IDMEvent<ICommandControlDMContext> { >+ >+ /** >+ * Returns the command that is timed out. >+ */ >+ ICommandToken getCommand(); >+ } >+} >diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractMIControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractMIControl.java >index 33bb3e2..86cbf5d 100644 >--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractMIControl.java >+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractMIControl.java >@@ -1063,4 +1063,57 @@ > fCurrentStackLevel = -1; > } > >+ /** >+ * @since 4.1 >+ */ >+ public void commandFailed(ICommandToken token, String errorMessage) { >+ if ( !(token instanceof CommandHandle && token.getCommand() instanceof MICommand<?>) ) >+ return; >+ final CommandHandle commandHandle = (CommandHandle)token; >+ Integer tokenId = commandHandle.getTokenId(); >+ >+ MIConst value = new MIConst(); >+ value.setCString( errorMessage ); >+ MIResult result = new MIResult(); >+ result.setVariable( "msg" ); //$NON-NLS-1$ >+ result.setMIValue( value ); >+ MIResultRecord resultRecord = new MIResultRecord(); >+ resultRecord.setToken( tokenId.intValue() ); >+ resultRecord.setResultClass( MIResultRecord.ERROR ); >+ resultRecord.setMIResults( new MIResult[] { result } ); >+ MIOutput miOutput = new MIOutput( resultRecord, new MIOOBRecord[0] ); >+ >+ final MIInfo info = commandHandle.getCommand().getResult(miOutput); >+ DataRequestMonitor<MIInfo> rm = commandHandle.getRequestMonitor(); >+ >+ if ( rm != null ) { >+ rm.setData(info); >+ rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, errorMessage)); >+ >+ /* >+ * We need to complete the command on the DSF thread for data security. >+ */ >+ getExecutor().execute(new DsfRunnable() { >+ @Override >+ public void run() { >+ /* >+ * Complete the specific command. >+ */ >+ if (commandHandle.getRequestMonitor() != null) { >+ commandHandle.getRequestMonitor().done(); >+ } >+ >+ /* >+ * Now tell the generic listeners about it. >+ */ >+ processCommandDone(commandHandle, info); >+ } >+ >+ @Override >+ public String toString() { >+ return "MI command output received for: " + commandHandle.getCommand(); //$NON-NLS-1$ >+ } >+ }); >+ } >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
nobody
:
iplog-
Actions:
View
|
Diff
Attachments on
bug 361934
:
205924
|
206262
|
206328
|
208645
|
210213
|
210215
|
210604
|
210934
|
213410