|
Lines 9-22
Link Here
|
| 9 |
* Wind River Systems - initial API and implementation |
9 |
* Wind River Systems - initial API and implementation |
| 10 |
* Ericsson AB - Modified for handling of multiple threads |
10 |
* Ericsson AB - Modified for handling of multiple threads |
| 11 |
* Indel AG - [369622] fixed moveToLine using MinGW |
11 |
* Indel AG - [369622] fixed moveToLine using MinGW |
|
|
12 |
* Marc Khouzam (Ericsson) - Support for operations on multiple execution contexts (bug 330974) |
| 12 |
*******************************************************************************/ |
13 |
*******************************************************************************/ |
| 13 |
|
14 |
|
| 14 |
package org.eclipse.cdt.dsf.gdb.service; |
15 |
package org.eclipse.cdt.dsf.gdb.service; |
| 15 |
|
16 |
|
|
|
17 |
import java.util.ArrayList; |
| 18 |
import java.util.Arrays; |
| 16 |
import java.util.HashMap; |
19 |
import java.util.HashMap; |
| 17 |
import java.util.HashSet; |
20 |
import java.util.HashSet; |
| 18 |
import java.util.Hashtable; |
21 |
import java.util.Hashtable; |
| 19 |
import java.util.LinkedList; |
22 |
import java.util.LinkedList; |
|
|
23 |
import java.util.List; |
| 20 |
import java.util.Map; |
24 |
import java.util.Map; |
| 21 |
import java.util.Set; |
25 |
import java.util.Set; |
| 22 |
|
26 |
|
|
Lines 42-47
Link Here
|
| 42 |
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; |
46 |
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; |
| 43 |
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension.IBreakpointHitDMEvent; |
47 |
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension.IBreakpointHitDMEvent; |
| 44 |
import org.eclipse.cdt.dsf.debug.service.ICachingService; |
48 |
import org.eclipse.cdt.dsf.debug.service.ICachingService; |
|
|
49 |
import org.eclipse.cdt.dsf.debug.service.IMultiRunControl; |
| 45 |
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; |
50 |
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; |
| 46 |
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; |
51 |
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; |
| 47 |
import org.eclipse.cdt.dsf.debug.service.IRunControl; |
52 |
import org.eclipse.cdt.dsf.debug.service.IRunControl; |
|
Lines 104-110
Link Here
|
| 104 |
* sync with the service state. |
109 |
* sync with the service state. |
| 105 |
* @since 1.1 |
110 |
* @since 1.1 |
| 106 |
*/ |
111 |
*/ |
| 107 |
public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunControl, ICachingService |
112 |
public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunControl, IMultiRunControl, ICachingService |
| 108 |
{ |
113 |
{ |
| 109 |
@Immutable |
114 |
@Immutable |
| 110 |
private static class ExecutionData implements IExecutionDMData2 { |
115 |
private static class ExecutionData implements IExecutionDMData2 { |
|
Lines 396-402
Link Here
|
| 396 |
private void doInitialize(final RequestMonitor rm) { |
401 |
private void doInitialize(final RequestMonitor rm) { |
| 397 |
register(new String[]{ IRunControl.class.getName(), |
402 |
register(new String[]{ IRunControl.class.getName(), |
| 398 |
IRunControl2.class.getName(), |
403 |
IRunControl2.class.getName(), |
| 399 |
IMIRunControl.class.getName()}, |
404 |
IMIRunControl.class.getName(), |
|
|
405 |
IMultiRunControl.class.getName() }, |
| 400 |
new Hashtable<String,String>()); |
406 |
new Hashtable<String,String>()); |
| 401 |
fConnection = getServicesTracker().getService(ICommandControlService.class); |
407 |
fConnection = getServicesTracker().getService(ICommandControlService.class); |
| 402 |
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); |
408 |
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); |
|
Lines 1878-1881
Link Here
|
| 1878 |
} |
1884 |
} |
| 1879 |
return result; |
1885 |
return result; |
| 1880 |
} |
1886 |
} |
|
|
1887 |
|
| 1888 |
/** |
| 1889 |
* Removes duplicates from the list of execution contexts. |
| 1890 |
* Also, remove threads that are part of a process that is also present. |
| 1891 |
*/ |
| 1892 |
private List<IExecutionDMContext> extractContextsForOperation(IExecutionDMContext[] contexts) { |
| 1893 |
// Handle duplicate contexts by using a set |
| 1894 |
Set<IExecutionDMContext> specifiedExedDmcSet = new HashSet<IExecutionDMContext>(Arrays.asList(contexts)); |
| 1895 |
|
| 1896 |
// A list that ignores threads for which the process is also present |
| 1897 |
List<IExecutionDMContext> execDmcForOperationList = new ArrayList<IExecutionDMContext>(specifiedExedDmcSet.size()); |
| 1898 |
|
| 1899 |
// Check for the case of a process selected along with some of its threads |
| 1900 |
for (IExecutionDMContext execDmc : specifiedExedDmcSet) { |
| 1901 |
if (execDmc instanceof IContainerDMContext) { |
| 1902 |
// This is a process: it is automatically part of our list |
| 1903 |
execDmcForOperationList.add(execDmc); |
| 1904 |
} else { |
| 1905 |
// Get the process for this thread |
| 1906 |
IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class); |
| 1907 |
// Check if the process is also present |
| 1908 |
if (specifiedExedDmcSet.contains(containerDmc) == false) { |
| 1909 |
// This thread does not belong to a process that is selected, so we keep it. |
| 1910 |
execDmcForOperationList.add(execDmc); |
| 1911 |
} |
| 1912 |
} |
| 1913 |
} |
| 1914 |
return execDmcForOperationList; |
| 1915 |
} |
| 1916 |
|
| 1917 |
// Multi resume: |
| 1918 |
// |
| 1919 |
// If one or more more threads of one or many processes are selected, we want to |
| 1920 |
// resume each thread. |
| 1921 |
// |
| 1922 |
// If a process is selected along with one or more threads of that process, |
| 1923 |
// what does the user want us to do? Selecting the process means resume all its |
| 1924 |
// threads, but what do we do with the selected threads? Why are they |
| 1925 |
// selected? In an attempt to be user friendly, lets assume that the user |
| 1926 |
// wants to resume the entire process. |
| 1927 |
// |
| 1928 |
// On the other hand, selecting a process and also threads from another |
| 1929 |
// process makes perfect sense; the process is resumed, and the threads |
| 1930 |
// selected are handled as the normal case. |
| 1931 |
|
| 1932 |
/** @since 4.1 */ |
| 1933 |
@Override |
| 1934 |
public void canResumeSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 1935 |
assert contexts != null; |
| 1936 |
|
| 1937 |
if (fRunControlOperationsEnabled == false) { |
| 1938 |
rm.done(false); |
| 1939 |
return; |
| 1940 |
} |
| 1941 |
|
| 1942 |
List<IExecutionDMContext> execDmcToResumeList = extractContextsForOperation(contexts); |
| 1943 |
|
| 1944 |
// If any of the threads or processes can be resumed, we allow |
| 1945 |
// the user to perform the operation. |
| 1946 |
for (IExecutionDMContext execDmc : execDmcToResumeList) { |
| 1947 |
if (doCanResume(execDmc)) { |
| 1948 |
rm.done(true); |
| 1949 |
return; |
| 1950 |
} |
| 1951 |
} |
| 1952 |
|
| 1953 |
// Didn't find anything that could be resumed. |
| 1954 |
rm.done(false); |
| 1955 |
} |
| 1956 |
|
| 1957 |
/** @since 4.1 */ |
| 1958 |
@Override |
| 1959 |
public void canResumeAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 1960 |
assert contexts != null; |
| 1961 |
|
| 1962 |
if (fRunControlOperationsEnabled == false) { |
| 1963 |
rm.done(false); |
| 1964 |
return; |
| 1965 |
} |
| 1966 |
|
| 1967 |
List<IExecutionDMContext> execDmcToResumeList = extractContextsForOperation(contexts); |
| 1968 |
|
| 1969 |
// If any of the threads or processes cannot be resumed, we don't allow |
| 1970 |
// the user to perform the operation. |
| 1971 |
for (IExecutionDMContext execDmc : execDmcToResumeList) { |
| 1972 |
if (!doCanResume(execDmc)) { |
| 1973 |
rm.done(false); |
| 1974 |
return; |
| 1975 |
} |
| 1976 |
} |
| 1977 |
|
| 1978 |
// Everything can be resumed |
| 1979 |
rm.done(true); |
| 1980 |
} |
| 1981 |
|
| 1982 |
/** @since 4.1 */ |
| 1983 |
@Override |
| 1984 |
public void canSuspendSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 1985 |
assert contexts != null; |
| 1986 |
|
| 1987 |
if (fRunControlOperationsEnabled == false) { |
| 1988 |
rm.done(false); |
| 1989 |
return; |
| 1990 |
} |
| 1991 |
|
| 1992 |
List<IExecutionDMContext> execDmcToSuspendList = extractContextsForOperation(contexts); |
| 1993 |
|
| 1994 |
// If any of the threads or processes can be suspended, we allow |
| 1995 |
// the user to perform the operation. |
| 1996 |
for (IExecutionDMContext execDmc : execDmcToSuspendList) { |
| 1997 |
if (doCanSuspend(execDmc)) { |
| 1998 |
rm.done(true); |
| 1999 |
return; |
| 2000 |
} |
| 2001 |
} |
| 2002 |
|
| 2003 |
// Didn't find anything that could be suspended. |
| 2004 |
rm.done(false); |
| 2005 |
} |
| 2006 |
|
| 2007 |
/** @since 4.1 */ |
| 2008 |
@Override |
| 2009 |
public void canSuspendAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 2010 |
assert contexts != null; |
| 2011 |
|
| 2012 |
if (fRunControlOperationsEnabled == false) { |
| 2013 |
rm.done(false); |
| 2014 |
return; |
| 2015 |
} |
| 2016 |
|
| 2017 |
List<IExecutionDMContext> execDmcToSuspendList = extractContextsForOperation(contexts); |
| 2018 |
|
| 2019 |
// If any of the threads or processes cannot be suspended, we don't allow |
| 2020 |
// the user to perform the operation. |
| 2021 |
for (IExecutionDMContext execDmc : execDmcToSuspendList) { |
| 2022 |
if (!doCanSuspend(execDmc)) { |
| 2023 |
rm.done(false); |
| 2024 |
return; |
| 2025 |
} |
| 2026 |
} |
| 2027 |
|
| 2028 |
// Everything can be suspended |
| 2029 |
rm.done(true); |
| 2030 |
} |
| 2031 |
|
| 2032 |
/** @since 4.1 */ |
| 2033 |
@Override |
| 2034 |
public void isSuspendedSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 2035 |
assert contexts != null; |
| 2036 |
|
| 2037 |
List<IExecutionDMContext> execDmcSuspendedList = extractContextsForOperation(contexts); |
| 2038 |
|
| 2039 |
// Look for any thread or process that is suspended |
| 2040 |
for (IExecutionDMContext execDmc : execDmcSuspendedList) { |
| 2041 |
if (isSuspended(execDmc)) { |
| 2042 |
rm.done(true); |
| 2043 |
return; |
| 2044 |
} |
| 2045 |
} |
| 2046 |
|
| 2047 |
// Didn't find anything that was suspended. |
| 2048 |
rm.done(false); |
| 2049 |
} |
| 2050 |
|
| 2051 |
/** @since 4.1 */ |
| 2052 |
@Override |
| 2053 |
public void isSuspendedAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 2054 |
assert contexts != null; |
| 2055 |
|
| 2056 |
List<IExecutionDMContext> execDmcSuspendedList = extractContextsForOperation(contexts); |
| 2057 |
|
| 2058 |
// Look for any thread or process that is not suspended |
| 2059 |
for (IExecutionDMContext execDmc : execDmcSuspendedList) { |
| 2060 |
if (!isSuspended(execDmc)) { |
| 2061 |
rm.done(false); |
| 2062 |
return; |
| 2063 |
} |
| 2064 |
} |
| 2065 |
|
| 2066 |
// Everything is suspended. |
| 2067 |
rm.done(true); |
| 2068 |
} |
| 2069 |
|
| 2070 |
/** @since 4.1 */ |
| 2071 |
@Override |
| 2072 |
public void canStepSome(IExecutionDMContext[] contexts, StepType stepType, DataRequestMonitor<Boolean> rm) { |
| 2073 |
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$ |
| 2074 |
} |
| 2075 |
|
| 2076 |
/** @since 4.1 */ |
| 2077 |
@Override |
| 2078 |
public void canStepAll(IExecutionDMContext[] contexts, StepType stepType, DataRequestMonitor<Boolean> rm) { |
| 2079 |
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$ |
| 2080 |
} |
| 2081 |
|
| 2082 |
/** @since 4.1 */ |
| 2083 |
@Override |
| 2084 |
public void isSteppingSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 2085 |
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$ |
| 2086 |
} |
| 2087 |
|
| 2088 |
/** @since 4.1 */ |
| 2089 |
@Override |
| 2090 |
public void isSteppingAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { |
| 2091 |
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$ |
| 2092 |
} |
| 2093 |
|
| 2094 |
/** |
| 2095 |
* {@inheritDoc} |
| 2096 |
* |
| 2097 |
* For GDB, a separate resume command will be sent, one for each context |
| 2098 |
* that can be resumed. |
| 2099 |
* @since 4.1 |
| 2100 |
*/ |
| 2101 |
@Override |
| 2102 |
public void resume(IExecutionDMContext[] contexts, RequestMonitor rm) { |
| 2103 |
assert contexts != null; |
| 2104 |
|
| 2105 |
List<IExecutionDMContext> execDmcToResumeList = extractContextsForOperation(contexts); |
| 2106 |
|
| 2107 |
CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm); |
| 2108 |
int count = 0; |
| 2109 |
|
| 2110 |
// Perform resume operation on each thread or process that can be resumed |
| 2111 |
for (IExecutionDMContext execDmc : execDmcToResumeList) { |
| 2112 |
if (doCanResume(execDmc)) { |
| 2113 |
count++; |
| 2114 |
resume(execDmc, crm); |
| 2115 |
} |
| 2116 |
} |
| 2117 |
|
| 2118 |
crm.setDoneCount(count); |
| 2119 |
} |
| 2120 |
|
| 2121 |
/** |
| 2122 |
* {@inheritDoc} |
| 2123 |
* |
| 2124 |
* For GDB, a separate suspend command will be sent, one for each context |
| 2125 |
* that can be suspended. |
| 2126 |
* @since 4.1 |
| 2127 |
*/ |
| 2128 |
@Override |
| 2129 |
public void suspend(IExecutionDMContext[] contexts, RequestMonitor rm) { |
| 2130 |
assert contexts != null; |
| 2131 |
|
| 2132 |
List<IExecutionDMContext> execDmcToSuspendList = extractContextsForOperation(contexts); |
| 2133 |
|
| 2134 |
CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm); |
| 2135 |
int count = 0; |
| 2136 |
|
| 2137 |
// Perform resume operation on each thread or process that can be resumed |
| 2138 |
for (IExecutionDMContext execDmc : execDmcToSuspendList) { |
| 2139 |
if (doCanSuspend(execDmc)) { |
| 2140 |
count++; |
| 2141 |
suspend(execDmc, crm); |
| 2142 |
} |
| 2143 |
} |
| 2144 |
|
| 2145 |
crm.setDoneCount(count); |
| 2146 |
} |
| 2147 |
|
| 2148 |
/** @since 4.1 */ |
| 2149 |
@Override |
| 2150 |
public void step(IExecutionDMContext[] contexts, StepType stepType, RequestMonitor rm) { |
| 2151 |
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$ |
| 2152 |
} |
| 1881 |
} |
2153 |
} |