| /******************************************************************************* |
| * Copyright (c) 2008, 2020 QNX Software Systems and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * QNX Software Systems - Initial API and implementation |
| * Ericsson - Modified for DSF |
| * Sergey Prigogin (Google) |
| * Marc Khouzam (Ericsson) - Support for fast tracepoints (Bug 346320) |
| * Intel Corporation - Added Reverse Debugging BTrace support |
| *******************************************************************************/ |
| package org.eclipse.cdt.dsf.gdb.internal.ui.launching; |
| |
| import java.io.File; |
| import java.util.Observable; |
| import java.util.Observer; |
| |
| import org.eclipse.cdt.debug.ui.AbstractCDebuggerPage; |
| import org.eclipse.cdt.dsf.gdb.IGDBFlatpakLaunchConstants; |
| import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; |
| import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; |
| import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; |
| import org.eclipse.cdt.utils.ui.controls.ControlFactory; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CTabFolder; |
| import org.eclipse.swt.custom.CTabItem; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Combo; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * The dynamic tab for gdb-based debugger implementations. |
| */ |
| public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer { |
| protected CTabFolder fTabFolder; |
| protected Text fGDBCommandText; |
| protected Text fGDBInitText; |
| protected Button fNonStopCheckBox; |
| |
| protected Button fReverseCheckBox; |
| protected Combo fReverseDebugMode; |
| protected static final String HW_REVERSE_MODE = LaunchUIMessages |
| .getString("GDBDebuggerPage.reverse_Debuggingmodehard"); //$NON-NLS-1$ |
| protected static final String SW_REVERSE_MODE = LaunchUIMessages |
| .getString("GDBDebuggerPage.reverse_Debuggingmodesoft"); //$NON-NLS-1$ |
| |
| protected Button fUpdateThreadlistOnSuspend; |
| protected Button fDebugOnFork; |
| |
| protected Text fGDBServerCommandText; |
| protected Text fGDBServerPortNumberText; |
| protected Button fRemoteTimeoutEnabledCheckbox; |
| protected Text fRemoteTimeoutValueText; |
| |
| /** |
| * Checkbox for using GDB's new-console -- only displayed on Windows. Will be null if unsupported. |
| */ |
| private Button fExternalConsole; |
| |
| /** |
| * A combo box to let the user choose if fast tracepoints should be used or not. |
| */ |
| protected Combo fTracepointModeCombo; |
| protected static final String TP_FAST_ONLY = LaunchUIMessages.getString("GDBDebuggerPage.tracepoint_mode_fast"); //$NON-NLS-1$ |
| protected static final String TP_NORMAL_ONLY = LaunchUIMessages.getString("GDBDebuggerPage.tracepoint_mode_normal"); //$NON-NLS-1$ |
| protected static final String TP_AUTOMATIC = LaunchUIMessages.getString("GDBDebuggerPage.tracepoint_mode_auto"); //$NON-NLS-1$ |
| |
| private IMILaunchConfigurationComponent fSolibBlock; |
| private boolean fIsInitializing = false; |
| |
| @Override |
| public void createControl(Composite parent) { |
| Composite comp = new Composite(parent, SWT.NONE); |
| comp.setLayout(new GridLayout()); |
| comp.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| fTabFolder = new CTabFolder(comp, SWT.NONE); |
| fTabFolder.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL)); |
| createTabs(fTabFolder); |
| fTabFolder.setSelection(0); |
| setControl(parent); |
| } |
| |
| @Override |
| public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { |
| IPreferenceStore preferenceStore = GdbUIPlugin.getDefault().getPreferenceStore(); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, |
| preferenceStore.getString(IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND)); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, |
| preferenceStore.getString(IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT)); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, |
| preferenceStore.getBoolean(IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP)); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE_MODE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_DEFAULT); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND, |
| IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK, |
| IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_EXTERNAL_CONSOLE, |
| preferenceStore.getBoolean(IGdbDebugPreferenceConstants.PREF_EXTERNAL_CONSOLE)); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT); |
| |
| if (fSolibBlock != null) |
| fSolibBlock.setDefaults(configuration); |
| |
| if (System.getenv("FLATPAK_SANDBOX_DIR") != null) { //$NON-NLS-1$ |
| configuration.setAttribute(IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_COMMAND, |
| IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_COMMAND_DEFAULT); |
| configuration.setAttribute(IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_PORT, |
| IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_PORT_DEFAULT); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REMOTE_TIMEOUT_ENABLED, |
| IGDBLaunchConfigurationConstants.DEBUGGER_REMOTE_TIMEOUT_ENABLED_DEFAULT); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REMOTE_TIMEOUT_VALUE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_REMOTE_TIMEOUT_VALUE_DEFAULT); |
| } |
| |
| } |
| |
| @Override |
| public boolean isValid(ILaunchConfiguration launchConfig) { |
| boolean valid = fGDBCommandText.getText().length() != 0; |
| if (valid) { |
| setErrorMessage(null); |
| setMessage(null); |
| } else { |
| setErrorMessage(LaunchUIMessages.getString("GDBDebuggerPage.gdb_executable_not_specified")); //$NON-NLS-1$ |
| setMessage(null); |
| } |
| return valid; |
| } |
| |
| /** utility method to cut down on clutter */ |
| private String getStringAttr(ILaunchConfiguration config, String attributeName, String defaultValue) { |
| try { |
| return config.getAttribute(attributeName, defaultValue); |
| } catch (CoreException e) { |
| return defaultValue; |
| } |
| } |
| |
| /** utility method to cut down on clutter */ |
| private boolean getBooleanAttr(ILaunchConfiguration config, String attributeName, boolean defaultValue) { |
| try { |
| return config.getAttribute(attributeName, defaultValue); |
| } catch (CoreException e) { |
| return defaultValue; |
| } |
| } |
| |
| @Override |
| public void initializeFrom(ILaunchConfiguration configuration) { |
| setInitializing(true); |
| IPreferenceStore preferenceStore = GdbUIPlugin.getDefault().getPreferenceStore(); |
| String gdbCommand = getStringAttr(configuration, IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, |
| preferenceStore.getString(IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND)); |
| String gdbInit = getStringAttr(configuration, IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, |
| preferenceStore.getString(IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT)); |
| boolean nonStopMode = getBooleanAttr(configuration, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, |
| preferenceStore.getBoolean(IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP)); |
| boolean reverseEnabled = getBooleanAttr(configuration, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT); |
| |
| updateReverseDebugModeFromConfig(configuration); |
| |
| boolean updateThreadsOnSuspend = getBooleanAttr(configuration, |
| IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND, |
| IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT); |
| boolean debugOnFork = getBooleanAttr(configuration, |
| IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK, |
| IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT); |
| boolean externalConsole = getBooleanAttr(configuration, |
| IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_EXTERNAL_CONSOLE, |
| preferenceStore.getBoolean(IGdbDebugPreferenceConstants.PREF_EXTERNAL_CONSOLE)); |
| |
| if (fSolibBlock != null) |
| fSolibBlock.initializeFrom(configuration); |
| fGDBCommandText.setText(gdbCommand); |
| fGDBInitText.setText(gdbInit); |
| fNonStopCheckBox.setSelection(nonStopMode); |
| fReverseCheckBox.setSelection(reverseEnabled); |
| fUpdateThreadlistOnSuspend.setSelection(updateThreadsOnSuspend); |
| fDebugOnFork.setSelection(debugOnFork); |
| if (fExternalConsole != null) { |
| fExternalConsole.setSelection(externalConsole); |
| } |
| |
| if (System.getenv("FLATPAK_SANDBOX_DIR") != null) { //$NON-NLS-1$ |
| String gdbServerCommand = getStringAttr(configuration, IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_COMMAND, |
| IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_COMMAND_DEFAULT); |
| boolean remoteTimeoutEnabled = getBooleanAttr(configuration, |
| IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REMOTE_TIMEOUT_ENABLED, |
| preferenceStore.getBoolean(IGdbDebugPreferenceConstants.PREF_DEFAULT_REMOTE_TIMEOUT_ENABLED)); |
| String remoteTimeOut = getStringAttr(configuration, |
| IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REMOTE_TIMEOUT_VALUE, |
| preferenceStore.getString(IGdbDebugPreferenceConstants.PREF_DEFAULT_REMOTE_TIMEOUT_VALUE)); |
| String port = getStringAttr(configuration, IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_PORT, |
| IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_PORT_DEFAULT); |
| fGDBServerCommandText.setText(gdbServerCommand); |
| fRemoteTimeoutEnabledCheckbox.setSelection(remoteTimeoutEnabled); |
| fRemoteTimeoutValueText.setText(remoteTimeOut); |
| fGDBServerPortNumberText.setText(port); |
| } |
| |
| updateTracepointModeFromConfig(configuration); |
| |
| setInitializing(false); |
| } |
| |
| protected void updateTracepointModeFromConfig(ILaunchConfiguration config) { |
| if (fTracepointModeCombo != null) { |
| String tracepointMode = getStringAttr(config, |
| IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT); |
| |
| if (tracepointMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_NORMAL_ONLY)) { |
| fTracepointModeCombo.setText(TP_NORMAL_ONLY); |
| } else if (tracepointMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_FAST_ONLY)) { |
| fTracepointModeCombo.setText(TP_FAST_ONLY); |
| } else if (tracepointMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_FAST_THEN_NORMAL)) { |
| fTracepointModeCombo.setText(TP_AUTOMATIC); |
| } else { |
| // Comment out assertion in the short term to allow for existing launches |
| // that used the old names to migrate to the new names. |
| // It can be uncommented after we have released Juno. |
| // Bug 375256 |
| // |
| // assert false : "Unknown Tracepoint Mode: " + tracepointMode; //$NON-NLS-1$ |
| fTracepointModeCombo.setText(TP_NORMAL_ONLY); |
| } |
| } |
| } |
| |
| protected void updateReverseDebugModeFromConfig(ILaunchConfiguration config) { |
| if (fReverseDebugMode != null) { |
| String debugMode = getStringAttr(config, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE_MODE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_DEFAULT); |
| |
| if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_HARDWARE)) { |
| fReverseDebugMode.setText(HW_REVERSE_MODE); |
| } else { |
| fReverseDebugMode.setText(SW_REVERSE_MODE); |
| } |
| } |
| } |
| |
| protected String getSelectedTracepointMode() { |
| if (fTracepointModeCombo != null) { |
| int selectedIndex = fTracepointModeCombo.getSelectionIndex(); |
| if (fTracepointModeCombo.getItem(selectedIndex).equals(TP_NORMAL_ONLY)) { |
| return IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_NORMAL_ONLY; |
| } else if (fTracepointModeCombo.getItem(selectedIndex).equals(TP_FAST_ONLY)) { |
| return IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_FAST_ONLY; |
| } else if (fTracepointModeCombo.getItem(selectedIndex).equals(TP_AUTOMATIC)) { |
| return IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_FAST_THEN_NORMAL; |
| } else { |
| assert false : "Unknown Tracepoint mode: " + fTracepointModeCombo.getItem(selectedIndex); //$NON-NLS-1$ |
| } |
| } |
| return IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT; |
| } |
| |
| protected String getSelectedReverseDebugMode() { |
| if (fReverseDebugMode != null) { |
| int selectedIndex = fReverseDebugMode.getSelectionIndex(); |
| if (fReverseDebugMode.getItem(selectedIndex).equals(HW_REVERSE_MODE)) { |
| return IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_HARDWARE; |
| } else if (fReverseDebugMode.getItem(selectedIndex).equals(SW_REVERSE_MODE)) { |
| return IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_SOFTWARE; |
| } else { |
| assert false : "Unknown Reverse Debug mode: " + fReverseDebugMode.getItem(selectedIndex); //$NON-NLS-1$ |
| } |
| } |
| return IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_DEFAULT; |
| } |
| |
| @Override |
| public void performApply(ILaunchConfigurationWorkingCopy configuration) { |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, fGDBCommandText.getText().trim()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, fGDBInitText.getText().trim()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, |
| fNonStopCheckBox.getSelection()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE, |
| fReverseCheckBox.getSelection()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND, |
| fUpdateThreadlistOnSuspend.getSelection()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK, |
| fDebugOnFork.getSelection()); |
| if (fExternalConsole != null) { |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_EXTERNAL_CONSOLE, |
| fExternalConsole.getSelection()); |
| } |
| |
| if (fTracepointModeCombo != null) { |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE, |
| getSelectedTracepointMode()); |
| } |
| |
| if (fReverseDebugMode != null) { |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE_MODE, |
| getSelectedReverseDebugMode()); |
| } |
| |
| if (fSolibBlock != null) |
| fSolibBlock.performApply(configuration); |
| |
| if (System.getenv("FLATPAK_SANDBOX_DIR") != null) { //$NON-NLS-1$ |
| configuration.setAttribute(IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_COMMAND, |
| fGDBServerCommandText.getText()); |
| configuration.setAttribute(IGDBFlatpakLaunchConstants.ATTR_GDBSERVER_PORT, |
| fGDBServerPortNumberText.getText()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REMOTE_TIMEOUT_ENABLED, |
| fRemoteTimeoutEnabledCheckbox.getSelection()); |
| configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REMOTE_TIMEOUT_VALUE, |
| fRemoteTimeoutValueText.getText()); |
| } |
| |
| } |
| |
| @Override |
| public String getName() { |
| return LaunchUIMessages.getString("GDBDebuggerPage.tab_name"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getShell() |
| */ |
| @Override |
| protected Shell getShell() { |
| return super.getShell(); |
| } |
| |
| /** |
| * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#updateLaunchConfigurationDialog() |
| */ |
| @Override |
| protected void updateLaunchConfigurationDialog() { |
| super.updateLaunchConfigurationDialog(); |
| } |
| |
| @Override |
| public void update(Observable o, Object arg) { |
| if (!isInitializing()) |
| updateLaunchConfigurationDialog(); |
| } |
| |
| public IMILaunchConfigurationComponent createSolibBlock(Composite parent) { |
| IMILaunchConfigurationComponent block = new GDBSolibBlock(new SolibSearchPathBlock(), true, true); |
| block.createControl(parent); |
| return block; |
| } |
| |
| public void createTabs(CTabFolder tabFolder) { |
| createMainTab(tabFolder); |
| createSolibTab(tabFolder); |
| if (System.getenv("FLATPAK_SANDBOX_DIR") != null) { //$NON-NLS-1$ |
| createFlatpakTab(tabFolder); |
| } |
| } |
| |
| public void createFlatpakTab(CTabFolder tabFolder) { |
| CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE); |
| tabItem.setText(LaunchUIMessages.getString("GDBDebuggerPage.flatpak_tab_name")); //$NON-NLS-1$ |
| Composite comp = ControlFactory.createCompositeEx(tabFolder, 1, GridData.FILL_BOTH); |
| ((GridLayout) comp.getLayout()).makeColumnsEqualWidth = false; |
| tabItem.setControl(comp); |
| |
| Composite subComp = new Composite(comp, SWT.NULL); |
| subComp.setLayout(new GridLayout(2, true)); |
| subComp.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| ((GridLayout) subComp.getLayout()).makeColumnsEqualWidth = false; |
| subComp.setFont(tabFolder.getFont()); |
| |
| Label label = new Label(subComp, SWT.LEFT); |
| label.setText(LaunchUIMessages.getString("GDBDebuggerPage.gdbserver_name_textfield_label")); //$NON-NLS-1$ |
| GridData gd = new GridData(); |
| label.setLayoutData(gd); |
| |
| fGDBServerCommandText = new Text(subComp, SWT.SINGLE | SWT.BORDER); |
| GridData data = new GridData(SWT.FILL, SWT.TOP, true, false); |
| fGDBServerCommandText.setLayoutData(data); |
| fGDBServerCommandText.addModifyListener(new ModifyListener() { |
| |
| @Override |
| public void modifyText(ModifyEvent evt) { |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| label = new Label(subComp, SWT.LEFT); |
| label.setText(LaunchUIMessages.getString("GDBDebuggerPage.port_number_textfield_label")); //$NON-NLS-1$ |
| gd = new GridData(); |
| label.setLayoutData(gd); |
| |
| fGDBServerPortNumberText = new Text(subComp, SWT.SINGLE | SWT.BORDER); |
| data = new GridData(SWT.FILL, SWT.TOP, true, false); |
| fGDBServerPortNumberText.setLayoutData(data); |
| fGDBServerPortNumberText.addModifyListener(new ModifyListener() { |
| |
| @Override |
| public void modifyText(ModifyEvent evt) { |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| |
| fRemoteTimeoutEnabledCheckbox = new Button(subComp, SWT.CHECK); |
| fRemoteTimeoutEnabledCheckbox |
| .setText(LaunchUIMessages.getString("GDBDebuggerPage.gdbserver_Settings_Remotetimeout_label")); //$NON-NLS-1$ |
| fRemoteTimeoutEnabledCheckbox |
| .setToolTipText(LaunchUIMessages.getString("GDBDebuggerPage.gdbserver_Settings_Remotetimeout_tooltip")); //$NON-NLS-1$ |
| gd = new GridData(); |
| fRemoteTimeoutEnabledCheckbox.setLayoutData(gd); |
| fRemoteTimeoutEnabledCheckbox.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| remoteTimeoutEnabledChanged(); |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| |
| fRemoteTimeoutValueText = new Text(subComp, SWT.SINGLE | SWT.BORDER); |
| data = new GridData(SWT.FILL, SWT.TOP, true, false); |
| fRemoteTimeoutValueText.setLayoutData(data); |
| fRemoteTimeoutValueText |
| .setToolTipText(LaunchUIMessages.getString("GDBDebuggerPage.gdbserver_Settings_Remotetimeout_tooltip")); //$NON-NLS-1$ |
| fRemoteTimeoutValueText.addModifyListener(new ModifyListener() { |
| |
| @Override |
| public void modifyText(ModifyEvent evt) { |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| remoteTimeoutEnabledChanged(); |
| } |
| |
| private void remoteTimeoutEnabledChanged() { |
| fRemoteTimeoutValueText.setEnabled(fRemoteTimeoutEnabledCheckbox.getSelection()); |
| } |
| |
| public void createMainTab(CTabFolder tabFolder) { |
| CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE); |
| tabItem.setText(LaunchUIMessages.getString("GDBDebuggerPage.main_tab_name")); //$NON-NLS-1$ |
| Composite comp = ControlFactory.createCompositeEx(tabFolder, 1, GridData.FILL_BOTH); |
| ((GridLayout) comp.getLayout()).makeColumnsEqualWidth = false; |
| tabItem.setControl(comp); |
| |
| createGdbContent(comp); |
| |
| ControlFactory.createLabel(comp, LaunchUIMessages.getString("GDBDebuggerPage.cmdfile_warning"), //$NON-NLS-1$ |
| 200, SWT.DEFAULT, SWT.WRAP); |
| |
| // TODO: Ideally, this field should be disabled if the back-end doesn't support non-stop debugging |
| // TODO: Find a way to determine if non-stop is supported (i.e. find the GDB version) then grey out the check box if necessary |
| fNonStopCheckBox = addCheckbox(comp, LaunchUIMessages.getString("GDBDebuggerPage.nonstop_mode")); //$NON-NLS-1$ |
| |
| createReverseDebugModeCombo(comp); |
| |
| fUpdateThreadlistOnSuspend = addCheckbox(comp, |
| LaunchUIMessages.getString("GDBDebuggerPage.update_thread_list_on_suspend")); //$NON-NLS-1$ |
| // This checkbox needs an explanation. Attach context help to it. |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(fUpdateThreadlistOnSuspend, |
| GdbUIPlugin.PLUGIN_ID + ".update_threadlist_button_context"); //$NON-NLS-1$ |
| |
| fDebugOnFork = addCheckbox(comp, |
| LaunchUIMessages.getString("GDBDebuggerPage.Automatically_debug_forked_processes")); //$NON-NLS-1$ |
| if (Platform.getOS().startsWith("win")) { //$NON-NLS-1$ |
| fExternalConsole = addCheckbox(comp, |
| LaunchUIMessages.getString("GDBDebuggerPage.use_new_console_for_process")); //$NON-NLS-1$ |
| } |
| |
| createTracepointModeCombo(comp); |
| } |
| |
| private void createGdbContent(Composite comp) { |
| // Create a sub-composite with 3 columns |
| Composite subComp = ControlFactory.createCompositeEx(comp, 3, GridData.FILL_HORIZONTAL); |
| ((GridLayout) subComp.getLayout()).makeColumnsEqualWidth = false; |
| |
| ControlFactory.createLabel(subComp, LaunchUIMessages.getString("GDBDebuggerPage.gdb_debugger")); //$NON-NLS-1$ |
| fGDBCommandText = ControlFactory.createTextField(subComp, SWT.SINGLE | SWT.BORDER); |
| fGDBCommandText.addModifyListener(new ModifyListener() { |
| @Override |
| public void modifyText(ModifyEvent evt) { |
| if (!isInitializing()) |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| Button button = createPushButton(subComp, LaunchUIMessages.getString("GDBDebuggerPage.gdb_browse"), null); //$NON-NLS-1$ |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent evt) { |
| handleGDBButtonSelected(); |
| updateLaunchConfigurationDialog(); |
| } |
| |
| private void handleGDBButtonSelected() { |
| FileDialog dialog = new FileDialog(getShell(), SWT.NONE); |
| dialog.setText(LaunchUIMessages.getString("GDBDebuggerPage.gdb_browse_dlg_title")); //$NON-NLS-1$ |
| String gdbCommand = fGDBCommandText.getText().trim(); |
| int lastSeparatorIndex = gdbCommand.lastIndexOf(File.separator); |
| if (lastSeparatorIndex != -1) { |
| String cmd = gdbCommand.substring(0, lastSeparatorIndex); |
| // remove double quotes, since they interfere with |
| // "setFilterPath()" below |
| cmd = cmd.replaceAll("\\\"", ""); //$NON-NLS-1$//$NON-NLS-2$ |
| dialog.setFilterPath(cmd); |
| } |
| String res = dialog.open(); |
| if (res == null) { |
| return; |
| } |
| // path contains space(s)? |
| if (res.contains(" ")) { //$NON-NLS-1$ |
| // surround it in double quotes |
| res = '"' + res + '"'; |
| } |
| fGDBCommandText.setText(res); |
| } |
| }); |
| |
| ControlFactory.createLabel(subComp, LaunchUIMessages.getString("GDBDebuggerPage.gdb_command_file")); //$NON-NLS-1$ |
| fGDBInitText = ControlFactory.createTextField(subComp, SWT.SINGLE | SWT.BORDER); |
| fGDBInitText.addModifyListener(new ModifyListener() { |
| @Override |
| public void modifyText(ModifyEvent evt) { |
| if (!isInitializing()) |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| button = createPushButton(subComp, LaunchUIMessages.getString("GDBDebuggerPage.gdb_cmdfile_browse"), null); //$NON-NLS-1$ |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent evt) { |
| handleGDBInitButtonSelected(); |
| updateLaunchConfigurationDialog(); |
| } |
| |
| private void handleGDBInitButtonSelected() { |
| FileDialog dialog = new FileDialog(getShell(), SWT.NONE); |
| dialog.setText(LaunchUIMessages.getString("GDBDebuggerPage.gdb_cmdfile_dlg_title")); //$NON-NLS-1$ |
| String gdbCommand = fGDBInitText.getText().trim(); |
| int lastSeparatorIndex = gdbCommand.lastIndexOf(File.separator); |
| if (lastSeparatorIndex != -1) { |
| dialog.setFilterPath(gdbCommand.substring(0, lastSeparatorIndex)); |
| } |
| String res = dialog.open(); |
| if (res == null) { |
| return; |
| } |
| fGDBInitText.setText(res); |
| } |
| }); |
| } |
| |
| protected void createTracepointModeCombo(Composite parent) { |
| // Create a sub-composite with 2 columns |
| Composite subComp = ControlFactory.createCompositeEx(parent, 2, GridData.FILL_HORIZONTAL); |
| ((GridLayout) subComp.getLayout()).makeColumnsEqualWidth = false; |
| |
| // Add a combo to choose the type of tracepoint mode to use |
| ControlFactory.createLabel(subComp, LaunchUIMessages.getString("GDBDebuggerPage.tracepoint_mode_label")); //$NON-NLS-1$ |
| |
| fTracepointModeCombo = new Combo(subComp, SWT.READ_ONLY | SWT.DROP_DOWN); |
| fTracepointModeCombo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); |
| fTracepointModeCombo.add(TP_NORMAL_ONLY); |
| fTracepointModeCombo.add(TP_FAST_ONLY); |
| fTracepointModeCombo.add(TP_AUTOMATIC); |
| |
| fTracepointModeCombo.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| fTracepointModeCombo.select(0); |
| } |
| |
| protected void createReverseDebugModeCombo(Composite parent) { |
| // Create a sub-composite with 2 columns with no indentation width- or height-wise |
| Composite subComp = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(2, false); |
| layout.marginWidth = 0; |
| layout.marginHeight = 0; |
| subComp.setLayout(layout); |
| subComp.setFont(parent.getFont()); |
| |
| fReverseCheckBox = addCheckbox(subComp, LaunchUIMessages.getString("GDBDebuggerPage.reverse_Debugging")); //$NON-NLS-1$ |
| |
| fReverseDebugMode = new Combo(subComp, SWT.READ_ONLY | SWT.DROP_DOWN); |
| fReverseDebugMode.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); |
| fReverseDebugMode.add(HW_REVERSE_MODE); |
| fReverseDebugMode.add(SW_REVERSE_MODE); |
| |
| fReverseDebugMode.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| fReverseDebugMode.select(0); |
| } |
| |
| public void createSolibTab(CTabFolder tabFolder) { |
| CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE); |
| tabItem.setText(LaunchUIMessages.getString("GDBDebuggerPage.shared_libraries")); //$NON-NLS-1$ |
| Composite comp = ControlFactory.createCompositeEx(fTabFolder, 1, GridData.FILL_BOTH); |
| comp.setFont(tabFolder.getFont()); |
| tabItem.setControl(comp); |
| fSolibBlock = createSolibBlock(comp); |
| if (fSolibBlock instanceof Observable) |
| ((Observable) fSolibBlock).addObserver(this); |
| } |
| |
| /** Used to add a checkbox to the tab. Each checkbox has its own line. */ |
| private Button addCheckbox(Composite parent, String label) { |
| Button button = ControlFactory.createCheckBox(parent, label); |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| updateLaunchConfigurationDialog(); |
| } |
| }); |
| |
| return button; |
| } |
| |
| @Override |
| public void dispose() { |
| if (fSolibBlock != null) { |
| if (fSolibBlock instanceof Observable) |
| ((Observable) fSolibBlock).deleteObserver(this); |
| fSolibBlock.dispose(); |
| } |
| super.dispose(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| @Override |
| public void activated(ILaunchConfigurationWorkingCopy workingCopy) { |
| // Override the default behavior |
| } |
| |
| protected boolean isInitializing() { |
| return fIsInitializing; |
| } |
| |
| private void setInitializing(boolean isInitializing) { |
| fIsInitializing = isInitializing; |
| } |
| } |