1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Bug 362039: Default directory for "post mortem" debug, as well as handling the use of variables in core/trace file specification.

This commit is contained in:
Marc Khouzam 2012-02-16 21:39:37 -05:00
parent c49a852b88
commit 437d707cd9
6 changed files with 159 additions and 49 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2010 QNX Software Systems and others.
* Copyright (c) 2008, 2012 QNX Software Systems 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
@ -10,9 +10,13 @@
* Ken Ryall (Nokia) - bug 178731
* Ericsson - Support for tracepoint post-mortem debugging
* IBM Corporation
* Marc Khouzam (Ericsson) - Support setting the path in which the core file
* dialog should start (Bug 362039)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.launching;
import java.io.File;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement;
@ -30,6 +34,7 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.DebugUITools;
@ -485,15 +490,25 @@ public class CMainTab extends CAbstractMainTab {
String coreName = fCoreText.getText().trim();
// We accept an empty string. This should trigger a prompt to the user
// This allows to re-use the launch, with a different core file.
// We also accept an absolute or workspace-relative path, including variables.
// This allows the user to indicate in which directory the prompt will start (Bug 362039)
if (!coreName.equals(EMPTY_STRING)) {
if (coreName.equals(".") || coreName.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
setErrorMessage(LaunchMessages.getString("CMainTab.File_does_not_exist")); //$NON-NLS-1$
try {
// Replace the variables
coreName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(coreName, false);
} catch (CoreException e) {
setErrorMessage(e.getMessage());
return false;
}
IPath corePath = new Path(coreName);
if (!corePath.toFile().exists()) {
setErrorMessage(LaunchMessages.getString("CMainTab.File_does_not_exist")); //$NON-NLS-1$
return false;
coreName = coreName.trim();
File filePath = new File(coreName);
if (!filePath.isDirectory()) {
IPath corePath = new Path(coreName);
if (!corePath.toFile().exists()) {
setErrorMessage(LaunchMessages.getString("CMainTab.File_does_not_exist")); //$NON-NLS-1$
return false;
}
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009 Ericsson and others.
* Copyright (c) 2009, 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - initial API and implementation
* Marc Khouzam (Ericsson) - Set path in which the dialog should start (Bug 362039)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.launching;
@ -46,6 +47,12 @@ public class CoreFilePrompter implements IStatusHandler {
FileDialog dialog = new FileDialog(shell);
dialog.setText(LaunchMessages.getString("CoreFileLaunchDelegate.Select_Corefile")); //$NON-NLS-1$
String initialPath = (String)params;
if (initialPath != null && initialPath.length() != 0) {
dialog.setFilterPath(initialPath);
}
String res = dialog.open();
if (res != null) {
File file = new File(res);

View file

@ -92,8 +92,8 @@ CMainTab.&ProjectColon=&Project:
CMainTab.C/C++_Application=C/C++ Application:
CMainTab.CoreFile_type=Core file
CMainTab.TraceFile_type=Trace file
CMainTab.CoreFile_path=Core file (leave blank to trigger prompt):
CMainTab.TraceFile_path=Trace data file (leave blank to trigger prompt):
CMainTab.CoreFile_path=Core file (leave blank or select root directory to trigger prompt):
CMainTab.TraceFile_path=Trace data file (leave blank or select root directory to trigger prompt):
CMainTab.Search...=Searc&h Project...
CMainTab.Choose_program_to_run=Choose a &program to run:
CMainTab.Choose_program_to_run_from_NAME=Choose a program to run from {0}:

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011 Ericsson and others.
* Copyright (c) 2011, 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,9 +7,12 @@
*
* Contributors:
* Ericsson - initial API and implementation
* Marc Khouzam (Ericsson) - Support setting the path in which the core file
* dialog should start (Bug 362039)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.io.File;
import java.util.Map;
import java.util.Properties;
@ -40,8 +43,10 @@ import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler;
@ -256,10 +261,21 @@ public class DebugNewProcessSequence extends ReflectionSequence {
/** @since 4.0 */
protected static class PromptForCoreJob extends Job {
/**
* The initial path that should be used in the prompt for the core file
* @since 4.1
*/
protected String fInitialPath;
protected DataRequestMonitor<String> fRequestMonitor;
public PromptForCoreJob(String name, DataRequestMonitor<String> rm) {
this(name, null, null, rm);
}
/** @since 4.1 */
public PromptForCoreJob(String name, String coreType, String initialPath, DataRequestMonitor<String> rm) {
super(name);
fInitialPath = initialPath;
fRequestMonitor = rm;
}
@ -281,7 +297,7 @@ public class DebugNewProcessSequence extends ReflectionSequence {
}
try {
Object result = prompter.handleStatus(filePrompt, null);
Object result = prompter.handleStatus(filePrompt, fInitialPath);
if (result == null) {
fRequestMonitor.cancel();
} else if (result instanceof String) {
@ -314,14 +330,46 @@ public class DebugNewProcessSequence extends ReflectionSequence {
String coreFile = CDebugUtils.getAttribute(
fAttributes,
ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, ""); //$NON-NLS-1$
try {
// Support variable substitution for the core file path
// Bug 362039
coreFile = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(coreFile, false);
} catch (CoreException e) {
// Ignore and use core file string as is.
// This should not happen because the dialog will
// prevent the user from making such mistakes
}
final String coreType = CDebugUtils.getAttribute(
fAttributes,
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_POST_MORTEM_TYPE,
IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TYPE_DEFAULT);
if (coreFile.length() == 0) {
// We handle three cases:
// 1- Core file specified, in which case we use it
// 2- Nothing specified, in which case we prompt for a core file path
// 3- Path to a directory, in which case we prompt for a core file starting at the specified path
boolean shouldPrompt = false;
coreFile = coreFile.trim();
if (coreFile.length() == 0) {
shouldPrompt = true;
} else {
File filePath = new File(coreFile);
if (filePath.isDirectory()) {
// The user provided a directory. We need to prompt for an actual
// core file, but we'll start off in the specified directory
// Bug 362039
shouldPrompt = true;
}
// else not a directory but an actual core file: use it.
}
if (shouldPrompt) {
new PromptForCoreJob(
"Prompt for post mortem file", //$NON-NLS-1$
coreType,
coreFile,
new DataRequestMonitor<String>(getExecutor(), rm) {
@Override
protected void handleCancel() {
@ -332,53 +380,48 @@ public class DebugNewProcessSequence extends ReflectionSequence {
protected void handleSuccess() {
String newCoreFile = getData();
if (newCoreFile == null || newCoreFile.length()== 0) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get post mortem file path", null)); //$NON-NLS-1$
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, Messages.Cannot_get_post_mortem_file_path_error, null));
rm.done();
} else {
if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) {
fCommandControl.queueCommand(
fCommandFactory.createMITargetSelectCore(fCommandControl.getContext(), newCoreFile),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
} else if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE)) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(fCommandControl.getContext(), ITraceTargetDMContext.class);
traceControl.loadTraceData(targetDmc, newCoreFile, rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Tracing not supported", null));
rm.done();
}
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Invalid post-mortem type", null));
rm.done();
}
targetSelectFile(coreType, newCoreFile, rm);
}
}
}).schedule();
} else {
if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) {
fCommandControl.queueCommand(
fCommandFactory.createMITargetSelectCore(fCommandControl.getContext(), coreFile),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
} else if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE)) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(fCommandControl.getContext(), ITraceTargetDMContext.class);
traceControl.loadTraceData(targetDmc, coreFile, rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Tracing not supported", null));
rm.done();
}
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Invalid post-mortem type", null));
rm.done();
}
// The user specified something that was not a directory,
// it therefore should be the core file itself. Let's use it.
// First convert to absolute path so that things work even if the user
// specifies a relative path. The reason we do this is that GDB
// may not be using the same root path as Eclipse.
String absoluteCoreFile = new Path(coreFile).toFile().getAbsolutePath();
targetSelectFile(coreType, absoluteCoreFile, rm);
}
} else {
rm.done();
}
}
private void targetSelectFile(String coreType, String file, RequestMonitor rm) {
if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) {
fCommandControl.queueCommand(
fCommandFactory.createMITargetSelectCore(fCommandControl.getContext(), file),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
} else if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE)) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(fCommandControl.getContext(), ITraceTargetDMContext.class);
traceControl.loadTraceData(targetDmc, file, rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, Messages.Tracing_not_supported_error, null));
rm.done();
}
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, Messages.Invalid_post_mortem_type_error, null));
rm.done();
}
}
/**
* Start tracking the breakpoints. Note that for remote debugging
* we should first connect to the target.
@ -435,4 +478,4 @@ public class DebugNewProcessSequence extends ReflectionSequence {
fTracker = null;
rm.done();
}
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import org.eclipse.osgi.util.NLS;
/**
* Preference strings.
* @since 4.1
*/
class Messages extends NLS {
public static String Tracing_not_supported_error;
public static String Invalid_post_mortem_type_error;
public static String Cannot_get_post_mortem_file_path_error;
static {
// initialize resource bundle
NLS.initializeMessages(Messages.class.getName(), Messages.class);
}
private Messages() {
}
}

View file

@ -0,0 +1,14 @@
###############################################################################
# Copyright (c) 2012 Ericsson and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Marc Khouzam (Ericsson) - initial API and implementation
###############################################################################
Tracing_not_supported_error=Tracing not supported
Invalid_post_mortem_type_error=Invalid post-mortem type
Cannot_get_post_mortem_file_path_error=Cannot get post mortem file path