1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-10 09:45:39 +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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,9 +10,13 @@
* Ken Ryall (Nokia) - bug 178731 * Ken Ryall (Nokia) - bug 178731
* Ericsson - Support for tracepoint post-mortem debugging * Ericsson - Support for tracepoint post-mortem debugging
* IBM Corporation * 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; package org.eclipse.cdt.dsf.gdb.internal.ui.launching;
import java.io.File;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement; 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.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.DebugUITools;
@ -485,15 +490,25 @@ public class CMainTab extends CAbstractMainTab {
String coreName = fCoreText.getText().trim(); String coreName = fCoreText.getText().trim();
// We accept an empty string. This should trigger a prompt to the user // 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. // 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(EMPTY_STRING)) {
if (coreName.equals(".") || coreName.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$ try {
setErrorMessage(LaunchMessages.getString("CMainTab.File_does_not_exist")); //$NON-NLS-1$ // Replace the variables
coreName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(coreName, false);
} catch (CoreException e) {
setErrorMessage(e.getMessage());
return false; return false;
} }
IPath corePath = new Path(coreName);
if (!corePath.toFile().exists()) { coreName = coreName.trim();
setErrorMessage(LaunchMessages.getString("CMainTab.File_does_not_exist")); //$NON-NLS-1$ File filePath = new File(coreName);
return false; 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Ericsson - initial API and implementation * 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; package org.eclipse.cdt.dsf.gdb.internal.ui.launching;
@ -46,6 +47,12 @@ public class CoreFilePrompter implements IStatusHandler {
FileDialog dialog = new FileDialog(shell); FileDialog dialog = new FileDialog(shell);
dialog.setText(LaunchMessages.getString("CoreFileLaunchDelegate.Select_Corefile")); //$NON-NLS-1$ 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(); String res = dialog.open();
if (res != null) { if (res != null) {
File file = new File(res); File file = new File(res);

View file

@ -92,8 +92,8 @@ CMainTab.&ProjectColon=&Project:
CMainTab.C/C++_Application=C/C++ Application: CMainTab.C/C++_Application=C/C++ Application:
CMainTab.CoreFile_type=Core file CMainTab.CoreFile_type=Core file
CMainTab.TraceFile_type=Trace file CMainTab.TraceFile_type=Trace file
CMainTab.CoreFile_path=Core 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 to trigger prompt): CMainTab.TraceFile_path=Trace data file (leave blank or select root directory to trigger prompt):
CMainTab.Search...=Searc&h Project... CMainTab.Search...=Searc&h Project...
CMainTab.Choose_program_to_run=Choose a &program to run: CMainTab.Choose_program_to_run=Choose a &program to run:
CMainTab.Choose_program_to_run_from_NAME=Choose a program to run from {0}: 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,9 +7,12 @@
* *
* Contributors: * Contributors:
* Ericsson - initial API and implementation * 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; package org.eclipse.cdt.dsf.gdb.service;
import java.io.File;
import java.util.Map; import java.util.Map;
import java.util.Properties; 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.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler; import org.eclipse.debug.core.IStatusHandler;
@ -256,10 +261,21 @@ public class DebugNewProcessSequence extends ReflectionSequence {
/** @since 4.0 */ /** @since 4.0 */
protected static class PromptForCoreJob extends Job { 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; protected DataRequestMonitor<String> fRequestMonitor;
public PromptForCoreJob(String name, DataRequestMonitor<String> rm) { 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); super(name);
fInitialPath = initialPath;
fRequestMonitor = rm; fRequestMonitor = rm;
} }
@ -281,7 +297,7 @@ public class DebugNewProcessSequence extends ReflectionSequence {
} }
try { try {
Object result = prompter.handleStatus(filePrompt, null); Object result = prompter.handleStatus(filePrompt, fInitialPath);
if (result == null) { if (result == null) {
fRequestMonitor.cancel(); fRequestMonitor.cancel();
} else if (result instanceof String) { } else if (result instanceof String) {
@ -314,14 +330,46 @@ public class DebugNewProcessSequence extends ReflectionSequence {
String coreFile = CDebugUtils.getAttribute( String coreFile = CDebugUtils.getAttribute(
fAttributes, fAttributes,
ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, ""); //$NON-NLS-1$ 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( final String coreType = CDebugUtils.getAttribute(
fAttributes, fAttributes,
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_POST_MORTEM_TYPE, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_POST_MORTEM_TYPE,
IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TYPE_DEFAULT); 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( new PromptForCoreJob(
"Prompt for post mortem file", //$NON-NLS-1$ "Prompt for post mortem file", //$NON-NLS-1$
coreType,
coreFile,
new DataRequestMonitor<String>(getExecutor(), rm) { new DataRequestMonitor<String>(getExecutor(), rm) {
@Override @Override
protected void handleCancel() { protected void handleCancel() {
@ -332,53 +380,48 @@ public class DebugNewProcessSequence extends ReflectionSequence {
protected void handleSuccess() { protected void handleSuccess() {
String newCoreFile = getData(); String newCoreFile = getData();
if (newCoreFile == null || newCoreFile.length()== 0) { 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(); rm.done();
} else { } else {
if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) { targetSelectFile(coreType, newCoreFile, rm);
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();
}
} }
} }
}).schedule(); }).schedule();
} else { } else {
if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) { // The user specified something that was not a directory,
fCommandControl.queueCommand( // it therefore should be the core file itself. Let's use it.
fCommandFactory.createMITargetSelectCore(fCommandControl.getContext(), coreFile),
new DataRequestMonitor<MIInfo>(getExecutor(), rm)); // First convert to absolute path so that things work even if the user
} else if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE)) { // specifies a relative path. The reason we do this is that GDB
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class); // may not be using the same root path as Eclipse.
if (traceControl != null) { String absoluteCoreFile = new Path(coreFile).toFile().getAbsolutePath();
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(fCommandControl.getContext(), ITraceTargetDMContext.class); targetSelectFile(coreType, absoluteCoreFile, rm);
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();
}
} }
} else { } else {
rm.done(); 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 * Start tracking the breakpoints. Note that for remote debugging
* we should first connect to the target. * we should first connect to the target.
@ -435,4 +478,4 @@ public class DebugNewProcessSequence extends ReflectionSequence {
fTracker = null; fTracker = null;
rm.done(); 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