mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 08:46:02 +02:00
Bug 569397: Update SyncUtil's javadoc
Signed-off-by: Abdullah Khalid <abdullah.dev0@gmail.com> Change-Id: Id200f0c2badfc878503bdd5dc3a8b0f98ab1718c
This commit is contained in:
parent
05322656c6
commit
a7546a575f
1 changed files with 420 additions and 21 deletions
|
@ -93,7 +93,16 @@ import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.debug.core.model.MemoryByte;
|
import org.eclipse.debug.core.model.MemoryByte;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timeout wait values are in milliseconds, or WAIT_FOREVER.
|
* Utility class for common testing APIs
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: Most, if not all, methods in this class timeouts unless otherwise
|
||||||
|
* stated. If the method takes a timeout parameter then it would timeout after
|
||||||
|
* that much time elapses. However, even if the method does not take that
|
||||||
|
* parameter it would still timeout but with a default one as hardcoded in that
|
||||||
|
* method's implementation or, in most cases, as specified in {@code ETimeout}.
|
||||||
|
* Wherever a timeout is mentioned its wait values are or must be in
|
||||||
|
* milliseconds, or WAIT_FOREVER
|
||||||
*/
|
*/
|
||||||
public class SyncUtil {
|
public class SyncUtil {
|
||||||
|
|
||||||
|
@ -117,7 +126,12 @@ public class SyncUtil {
|
||||||
// Each version of GDB can expose the set of register differently
|
// Each version of GDB can expose the set of register differently
|
||||||
private static Map<String, List<String>> fRegisterNames = new HashMap<>();
|
private static Map<String, List<String>> fRegisterNames = new HashMap<>();
|
||||||
|
|
||||||
// Initialize some common things, once the session has been established
|
/**
|
||||||
|
* Initialize some common things, once the session has been established
|
||||||
|
*
|
||||||
|
* @param session
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static void initialize(DsfSession session) throws Exception {
|
public static void initialize(DsfSession session) throws Exception {
|
||||||
fSession = session;
|
fSession = session;
|
||||||
|
|
||||||
|
@ -138,10 +152,30 @@ public class SyncUtil {
|
||||||
fSession.getExecutor().submit(runnable).get();
|
fSession.getExecutor().submit(runnable).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward with the given {@code stepType} and can also specify to step a
|
||||||
|
* fixed number of time/s using {@code numSteps}. For possible step types see
|
||||||
|
* {@link SyncUtil#step(StepType) step(StepType)}
|
||||||
|
*
|
||||||
|
* @param numSteps
|
||||||
|
* @param stepType
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(int numSteps, StepType stepType) throws Throwable {
|
public static MIStoppedEvent step(int numSteps, StepType stepType) throws Throwable {
|
||||||
return step(numSteps, stepType, false);
|
return step(numSteps, stepType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward or backward with the given {@code stepType} and can also
|
||||||
|
* specify to step a fixed number of time/s using {@code numSteps}. For a list
|
||||||
|
* of possible step types see {@link SyncUtil#step(StepType) step(StepType)}
|
||||||
|
*
|
||||||
|
* @param numSteps
|
||||||
|
* @param stepType
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(int numSteps, StepType stepType, boolean reverse) throws Throwable {
|
public static MIStoppedEvent step(int numSteps, StepType stepType, boolean reverse) throws Throwable {
|
||||||
MIStoppedEvent retVal = null;
|
MIStoppedEvent retVal = null;
|
||||||
for (int i = 0; i < numSteps; i++) {
|
for (int i = 0; i < numSteps; i++) {
|
||||||
|
@ -150,24 +184,80 @@ public class SyncUtil {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward with the given {@code stepType} A {@code stepType} can be one
|
||||||
|
* of the following:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@code StepType.STEP_OVER}
|
||||||
|
* <li>{@code StepType.STEP_INTO}
|
||||||
|
* <li>{@code StepType.STEP_RETURN}
|
||||||
|
* <li>{@code StepType.INSTRUCTION_STEP_OVER}
|
||||||
|
* <li>{@code StepType.INSTRUCTION_STEP_INTO}
|
||||||
|
* <li>{@code StepType.INSTRUCTION_STEP_RETURN}
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param stepType
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(StepType stepType) throws Throwable {
|
public static MIStoppedEvent step(StepType stepType) throws Throwable {
|
||||||
return step(stepType, false, DefaultTimeouts.get(ETimeout.step));
|
return step(stepType, false, DefaultTimeouts.get(ETimeout.step));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward or backward with the given {@code stepType}. For possible step
|
||||||
|
* types see {@link SyncUtil#step(StepType) step(StepType)}
|
||||||
|
*
|
||||||
|
* @param stepType
|
||||||
|
* @param reverse
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(StepType stepType, boolean reverse, int massagedTimeout) throws Throwable {
|
public static MIStoppedEvent step(StepType stepType, boolean reverse, int massagedTimeout) throws Throwable {
|
||||||
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
||||||
return step(containerDmc, stepType, reverse, massagedTimeout);
|
return step(containerDmc, stepType, reverse, massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward with the given {@code stepType} and can also specify to step a
|
||||||
|
* given process or thread {@code dmc}. For possible step types see
|
||||||
|
* {@link SyncUtil#step(StepType) step(StepType)}
|
||||||
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @param stepType
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(IExecutionDMContext dmc, StepType stepType) throws Throwable {
|
public static MIStoppedEvent step(IExecutionDMContext dmc, StepType stepType) throws Throwable {
|
||||||
return step(dmc, stepType, DefaultTimeouts.get(ETimeout.step));
|
return step(dmc, stepType, DefaultTimeouts.get(ETimeout.step));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward with the given {@code stepType} and can also specify to step a
|
||||||
|
* given process or thread {@code dmc}. For possible step types see
|
||||||
|
* {@link SyncUtil#step(StepType) step(StepType)}
|
||||||
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @param stepType
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(final IExecutionDMContext dmc, final StepType stepType, int massagedTimeout)
|
public static MIStoppedEvent step(final IExecutionDMContext dmc, final StepType stepType, int massagedTimeout)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
return step(dmc, stepType, false, massagedTimeout);
|
return step(dmc, stepType, false, massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steps forward or backward with the given {@code stepType} and can also
|
||||||
|
* specify to step a given process or thread {@code dmc}. For possible step
|
||||||
|
* types see {@link SyncUtil#step(StepType) step(StepType)}
|
||||||
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @param stepType
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent step(final IExecutionDMContext dmc, final StepType stepType, boolean reverse,
|
public static MIStoppedEvent step(final IExecutionDMContext dmc, final StepType stepType, boolean reverse,
|
||||||
int massagedTimeout) throws Throwable {
|
int massagedTimeout) throws Throwable {
|
||||||
final ServiceEventWaitor<MIStoppedEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIStoppedEvent.class);
|
final ServiceEventWaitor<MIStoppedEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIStoppedEvent.class);
|
||||||
|
@ -216,18 +306,56 @@ public class SyncUtil {
|
||||||
return eventWaitor.waitForEvent(massagedTimeout);
|
return eventWaitor.waitForEvent(massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a breakpoint at {@code location}. The {@code location} is the one which
|
||||||
|
* the underlying debugger understands. For example, in case of gdb
|
||||||
|
* "<current-file>:<line#>" or "<line#>" or "<function-name>" are all valid
|
||||||
|
* locations. Refer to the debugger documentation to see all valid locations
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static String addBreakpoint(String location) throws Throwable {
|
public static String addBreakpoint(String location) throws Throwable {
|
||||||
return addBreakpoint(location, DefaultTimeouts.get(ETimeout.addBreakpoint));
|
return addBreakpoint(location, DefaultTimeouts.get(ETimeout.addBreakpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a breakpoint at {@code location}. For an example of possible locations
|
||||||
|
* see {@link SyncUtil#addBreakpoint(String) addBreakpoint(String)}
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static String addBreakpoint(String location, int massagedTimeout) throws Throwable {
|
public static String addBreakpoint(String location, int massagedTimeout) throws Throwable {
|
||||||
return addBreakpoint(location, true, massagedTimeout);
|
return addBreakpoint(location, true, massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a (possible temporary) breakpoint at {@code location}. For possible
|
||||||
|
* locations see {@link SyncUtil#addBreakpoint(String) addBreakpoint(String)}
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static String addBreakpoint(String location, boolean temporary) throws Throwable {
|
public static String addBreakpoint(String location, boolean temporary) throws Throwable {
|
||||||
return addBreakpoint(location, temporary, DefaultTimeouts.get(ETimeout.addBreakpoint));
|
return addBreakpoint(location, temporary, DefaultTimeouts.get(ETimeout.addBreakpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a (possible temporary) breakpoint at {@code location}. For possible
|
||||||
|
* locations see {@link SyncUtil#addBreakpoint(String) addBreakpoint(String)}
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* @param temporary
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
private static String addBreakpoint(final String location, final boolean temporary, int massagedTimeout)
|
private static String addBreakpoint(final String location, final boolean temporary, int massagedTimeout)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
|
|
||||||
|
@ -248,6 +376,13 @@ public class SyncUtil {
|
||||||
return info.getMIBreakpoints()[0].getNumber();
|
return info.getMIBreakpoints()[0].getNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the breakpoint list
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static String[] getBreakpointList(int timeout) throws Throwable {
|
public static String[] getBreakpointList(int timeout) throws Throwable {
|
||||||
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
||||||
final IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(containerDmc,
|
final IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(containerDmc,
|
||||||
|
@ -271,6 +406,15 @@ public class SyncUtil {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the process or thread ({@code dmc}) until its stopped (via
|
||||||
|
* breakpoint, termination or, any other means)
|
||||||
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
private static MIStoppedEvent resumeUntilStopped(final IExecutionDMContext dmc, int massagedTimeout)
|
private static MIStoppedEvent resumeUntilStopped(final IExecutionDMContext dmc, int massagedTimeout)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
final ServiceEventWaitor<MIStoppedEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIStoppedEvent.class);
|
final ServiceEventWaitor<MIStoppedEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIStoppedEvent.class);
|
||||||
|
@ -283,17 +427,40 @@ public class SyncUtil {
|
||||||
return eventWaitor.waitForEvent(massagedTimeout);
|
return eventWaitor.waitForEvent(massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the process until its stopped (via breakpoint, termination or, any
|
||||||
|
* other means)
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent resumeUntilStopped() throws Throwable {
|
public static MIStoppedEvent resumeUntilStopped() throws Throwable {
|
||||||
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
||||||
// Don't call resumeUtilStopped(int timeout) as this will duplicate the timeout massage
|
// Don't call resumeUtilStopped(int timeout) as this will duplicate the timeout massage
|
||||||
return resumeUntilStopped(containerDmc, DefaultTimeouts.get(ETimeout.resumeUntilStopped));
|
return resumeUntilStopped(containerDmc, DefaultTimeouts.get(ETimeout.resumeUntilStopped));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the process until its stopped (via breakpoint, termination or, any
|
||||||
|
* other means)
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent resumeUntilStopped(int timeout) throws Throwable {
|
public static MIStoppedEvent resumeUntilStopped(int timeout) throws Throwable {
|
||||||
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
||||||
return resumeUntilStopped(containerDmc, TestsPlugin.massageTimeout(timeout));
|
return resumeUntilStopped(containerDmc, TestsPlugin.massageTimeout(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the process or thread ({@code dmc})
|
||||||
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIRunningEvent resume(final IExecutionDMContext dmc, int massagedTimeout) throws Throwable {
|
public static MIRunningEvent resume(final IExecutionDMContext dmc, int massagedTimeout) throws Throwable {
|
||||||
final ServiceEventWaitor<MIRunningEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIRunningEvent.class);
|
final ServiceEventWaitor<MIRunningEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIRunningEvent.class);
|
||||||
|
|
||||||
|
@ -305,6 +472,13 @@ public class SyncUtil {
|
||||||
return eventWaitor.waitForEvent(massagedTimeout);
|
return eventWaitor.waitForEvent(massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the process or thread ({@code execDmc}) can resume or not
|
||||||
|
*
|
||||||
|
* @param execDmc
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static boolean canResume(final IExecutionDMContext execDmc) throws Throwable {
|
public static boolean canResume(final IExecutionDMContext execDmc) throws Throwable {
|
||||||
Query<Boolean> query = new Query<Boolean>() {
|
Query<Boolean> query = new Query<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -323,19 +497,43 @@ public class SyncUtil {
|
||||||
return canResume;
|
return canResume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the process timeout
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIRunningEvent resume() throws Throwable {
|
public static MIRunningEvent resume() throws Throwable {
|
||||||
return resume(DefaultTimeouts.get(ETimeout.resume));
|
return resume(DefaultTimeouts.get(ETimeout.resume));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the process
|
||||||
|
*
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIRunningEvent resume(int massagedTimeout) throws Throwable {
|
public static MIRunningEvent resume(int massagedTimeout) throws Throwable {
|
||||||
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
|
||||||
return resume(containerDmc, massagedTimeout);
|
return resume(containerDmc, massagedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes all the threads
|
||||||
|
*
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static void resumeAll() throws Throwable {
|
public static void resumeAll() throws Throwable {
|
||||||
resumeAll(DefaultTimeouts.get(ETimeout.resume));
|
resumeAll(DefaultTimeouts.get(ETimeout.resume));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes all the threads
|
||||||
|
*
|
||||||
|
* @param massagedTimeout
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static void resumeAll(int massagedTimeout) throws Throwable {
|
public static void resumeAll(int massagedTimeout) throws Throwable {
|
||||||
IMIExecutionDMContext[] threadDmcs = SyncUtil.getExecutionContexts();
|
IMIExecutionDMContext[] threadDmcs = SyncUtil.getExecutionContexts();
|
||||||
for (IMIExecutionDMContext thread : threadDmcs) {
|
for (IMIExecutionDMContext thread : threadDmcs) {
|
||||||
|
@ -345,19 +543,33 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits for and gets the stop event
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent waitForStop() throws Throwable {
|
public static MIStoppedEvent waitForStop() throws Throwable {
|
||||||
// Use a direct value to avoid double call to TestsPlugin.massageTimeout
|
// Use a direct value to avoid double call to TestsPlugin.massageTimeout
|
||||||
return waitForStop(10000);
|
return waitForStop(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is risky. If the command to resume/step execution
|
/**
|
||||||
// is sent and the stopped event is received before we call this method
|
* Waits for and gets the stop event
|
||||||
// here, then we will miss the stopped event.
|
*
|
||||||
// Normally, one should initialize the ServiveEventWaitor before
|
* <p>
|
||||||
// triggering the resume to make sure not to miss the stopped event.
|
* Note: This method is risky. If the command to resume/step execution is sent
|
||||||
// However, in some case this method will still work, for instance
|
* and the stopped event is received before we call this method here, then we
|
||||||
// if there is a sleep in the code between the resume and the time
|
* will miss the stopped event. Normally, one should initialize the
|
||||||
// it stops; this will give us plenty of time to call this method.
|
* ServiveEventWaitor before triggering the resume to make sure not to miss the
|
||||||
|
* stopped event. However, in some case this method will still work, for
|
||||||
|
* instance if there is a sleep in the code between the resume and the time it
|
||||||
|
* stops; this will give us plenty of time to call this method.
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent waitForStop(int timeout) throws Throwable {
|
public static MIStoppedEvent waitForStop(int timeout) throws Throwable {
|
||||||
final ServiceEventWaitor<MIStoppedEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIStoppedEvent.class);
|
final ServiceEventWaitor<MIStoppedEvent> eventWaitor = new ServiceEventWaitor<>(fSession, MIStoppedEvent.class);
|
||||||
|
|
||||||
|
@ -365,10 +577,27 @@ public class SyncUtil {
|
||||||
return eventWaitor.waitForEvent(TestsPlugin.massageTimeout(timeout));
|
return eventWaitor.waitForEvent(TestsPlugin.massageTimeout(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the process' execution to {@code location}. For an example of possible
|
||||||
|
* locations see {@link SyncUtil#addBreakpoint(String) addBreakpoint(String)}
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent runToLocation(String location) throws Throwable {
|
public static MIStoppedEvent runToLocation(String location) throws Throwable {
|
||||||
return runToLocation(location, DefaultTimeouts.get(ETimeout.runToLocation));
|
return runToLocation(location, DefaultTimeouts.get(ETimeout.runToLocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the process' execution to {@code location}. For an example of possible
|
||||||
|
* locations see {@link SyncUtil#addBreakpoint(String) addBreakpoint(String)}
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static MIStoppedEvent runToLocation(String location, int timeout) throws Throwable {
|
public static MIStoppedEvent runToLocation(String location, int timeout) throws Throwable {
|
||||||
// Set a temporary breakpoint and run to it.
|
// Set a temporary breakpoint and run to it.
|
||||||
// Note that if there were other breakpoints set ahead of this one,
|
// Note that if there were other breakpoints set ahead of this one,
|
||||||
|
@ -379,6 +608,17 @@ public class SyncUtil {
|
||||||
return resumeUntilStopped();
|
return resumeUntilStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the stack frame of the thread ({@code execCtx}). As each stack frame
|
||||||
|
* consists of many levels therefore {@code level} is needed to signify the
|
||||||
|
* level of the stack frame to get, like, 0 for the top-most level or 1 for the
|
||||||
|
* one after that
|
||||||
|
*
|
||||||
|
* @param execCtx
|
||||||
|
* @param level
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static IFrameDMContext getStackFrame(final IExecutionDMContext execCtx, final int level) throws Exception {
|
public static IFrameDMContext getStackFrame(final IExecutionDMContext execCtx, final int level) throws Exception {
|
||||||
Query<IFrameDMContext> query = new Query<IFrameDMContext>() {
|
Query<IFrameDMContext> query = new Query<IFrameDMContext>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -401,17 +641,49 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to return a specific frame DM context.
|
* Gets the stack frame of the thread whose index corresponds with the specified
|
||||||
|
* {@code threadIndex}. As each stack frame consists of many levels therefore
|
||||||
|
* {@code level} is needed to signify the level of the stack frame to get, like,
|
||||||
|
* 0 for the top-most level or 1 for the one after that
|
||||||
|
*
|
||||||
|
* @param threadIndex
|
||||||
|
* @param level
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
|
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
|
||||||
public static IFrameDMContext getStackFrame(int threadIndex, final int level) throws Exception {
|
public static IFrameDMContext getStackFrame(int threadIndex, final int level) throws Exception {
|
||||||
return getStackFrame(getExecutionContext(threadIndex), level);
|
return getStackFrame(getExecutionContext(threadIndex), level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the stack depth of the thread ({@code execCtx}). A stack depth is the
|
||||||
|
* maximum level of that stack frame
|
||||||
|
*
|
||||||
|
* @param execCtx
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static Integer getStackDepth(final IExecutionDMContext execCtx) throws Throwable {
|
public static Integer getStackDepth(final IExecutionDMContext execCtx) throws Throwable {
|
||||||
return getStackDepth(execCtx, 0);
|
return getStackDepth(execCtx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the stack depth of the thread ({@code execCtx}). A stack depth is the
|
||||||
|
* maximum level of that stack frame. If {@code maxDepth} is specified then it
|
||||||
|
* does not count beyond {@code maxDepth} frames
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For example, given stack with frame levels 0 through 11 and a
|
||||||
|
* {@code maxDepth} of 4 would return 4. However, with a {@code maxDepth} of 13
|
||||||
|
* it would return 12 (i.e. the actual depth)
|
||||||
|
*
|
||||||
|
* @param execCtx
|
||||||
|
* @param maxDepth
|
||||||
|
* @return If {@code maxDepth} is greater than the actual depth then actual
|
||||||
|
* depth is returned else {@code maxDepth} is returned
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static Integer getStackDepth(final IExecutionDMContext execCtx, final int maxDepth) throws Throwable {
|
public static Integer getStackDepth(final IExecutionDMContext execCtx, final int maxDepth) throws Throwable {
|
||||||
Query<Integer> query = new Query<Integer>() {
|
Query<Integer> query = new Query<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -424,6 +696,15 @@ public class SyncUtil {
|
||||||
return query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
|
return query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the frame data of the stack frame belonging to the specified thread
|
||||||
|
* ({@code execCtx}) and whose level is given by {@code level}
|
||||||
|
*
|
||||||
|
* @param execCtx
|
||||||
|
* @param level
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static IFrameDMData getFrameData(final IExecutionDMContext execCtx, final int level) throws Throwable {
|
public static IFrameDMData getFrameData(final IExecutionDMContext execCtx, final int level) throws Throwable {
|
||||||
Query<IFrameDMData> query = new Query<IFrameDMData>() {
|
Query<IFrameDMData> query = new Query<IFrameDMData>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -444,10 +725,27 @@ public class SyncUtil {
|
||||||
return query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
|
return query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IFrameDMData getFrameData(final int threadId, final int level) throws Throwable {
|
/**
|
||||||
return getFrameData(getExecutionContext(threadId), level);
|
* Gets the frame data of the stack frame belonging to that thread whose index
|
||||||
|
* is specified by {@code threadIndex} and whose level is given by {@code level}
|
||||||
|
*
|
||||||
|
* @param threadIndex
|
||||||
|
* @param level
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
public static IFrameDMData getFrameData(final int threadIndex, final int level) throws Throwable {
|
||||||
|
return getFrameData(getExecutionContext(threadIndex), level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the thread data of the thread whose thread id is specifed by
|
||||||
|
* {@code threadId}
|
||||||
|
*
|
||||||
|
* @param threadId
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static IThreadDMData getThreadData(final int threadId)
|
public static IThreadDMData getThreadData(final int threadId)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
final IProcessDMContext processContext = DMContexts.getAncestorOfType(SyncUtil.getContainerContext(),
|
final IProcessDMContext processContext = DMContexts.getAncestorOfType(SyncUtil.getContainerContext(),
|
||||||
|
@ -467,12 +765,32 @@ public class SyncUtil {
|
||||||
return query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
|
return query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and gets the expression ({@code expression}) in the context of the
|
||||||
|
* given process, thread or, frame ({@code parentCtx}). For example, given 2
|
||||||
|
* thread, thread1 and thread2, an expression may not be valid in the context of
|
||||||
|
* thread1 but it may be valid in the context of thread2. Therefore, while
|
||||||
|
* creating expression its important that the correct context is passed
|
||||||
|
*
|
||||||
|
* @param parentCtx
|
||||||
|
* @param expression
|
||||||
|
* @return the expression
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static IExpressionDMContext createExpression(final IDMContext parentCtx, final String expression)
|
public static IExpressionDMContext createExpression(final IDMContext parentCtx, final String expression)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
Callable<IExpressionDMContext> callable = () -> fExpressions.createExpression(parentCtx, expression);
|
Callable<IExpressionDMContext> callable = () -> fExpressions.createExpression(parentCtx, expression);
|
||||||
return fSession.getExecutor().submit(callable).get();
|
return fSession.getExecutor().submit(callable).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the sub-expressions in the given expression ({@code dmc})
|
||||||
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @return
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @throws ExecutionException
|
||||||
|
*/
|
||||||
public static IExpressionDMContext[] getSubExpressions(final IExpressionDMContext dmc)
|
public static IExpressionDMContext[] getSubExpressions(final IExpressionDMContext dmc)
|
||||||
throws InterruptedException, ExecutionException {
|
throws InterruptedException, ExecutionException {
|
||||||
Query<IExpressionDMContext[]> query = new Query<IExpressionDMContext[]>() {
|
Query<IExpressionDMContext[]> query = new Query<IExpressionDMContext[]>() {
|
||||||
|
@ -486,9 +804,13 @@ public class SyncUtil {
|
||||||
return query.get();
|
return query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Like getSubExpressions, but for cases where we know there will be only
|
* Gets the first sub-expression in the expression ({@code dmc})
|
||||||
* one child.
|
*
|
||||||
|
* @param dmc
|
||||||
|
* @return
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @throws ExecutionException
|
||||||
*/
|
*/
|
||||||
public static IExpressionDMContext getSubExpression(final IExpressionDMContext dmc)
|
public static IExpressionDMContext getSubExpression(final IExpressionDMContext dmc)
|
||||||
throws InterruptedException, ExecutionException {
|
throws InterruptedException, ExecutionException {
|
||||||
|
@ -499,6 +821,25 @@ public class SyncUtil {
|
||||||
return subExpressions[0];
|
return subExpressions[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@code String} representation of the specified expression
|
||||||
|
* ({@code dmc}) in the given {@code format}. The {@code format} may be one of
|
||||||
|
* the following:
|
||||||
|
* <ul>
|
||||||
|
* <li>@{code IFormattedValues.HEX_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.OCTAL_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.NATURAL_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.BINARY_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.DECIMAL_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.STRING_FORMAT}
|
||||||
|
* <li>@{code MIExpressions.DETAILS_FORMAT}
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param exprDmc
|
||||||
|
* @param format
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static String getExpressionValue(final IExpressionDMContext exprDmc, final String format) throws Throwable {
|
public static String getExpressionValue(final IExpressionDMContext exprDmc, final String format) throws Throwable {
|
||||||
Query<String> query = new Query<String>() {
|
Query<String> query = new Query<String>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -518,12 +859,40 @@ public class SyncUtil {
|
||||||
return query.get();
|
return query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the formatted value of the specified data ({@code dmc}) in the given
|
||||||
|
* {@code formatId}. The {@code formatId} may be one of the following:
|
||||||
|
* <ul>
|
||||||
|
* <li>@{code IFormattedValues.HEX_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.OCTAL_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.NATURAL_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.BINARY_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.DECIMAL_FORMAT}
|
||||||
|
* <li>@{code IFormattedValues.STRING_FORMAT}
|
||||||
|
* <li>@{code MIExpressions.DETAILS_FORMAT}
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param service
|
||||||
|
* @param dmc
|
||||||
|
* @param formatId
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static FormattedValueDMContext getFormattedValue(final IFormattedValues service,
|
public static FormattedValueDMContext getFormattedValue(final IFormattedValues service,
|
||||||
final IFormattedDataDMContext dmc, final String formatId) throws Throwable {
|
final IFormattedDataDMContext dmc, final String formatId) throws Throwable {
|
||||||
Callable<FormattedValueDMContext> callable = () -> service.getFormattedValueContext(dmc, formatId);
|
Callable<FormattedValueDMContext> callable = () -> service.getFormattedValueContext(dmc, formatId);
|
||||||
return fSession.getExecutor().submit(callable).get();
|
return fSession.getExecutor().submit(callable).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the thread belonging to the specified process ({@code parentCtx}) and
|
||||||
|
* whose thread id is specified by {@code threadId}
|
||||||
|
*
|
||||||
|
* @param parentCtx
|
||||||
|
* @param threadId
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static IMIExecutionDMContext createExecutionContext(final IContainerDMContext parentCtx, final int threadId)
|
public static IMIExecutionDMContext createExecutionContext(final IContainerDMContext parentCtx, final int threadId)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
Callable<IMIExecutionDMContext> callable = () -> {
|
Callable<IMIExecutionDMContext> callable = () -> {
|
||||||
|
@ -535,6 +904,14 @@ public class SyncUtil {
|
||||||
return fSession.getExecutor().submit(callable).get();
|
return fSession.getExecutor().submit(callable).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout manager for tests. Its reponsibilities include:
|
||||||
|
* <ul>
|
||||||
|
* <li>Specify default timeouts
|
||||||
|
* <li>Make timeouts configurable
|
||||||
|
* <li>Massage timeouts i.e. a common multiplier for all timeouts
|
||||||
|
* <ul>
|
||||||
|
*/
|
||||||
static class DefaultTimeouts {
|
static class DefaultTimeouts {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -658,9 +1035,12 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to return all thread execution contexts.
|
* Utility method to return all threads
|
||||||
* @throws TimeoutException
|
*
|
||||||
|
* @return
|
||||||
|
* @throws InterruptedException
|
||||||
* @throws ExecutionException
|
* @throws ExecutionException
|
||||||
|
* @throws TimeoutException
|
||||||
*/
|
*/
|
||||||
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
|
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
|
||||||
public static IMIExecutionDMContext[] getExecutionContexts()
|
public static IMIExecutionDMContext[] getExecutionContexts()
|
||||||
|
@ -694,9 +1074,13 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to return a specific execution DM context.
|
* Utility method to return a specific thread via {@code threadIndex}
|
||||||
* @throws TimeoutException
|
*
|
||||||
|
* @param threadIndex
|
||||||
|
* @return
|
||||||
|
* @throws InterruptedException
|
||||||
* @throws ExecutionException
|
* @throws ExecutionException
|
||||||
|
* @throws TimeoutException
|
||||||
*/
|
*/
|
||||||
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
|
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
|
||||||
public static IMIExecutionDMContext getExecutionContext(int threadIndex)
|
public static IMIExecutionDMContext getExecutionContext(int threadIndex)
|
||||||
|
@ -709,6 +1093,9 @@ public class SyncUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the restart operation is supported
|
* Check if the restart operation is supported
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static boolean canRestart() throws Exception {
|
public static boolean canRestart() throws Exception {
|
||||||
final IContainerDMContext containerDmc = getContainerContext();
|
final IContainerDMContext containerDmc = getContainerContext();
|
||||||
|
@ -734,7 +1121,11 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restart the program.
|
* Restarts the program ({@code launch})
|
||||||
|
*
|
||||||
|
* @param launch
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static MIStoppedEvent restart(final GdbLaunch launch) throws Exception {
|
public static MIStoppedEvent restart(final GdbLaunch launch) throws Exception {
|
||||||
final IContainerDMContext containerDmc = getContainerContext();
|
final IContainerDMContext containerDmc = getContainerContext();
|
||||||
|
@ -772,6 +1163,13 @@ public class SyncUtil {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the local variables of the frame ({@code frameDmc})
|
||||||
|
*
|
||||||
|
* @param frameDmc
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
public static IVariableDMData[] getLocals(final IFrameDMContext frameDmc) throws Throwable {
|
public static IVariableDMData[] getLocals(final IFrameDMContext frameDmc) throws Throwable {
|
||||||
Query<IVariableDMData[]> query = new Query<IVariableDMData[]>() {
|
Query<IVariableDMData[]> query = new Query<IVariableDMData[]>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -815,6 +1213,7 @@ public class SyncUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the registers directly from GDB (without using the registers service)
|
* Get the registers directly from GDB (without using the registers service)
|
||||||
|
*
|
||||||
* @param gdbVersion
|
* @param gdbVersion
|
||||||
* @param context
|
* @param context
|
||||||
* @return
|
* @return
|
||||||
|
|
Loading…
Add table
Reference in a new issue