Skip to content

Commit

Permalink
Issue eclipse-corrosion#178 Checking valid GDB in launch config + cos…
Browse files Browse the repository at this point in the history
…metic changes

Now the Rust debug launch config checks if the specified GDB is valid.
This is done in a blocking fashion, tests show that this does not block
the UI for an unreasonable time. Making the check non-blocking would
also make the code much more complicated, since the launcher framework
does not seem to be fit for such things.

Also some cosmetic changes were done to the debug launch config. The
"Main" tab now starts with a capital letter, as all other tabs. It also
has an icon now.

Signed-off-by: Max Bureck <[email protected]>
  • Loading branch information
Boereck committed Dec 2, 2019
1 parent 2925c55 commit ec623fa
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* Contributors:
* Lucas Bullen (Red Hat Inc.) - Initial implementation
* Max Bureck (Fraunhofer FOKUS) - Registering additional image for debug launcher
*******************************************************************************/
package org.eclipse.corrosion;

Expand Down Expand Up @@ -97,6 +98,7 @@ protected void initializeImageRegistry(ImageRegistry reg) {
super.initializeImageRegistry(reg);
declareRegistryImage(reg, "images/cargo.png"); //$NON-NLS-1$
declareRegistryImage(reg, "images/cargo16.png"); //$NON-NLS-1$
declareRegistryImage(reg, "icons/rustEditorIcon.png"); //$NON-NLS-1$
}

private final static void declareRegistryImage(ImageRegistry reg, String image) {
Expand Down
2 changes: 2 additions & 0 deletions org.eclipse.corrosion/src/org/eclipse/corrosion/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* Contributors:
* Mickael Istria (Red Hat Inc.) - Initial implementation
* Nicola Orru - Added support for external RLS startup configuration
* Max Bureck (Fraunhofer FOKUS) - Added message for GDB failure
*******************************************************************************/
package org.eclipse.corrosion;

Expand Down Expand Up @@ -167,4 +168,5 @@ public class Messages extends NLS {
public static String RustManager_toolchainDoesntIncludeRLS;
public static String CargoRunTab_Title;
public static String CargoTestTab_Title;
public static String RustDebugTabGroup_gdbErrorMsg;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,26 @@
import org.eclipse.corrosion.CorrosionPlugin;

/**
* This class contains static helper methods and fields to be used for the Debuging functionality in Eclipse Corrosion
* This class contains static helper methods and fields to be used for the
* Debuging functionality in Eclipse Corrosion
*/
class DebugUtil {

/**
* Default debugger executable to use for Rust
*/
/* package */ static final String DEFAULT_DEBUGGER = "rust-gdb"; //$NON-NLS-1$
private static final boolean IS_WINDOWS = Platform.getOS().equals(Platform.OS_WIN32);

/**
* Returns the default workspace path to the executable produced for the given project. This location is a guess based on the default rust/cargo project layout and the operating system running
* eclipse.
* Returns the default workspace path to the executable produced for the given
* project. This location is a guess based on the default rust/cargo project
* layout and the operating system running eclipse.
*
* @param project
* Rust project for which the executable workspace path is computed.
* @return default workspace path to the executable created for the given Rust {@code project}.
* @param project Rust project for which the executable workspace path is
* computed.
* @return default workspace path to the executable created for the given Rust
* {@code project}.
*/
static String getDefaultExecutablePath(IProject project) {
if (project == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* Contributors:
* Lucas Bullen (Red Hat Inc.) - Initial implementation
* Max Bureck (Fraunhofer FOKUS) - Moved default GDB definition to re-usable constant
*******************************************************************************/
package org.eclipse.corrosion.debug;

Expand Down Expand Up @@ -50,12 +51,15 @@
public class RustDebugDelegate extends GdbLaunchDelegate implements ILaunchShortcut {
public static final String BUILD_COMMAND_ATTRIBUTE = CorrosionPlugin.PLUGIN_ID + ".BUILD_COMMAND"; //$NON-NLS-1$

@Override public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
@Override
public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor)
throws CoreException {
ILaunchConfiguration configuration = launch.getLaunchConfiguration();
String buildCommand = configuration.getAttribute(BUILD_COMMAND_ATTRIBUTE, ""); //$NON-NLS-1$
String projectName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
String workingDirectoryString = RustLaunchDelegateTools.performVariableSubstitution(configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, "").trim()); //$NON-NLS-1$
String workingDirectoryString = RustLaunchDelegateTools.performVariableSubstitution(
configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, "").trim()); //$NON-NLS-1$
File workingDirectory = RustLaunchDelegateTools.convertToAbsolutePath(workingDirectoryString);
if (workingDirectoryString.isEmpty() || !workingDirectory.exists() || !workingDirectory.isDirectory()) {
workingDirectory = project.getLocation().toFile();
Expand Down Expand Up @@ -102,16 +106,19 @@ public class RustDebugDelegate extends GdbLaunchDelegate implements ILaunchShort
super.launch(configuration, mode, launch, monitor);
}

@Override public void launch(ISelection selection, String mode) {
ILaunchConfiguration launchConfig = getLaunchConfiguration(RustLaunchDelegateTools.firstResourceFromSelection(selection));
@Override
public void launch(ISelection selection, String mode) {
ILaunchConfiguration launchConfig = getLaunchConfiguration(
RustLaunchDelegateTools.firstResourceFromSelection(selection));
try {
RustLaunchDelegateTools.launch(launchConfig, mode);
} catch (CoreException e) {
CorrosionPlugin.logError(e);
}
}

@Override public void launch(IEditorPart editor, String mode) {
@Override
public void launch(IEditorPart editor, String mode) {
ILaunchConfiguration launchConfig = getLaunchConfiguration(RustLaunchDelegateTools.resourceFromEditor(editor));
try {
RustLaunchDelegateTools.launch(launchConfig, mode);
Expand All @@ -120,7 +127,9 @@ public class RustDebugDelegate extends GdbLaunchDelegate implements ILaunchShort
}
}

@Override protected ISourceLocator getSourceLocator(ILaunchConfiguration configuration, DsfSession session) throws CoreException {
@Override
protected ISourceLocator getSourceLocator(ILaunchConfiguration configuration, DsfSession session)
throws CoreException {
SourceLookupDirector locator = new SourceLookupDirector();
String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String) null);
if (memento == null) {
Expand All @@ -131,40 +140,48 @@ public class RustDebugDelegate extends GdbLaunchDelegate implements ILaunchShort
return locator;
}

@Override protected DsfSourceLookupDirector createDsfSourceLocator(ILaunchConfiguration configuration, DsfSession session) throws CoreException {
@Override
protected DsfSourceLookupDirector createDsfSourceLocator(ILaunchConfiguration configuration, DsfSession session)
throws CoreException {
DsfSourceLookupDirector sourceLookupDirector = new DsfSourceLookupDirector(session);
sourceLookupDirector.setSourceContainers(((SourceLookupDirector) getSourceLocator(configuration, session)).getSourceContainers());
sourceLookupDirector.setSourceContainers(
((SourceLookupDirector) getSourceLocator(configuration, session)).getSourceContainers());
return sourceLookupDirector;
}

@Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
@Override
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
setDefaultProcessFactory(configuration); // Reset process factory to what GdbLaunch expected
String projectName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
String workingDirectoryString = RustLaunchDelegateTools.performVariableSubstitution(configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, "").trim()); //$NON-NLS-1$
String workingDirectoryString = RustLaunchDelegateTools.performVariableSubstitution(
configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, "").trim()); //$NON-NLS-1$
File workingDirectory = RustLaunchDelegateTools.convertToAbsolutePath(workingDirectoryString);
if (workingDirectoryString.isEmpty() || !workingDirectory.exists() || !workingDirectory.isDirectory()) {
workingDirectory = project.getLocation().toFile();
}
String executableString = RustLaunchDelegateTools.performVariableSubstitution(configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "").trim()); //$NON-NLS-1$
String executableString = RustLaunchDelegateTools.performVariableSubstitution(
configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "").trim()); //$NON-NLS-1$
File executable = RustLaunchDelegateTools.convertToAbsolutePath(executableString);
if (!executable.exists()) {
IPath executablePath = Path.fromPortableString(executableString);
if (project != null && executablePath.segment(0).equals(project.getName())) { // project relative path
executable = project.getFile(executablePath.removeFirstSegments(1)).getLocation().toFile().getAbsoluteFile();
executable = project.getFile(executablePath.removeFirstSegments(1)).getLocation().toFile()
.getAbsoluteFile();
}
}

ILaunchConfigurationWorkingCopy wc = configuration.copy(configuration.getName());
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, executable.getAbsolutePath());
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, workingDirectory.getAbsolutePath());
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_LOCATION, project.getLocation().toString());

String stopInMainSymbol = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ""); //$NON-NLS-1$

String stopInMainSymbol = configuration
.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ""); //$NON-NLS-1$
if (stopInMainSymbol.equals("main")) { //$NON-NLS-1$
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, projectName + "::main"); //$NON-NLS-1$
}

ILaunch launch = super.getLaunch(wc.doSave(), mode);
if (!(launch instanceof RustGDBLaunchWrapper)) {
launch = new RustGDBLaunchWrapper(launch);
Expand All @@ -174,19 +191,21 @@ public class RustDebugDelegate extends GdbLaunchDelegate implements ILaunchShort
return launch;
}

@Override protected IPath checkBinaryDetails(ILaunchConfiguration config) throws CoreException {
@Override
protected IPath checkBinaryDetails(ILaunchConfiguration config) throws CoreException {
return LaunchUtils.verifyProgramPath(config, null);
}

private static ILaunchConfiguration getLaunchConfiguration(IResource resource) {
ILaunchConfiguration launchConfiguration = RustLaunchDelegateTools.getLaunchConfiguration(resource, "org.eclipse.corrosion.debug.RustDebugDelegate"); //$NON-NLS-1$
ILaunchConfiguration launchConfiguration = RustLaunchDelegateTools.getLaunchConfiguration(resource,
"org.eclipse.corrosion.debug.RustDebugDelegate"); //$NON-NLS-1$
if (launchConfiguration instanceof ILaunchConfigurationWorkingCopy) {
ILaunchConfigurationWorkingCopy wc = (ILaunchConfigurationWorkingCopy) launchConfiguration;
final IProject project = resource.getProject();
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName());
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, getDefaultExecutablePath(project)); // $NON-NLS-1$
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false);
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, "rust-gdb"); //$NON-NLS-1$
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, DebugUtil.DEFAULT_DEBUGGER);
}
return launchConfiguration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* Contributors:
* Lucas Bullen (Red Hat Inc.) - Initial implementation
* Max Bureck (Fraunhofer FOKUS) - Added icon
*******************************************************************************/
package org.eclipse.corrosion.debug;

Expand All @@ -18,6 +19,7 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.corrosion.CorrosionPlugin;
import org.eclipse.corrosion.Messages;
import org.eclipse.corrosion.cargo.core.CargoProjectTester;
import org.eclipse.corrosion.ui.InputComponent;
Expand All @@ -28,6 +30,7 @@
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
Expand Down Expand Up @@ -148,4 +151,9 @@ public boolean canSave() {
public String getName() {
return Messages.LaunchUI_main;
}

@Override
public Image getImage() {
return CorrosionPlugin.getDefault().getImageRegistry().get("icons/rustEditorIcon.png"); //$NON-NLS-1$
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,29 @@
*
* Contributors:
* Lucas Bullen (Red Hat Inc.) - Initial implementation
* Max Bureck (Fraunhofer FOKUS) - Check for valid GDB executable/script
*******************************************************************************/
package org.eclipse.corrosion.debug;

import static org.eclipse.corrosion.debug.DebugUtil.DEFAULT_DEBUGGER;

import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.internal.ui.launching.LocalApplicationCDebuggerTab;
import org.eclipse.cdt.dsf.gdb.launching.LaunchUtils;
import org.eclipse.cdt.launch.ui.CArgumentsTab;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.corrosion.Messages;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.EnvironmentTab;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
import org.eclipse.osgi.util.NLS;

@SuppressWarnings("restriction")
public class RustDebugTabGroup extends AbstractLaunchConfigurationTabGroup {
Expand All @@ -39,7 +48,49 @@ protected class RustLocalApplicationCDebuggerTab extends LocalApplicationCDebugg
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
super.setDefaults(config);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false);
config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, "rust-gdb"); //$NON-NLS-1$
config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, DEFAULT_DEBUGGER);
}

@Override
public boolean isValid(ILaunchConfiguration config) {
if (!super.isValid(config)) {
return false;
}
// Check for a valid GDB executable/script
String gdbCommand = getGdbCommand(config);
try {
LaunchUtils.getGDBVersion(gdbCommand, new String[] {});
} catch (CoreException e) {
final String msg = getMessageFromException(e);
setErrorMessage(msg);
return false;
}
return true;
}

private String getMessageFromException(CoreException e) {
final IStatus status = e.getStatus();
final String statusMessage = status.getMessage();
final Throwable statusException = status.getException();
if (statusException != null) {
String exceptionMessage = statusException.getLocalizedMessage();
return NLS.bind(Messages.RustDebugTabGroup_gdbErrorMsg, statusMessage, exceptionMessage);
}
// else
return statusMessage;
}

/**
* Reads and returns the user specified gdb executable from the given
* {@code config}.
*/
private String getGdbCommand(ILaunchConfiguration config) {
try {
return config.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, DEFAULT_DEBUGGER);
} catch (CoreException e) {
// we were not able to find command
return DEFAULT_DEBUGGER;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#
# Contributors:
# Mickael Istria (Red Hat Inc.) - Initial implementation
# Max Bureck (Fraunhofer FOKUS) - More consistent capitalization
#################################################################
DebugPreferencePage_seeGDBPage=See <A>GDB</A> Preferences Page
ImplementationsSearchQuery_implementations=Implementations
Expand Down Expand Up @@ -75,7 +76,7 @@ CargoExportWizardPage_outputLocation=Crate will be created in: {0}/target/packag
CargoRunDelegate_unableToFindProject=Unable to find project.
CargoRunDelegate_unableToFindToml=Unable to find Cargo.toml file.
CargoRunDelegate_unableToLaunch=Unable to Launch
LaunchUI_main=main
LaunchUI_main=Main
LaunchUI_useDefault=Use default
LaunchUI_variables=Variables
LaunchUI_selection=Selection
Expand Down Expand Up @@ -156,3 +157,4 @@ RustManager_unableToSetDefaultToolchain=Unable to set `{0}` as the default toolc
RustManager_toolchainDoesntIncludeRLS=The toolchain `{0}` does not contain the Rust Language Server, please select a different toolchain.
CargoRunTab_Title=Main
CargoTestTab_Title=Main
RustDebugTabGroup_gdbErrorMsg={0} [cause: {1}]

0 comments on commit ec623fa

Please sign in to comment.