/******************************************************************************* * Copyright (c) 2009, 2015 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: * Ericsson - Initial implementation of Test cases *******************************************************************************/ package org.eclipse.cdt.tests.dsf.gdb.tests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.Query; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.debug.service.IBreakpoints; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMData; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsAddedEvent; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsRemovedEvent; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsUpdatedEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.CollectAction; import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.EvaluateAction; import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager; import org.eclipse.cdt.dsf.gdb.launching.LaunchUtils; import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData; import org.eclipse.cdt.dsf.mi.service.MIBreakpoints; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.tests.dsf.gdb.framework.BaseParametrizedTestCase; import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil; import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin; import org.eclipse.core.runtime.Platform; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @RunWith(Parameterized.class) public class GDBRemoteTracepointsTest extends BaseParametrizedTestCase { protected DsfSession fSession; protected DsfServicesTracker fServicesTracker; protected IBreakpoints fBreakpointService; // private ITraceControl fTraceService; protected IBreakpointsTargetDMContext fBreakpointsDmc; // private ITraceTargetDMContext fTraceTargetDmc; // private int fTotalTracingBufferSize = 0; protected static final String EXEC_NAME = "TracepointTestApp.exe"; protected static final String SOURCE_NAME = "TracepointTestApp.cc"; protected static final int LINE_NUMBER_1_BYTE_INSTR = 28; protected static final int LINE_NUMBER_2_BYTE_INSTR = 15; protected static final int LINE_NUMBER_3_BYTE_INSTR = 17; protected static final int LINE_NUMBER_4_BYTE_INSTR = 19; protected static final int LINE_NUMBER_5_BYTE_INSTR = 21; protected static final String NO_CONDITION = ""; protected static final String NO_COMMANDS = ""; // private static final int LAST_LINE_NUMBER = 94; // // private static final int TOTAL_FRAMES_TO_BE_COLLECTED = 1 + 1 + 10 + 1 + 10000; protected final static int[] PASS_COUNTS = {12, 2, 32, 6, 128, 0, 0, 0, 0, 0, 0, 0}; protected final static String[] CONDITIONS = {"gIntVar == 543", "gBoolVar == false", "x == 3", "x > 4", "x > 2 && gIntVar == 12345"}; protected static CollectAction[] COLLECT_ACTIONS = new CollectAction[10]; protected static EvaluateAction[] EVAL_ACTIONS = new EvaluateAction[10]; // private static WhileSteppingAction[] STEPPING_ACTION_1 = new WhileSteppingAction[3]; @BeforeClass public static void initializeActions() { TracepointActionManager tracepointActionMgr = TracepointActionManager.getInstance(); int index = 0; COLLECT_ACTIONS[index] = new CollectAction(); COLLECT_ACTIONS[index].setCollectString("$locals"); COLLECT_ACTIONS[index].setName("Collect locals"); tracepointActionMgr.addAction(COLLECT_ACTIONS[index]); index++; COLLECT_ACTIONS[index] = new CollectAction(); COLLECT_ACTIONS[index].setCollectString("gIntVar"); COLLECT_ACTIONS[index].setName("Collect gIntVar"); tracepointActionMgr.addAction(COLLECT_ACTIONS[index]); index++; COLLECT_ACTIONS[index] = new CollectAction(); COLLECT_ACTIONS[index].setCollectString("$locals, x, $reg"); COLLECT_ACTIONS[index].setName("Collect locals, x and reg"); tracepointActionMgr.addAction(COLLECT_ACTIONS[index]); index++; COLLECT_ACTIONS[index] = new CollectAction(); COLLECT_ACTIONS[index].setCollectString("$reg"); COLLECT_ACTIONS[index].setName("Collect reg"); tracepointActionMgr.addAction(COLLECT_ACTIONS[index]); index++; COLLECT_ACTIONS[index] = new CollectAction(); COLLECT_ACTIONS[index].setCollectString("x, $locals"); COLLECT_ACTIONS[index].setName("Collect x, locals"); tracepointActionMgr.addAction(COLLECT_ACTIONS[index]); index++; COLLECT_ACTIONS[index] = new CollectAction(); COLLECT_ACTIONS[index].setCollectString("$myTraceVariable"); COLLECT_ACTIONS[index].setName("Collect myTraceVariable"); tracepointActionMgr.addAction(COLLECT_ACTIONS[index]); index++; index=0; EVAL_ACTIONS[index] = new EvaluateAction(); EVAL_ACTIONS[index].setEvalString("$count=$count+1"); EVAL_ACTIONS[index].setName("Eval increment count"); tracepointActionMgr.addAction(EVAL_ACTIONS[index]); index++; EVAL_ACTIONS[index] = new EvaluateAction(); EVAL_ACTIONS[index].setEvalString("$count2=$count2+2"); EVAL_ACTIONS[index].setName("Eval increment count2 by 2"); tracepointActionMgr.addAction(EVAL_ACTIONS[index]); index++; EVAL_ACTIONS[index] = new EvaluateAction(); EVAL_ACTIONS[index].setEvalString("$count3=$count3+3"); EVAL_ACTIONS[index].setName("Eval increment count3 by 3"); tracepointActionMgr.addAction(EVAL_ACTIONS[index]); index++; //TODO do while stepping actions index=0; } @Override public void doBeforeTest() throws Exception { Assume.assumeTrue("Skipping non-remote", remote); super.doBeforeTest(); fSession = getGDBLaunch().getSession(); Runnable runnable = new Runnable() { @Override public void run() { fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); fBreakpointService = fServicesTracker.getService(IBreakpoints.class); // fTraceService = fServicesTracker.getService(ITraceControl.class); fSession.addServiceEventListener(GDBRemoteTracepointsTest.this, null); // Create a large array to make sure we don't run out fTracepoints = new IBreakpointDMContext[100]; // Run an initial test to check that everything is ok with GDB checkTraceInitialStatus(); } }; fSession.getExecutor().submit(runnable).get(); IContainerDMContext containerDmc = SyncUtil.getContainerContext(); fBreakpointsDmc = DMContexts.getAncestorOfType(containerDmc, IBreakpointsTargetDMContext.class); assert(fBreakpointsDmc != null); // fTraceTargetDmc = DMContexts.getAncestorOfType(containerDmc, ITraceTargetDMContext.class); } @Override protected void setLaunchAttributes() { super.setLaunchAttributes(); setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, EXEC_PATH + EXEC_NAME); // GDB tracepoints are only supported on a remote target (e.g., using gdbserver) setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); // To test both fast and normal tracepoints, we use the FAST_THEN_NORMAL setting setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_FAST_THEN_NORMAL); } @Override public void doAfterTest() throws Exception { super.doAfterTest(); if (fSession != null) fSession.getExecutor().submit(() -> fSession.removeServiceEventListener(GDBRemoteTracepointsTest.this)) .get(); fBreakpointService = null; if (fServicesTracker != null) fServicesTracker.dispose(); } // ********************************************************************* // Below are utility methods. // ********************************************************************* private static Boolean lock = true; enum Events {BP_ADDED, BP_UPDATED, BP_REMOVED, BP_HIT} final int BP_ADDED = Events.BP_ADDED.ordinal(); final int BP_UPDATED = Events.BP_UPDATED.ordinal(); final int BP_REMOVED = Events.BP_REMOVED.ordinal(); final int BP_HIT = Events.BP_HIT.ordinal(); private int[] fBreakpointEvents = new int[Events.values().length]; private boolean fBreakpointEvent; private int fBreakpointEventCount; @DsfServiceEventHandler public void eventDispatched(IBreakpointsAddedEvent e) { synchronized (lock) { fBreakpointEvents[BP_ADDED]++; fBreakpointEventCount++; fBreakpointEvent = true; lock.notifyAll(); } } @DsfServiceEventHandler public void eventDispatched(IBreakpointsUpdatedEvent e) { synchronized (lock) { fBreakpointEvents[BP_UPDATED]++; fBreakpointEventCount++; fBreakpointEvent = true; lock.notifyAll(); } } @DsfServiceEventHandler public void eventDispatched(IBreakpointsRemovedEvent e) { synchronized (lock) { fBreakpointEvents[BP_REMOVED]++; fBreakpointEventCount++; fBreakpointEvent = true; lock.notifyAll(); } } // Clears the counters protected void clearEventCounters() { synchronized (lock) { for (int i = 0; i < fBreakpointEvents.length; i++) { fBreakpointEvents[i] = 0; } fBreakpointEvent = false; fBreakpointEventCount = 0; } } // Get the breakpoint hit count protected int getBreakpointEventCount(int event) { int count = 0; synchronized (lock) { count = fBreakpointEvents[event]; } return count; } // Suspends the thread until an event is flagged // NOTE: too simple for real life but good enough for this test suite protected void waitForBreakpointEvent() { synchronized (lock) { while (!fBreakpointEvent) { try { lock.wait(); } catch (InterruptedException ex) { } } fBreakpointEvent = false; } } // ********************************************************************* // Breakpoint service methods (to use with tracepoints). // ********************************************************************* protected IBreakpointDMContext insertBreakpoint(final IBreakpointsTargetDMContext context, final Map<String,Object> attributes) throws Throwable { Query<IBreakpointDMContext> query = new Query<IBreakpointDMContext>() { @Override protected void execute(final DataRequestMonitor<IBreakpointDMContext> rm) { fBreakpointService.insertBreakpoint(context, attributes, rm); } }; fBreakpointService.getExecutor().execute(query); try { return query.get(1, TimeUnit.SECONDS); } catch (ExecutionException e) { assert false : e.getCause().getMessage(); } return null; } protected void removeBreakpoint(final IBreakpointDMContext breakpoint) throws Throwable { Query<Object> query = new Query<Object>() { @Override protected void execute(final DataRequestMonitor<Object> rm) { fBreakpointService.removeBreakpoint(breakpoint, rm); } }; fBreakpointService.getExecutor().execute(query); try { query.get(1, TimeUnit.SECONDS); } catch (ExecutionException e) { assert false : e.getCause().getMessage(); } } protected void updateBreakpoint(final IBreakpointDMContext breakpoint, final Map<String, Object> delta) throws Throwable { Query<Object> query = new Query<Object>() { @Override protected void execute(DataRequestMonitor<Object> rm) { fBreakpointService.updateBreakpoint(breakpoint, delta, rm); } }; fBreakpointService.getExecutor().execute(query); try { query.get(1, TimeUnit.SECONDS); } catch (ExecutionException e) { assert false : e.getCause().getMessage(); } } protected IBreakpointDMData getBreakpoint(final IBreakpointDMContext breakpoint) throws Throwable { Query<IBreakpointDMData> query = new Query<IBreakpointDMData>() { @Override protected void execute(DataRequestMonitor<IBreakpointDMData> rm) { fBreakpointService.getBreakpointDMData(breakpoint, rm); } }; fBreakpointService.getExecutor().execute(query); try { return query.get(1, TimeUnit.SECONDS); } catch (ExecutionException e) { assert false : e.getCause().getMessage(); } return null; } protected IBreakpointDMContext[] getBreakpoints(final IBreakpointsTargetDMContext context) throws Throwable { Query<IBreakpointDMContext[]> query = new Query<IBreakpointDMContext[]>() { @Override protected void execute(DataRequestMonitor<IBreakpointDMContext[]> rm) { fBreakpointService.getBreakpoints(context, rm); } }; fBreakpointService.getExecutor().execute(query); try { return query.get(1, TimeUnit.SECONDS); } catch (ExecutionException e) { assert false : e.getCause().getMessage(); } return null; } // ********************************************************************* // TraceControl service methods. // ********************************************************************* // private void startTracing() throws InterruptedException // { // startTracing(null); // } // // private void startTracing(String errorMessage) throws InterruptedException // { // final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); // // fTraceService.getExecutor().submit(new Runnable() { // public void run() { // fTraceService.canStartTracing(fTraceTargetDmc, // new DataRequestMonitor<Boolean>(fTraceService.getExecutor(), null) { // @Override // protected void handleCompleted() { // wait.setReturnInfo(getData()); // wait.waitFinished(getStatus()); // } // }); // } // }); // // wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // assertTrue(wait.getMessage(), wait.isOK()); // assertTrue("Not allowed to start tracing!", (Boolean)wait.getReturnInfo()); // // wait.waitReset(); // // fTraceService.getExecutor().submit(new Runnable() { // public void run() { // fTraceService.startTracing(fTraceTargetDmc, // new RequestMonitor(fTraceService.getExecutor(), null) { // @Override // protected void handleCompleted() { // wait.waitFinished(getStatus()); // } // }); // } // }); // // wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // if (errorMessage == null) { // assertTrue(wait.getMessage(), wait.isOK()); // } else { // assertTrue(wait.getMessage(), !wait.isOK()); // assertTrue("Message " + wait.getMessage() + " does not contain \"" + errorMessage +"\"", // wait.getMessage().indexOf(errorMessage) != -1); // } // } // // private void stopTracing() throws InterruptedException // { // final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); // // fTraceService.getExecutor().submit(new Runnable() { // public void run() { // fTraceService.canStopTracing(fTraceTargetDmc, // new DataRequestMonitor<Boolean>(fTraceService.getExecutor(), null) { // @Override // protected void handleCompleted() { // wait.setReturnInfo(getData()); // wait.waitFinished(getStatus()); // } // }); // } // }); // // wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // assertTrue(wait.getMessage(), wait.isOK()); // assertTrue("Not allowed to stop tracing!", (Boolean)wait.getReturnInfo()); // // wait.waitReset(); // // fTraceService.getExecutor().submit(new Runnable() { // public void run() { // fTraceService.stopTracing(fTraceTargetDmc, // new RequestMonitor(fTraceService.getExecutor(), null) { // @Override // protected void handleCompleted() { // wait.waitFinished(getStatus()); // } // }); // } // }); // // wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // assertTrue(wait.getMessage(), wait.isOK()); // } // // private boolean isTracing() throws InterruptedException // { // final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); // // fTraceService.getExecutor().submit(new Runnable() { // public void run() { // fTraceService.isTracing(fTraceTargetDmc, // new DataRequestMonitor<Boolean>(fTraceService.getExecutor(), null) { // @Override // protected void handleCompleted() { // wait.setReturnInfo(getData()); // wait.waitFinished(getStatus()); // } // }); // } // }); // // wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // assertTrue(wait.getMessage(), wait.isOK()); // // return (Boolean)wait.getReturnInfo(); // } // // private ITraceStatusDMData getTraceStatus() throws InterruptedException // { // final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); // // fTraceService.getExecutor().submit(new Runnable() { // public void run() { // fTraceService.getTraceStatus(fTraceTargetDmc, // new DataRequestMonitor<ITraceStatusDMData>(fTraceService.getExecutor(), null) { // @Override // protected void handleCompleted() { // wait.setReturnInfo(getData()); // wait.waitFinished(getStatus()); // } // }); // } // }); // // wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // assertTrue(wait.getMessage(), wait.isOK()); // // return (ITraceStatusDMData)wait.getReturnInfo(); // } // ********************************************************************* // Below are the tests for the control of tracepoints. // ********************************************************************* protected IBreakpointDMContext[] fTracepoints = null; // private void checkTraceStatus(boolean supported, boolean active, int frames, // STOP_REASON_ENUM reason, Integer stoppingTracepoint) throws Throwable { // ITraceStatusDMData status = getTraceStatus(); // assertTrue("Error tracing supported should be " + supported + " but was " + status.isTracingSupported(), // status.isTracingSupported() == supported); // assertTrue("Error tracing active should be " + active + " but was " + status.isTracingActive(), // status.isTracingActive() == active); // boolean isTracing = isTracing(); // assertTrue("Error, tracing active is " + status.isTracingActive() + " but the tracepoint service thinks it is " + isTracing, // status.isTracingActive() == isTracing); // // assertTrue("Wrong number of collected frames. Expected " + frames + " but got " + // status.getNumberOfCollectedFrame(), // status.getNumberOfCollectedFrame() == frames); // assertTrue("Total buffer size should be positive but is " + // status.getTotalBufferSize(), // status.getTotalBufferSize() > 0); // // if (fTotalTracingBufferSize == 0) { // // Initialize buffer // fTotalTracingBufferSize = status.getTotalBufferSize(); // } else { // assertTrue("Total buffer size changed! Should be " + fTotalTracingBufferSize + // " but got " + status.getTotalBufferSize(), // status.getTotalBufferSize() == fTotalTracingBufferSize); // } // // assertTrue("Expected stopping reason " + reason + " but got " + status.getStopReason(), // status.getStopReason() == reason); // assertTrue("Expected stopping bp " + stoppingTracepoint + " but got " + status.getStoppingTracepoint(), // status.getStoppingTracepoint() == stoppingTracepoint); // } // // private void checkTraceStatus(boolean supported, boolean active, int frames) throws Throwable { // checkTraceStatus(supported, active, frames, null, null); // } // GDB 7.0 does not support fast tracepoints, but GDB 7.2 will protected boolean fastTracepointsSupported() { return false; } protected class TracepointData { String sourceFile; int lineNumber; String condition; int passcount; boolean enabled; String commands; boolean isFastTp; public TracepointData(int line, String cond, int pass, boolean isEnabled, String cmds, boolean fast) { this(SOURCE_NAME, line, cond, pass, isEnabled, cmds, fast); } public TracepointData(String file, int line, String cond, int pass, boolean isEnabled, String cmds, boolean fast) { sourceFile = file; lineNumber = line; condition = cond; passcount = pass; enabled = isEnabled; commands = cmds; if (fastTracepointsSupported()) { isFastTp = fast; } else { isFastTp = false; } } } protected void checkTracepoints(TracepointData[] dataArray) throws Throwable { int numTracepoints = dataArray.length; // Fetch the tp list from the backend IBreakpointDMContext[] tracepoints = getBreakpoints(fBreakpointsDmc); assertTrue("expected " + numTracepoints + " breakpoint(s), received " + tracepoints.length, tracepoints.length == numTracepoints); for (int i=0; i<numTracepoints; i++) { TracepointData data = dataArray[i]; // Ensure that the tracepoints were correctly installed MIBreakpointDMData tp = (MIBreakpointDMData) getBreakpoint(fTracepoints[i]); assertTrue("tracepoint "+i+" is not a tracepoint but a " + tp.getBreakpointType(), tp.getBreakpointType().equals(MIBreakpoints.TRACEPOINT)); assertTrue("tracepoint "+i+" should be a " + (data.isFastTp?"fast":"normal")+" tracepoint but is not", tp.getType().equals("fast tracepoint") == data.isFastTp); assertTrue("tracepoint "+i+" mismatch (wrong file name) got " + tp.getFileName(), tp.getFileName().equals(data.sourceFile)); assertTrue("tracepoint "+i+" mismatch (wrong line number) got " + tp.getLineNumber(), tp.getLineNumber() == data.lineNumber); assertTrue("tracepoint "+i+" mismatch (wrong condition) got " + tp.getCondition(), tp.getCondition().equals(data.condition)); assertTrue("tracepoint "+i+" mismatch (wrong pass count) got " + tp.getPassCount(), tp.getPassCount() == data.passcount); assertTrue("tracepoint "+i+" mismatch (wrong enablement) got " + tp.isEnabled(), tp.isEnabled() == data.enabled); assertTrue("tracepoint "+i+" mismatch (wrong actions) got " + tp.getCommands(), tp.getCommands().equals(data.commands)); assertTrue("tracepoint "+i+" mismatch", tp.equals((MIBreakpointDMData)getBreakpoint(tracepoints[i]))); } } protected void checkTracepoints(boolean useCond, boolean useCount, boolean enabled, boolean useActions) throws Throwable { TracepointData[] dataArray = new TracepointData[] { new TracepointData(LINE_NUMBER_1_BYTE_INSTR, useCond ? CONDITIONS[0] : NO_CONDITION, useCount ? PASS_COUNTS[0] : 0, enabled, useActions ? COLLECT_ACTIONS[0].toString() : NO_COMMANDS, false), new TracepointData(LINE_NUMBER_2_BYTE_INSTR, useCond ? CONDITIONS[1] : NO_CONDITION, useCount ? PASS_COUNTS[1] : 0, enabled, useActions ? COLLECT_ACTIONS[1].toString() : NO_COMMANDS, false), new TracepointData(LINE_NUMBER_3_BYTE_INSTR, useCond ? CONDITIONS[2] : NO_CONDITION, useCount ? PASS_COUNTS[2] : 0, enabled, useActions ? COLLECT_ACTIONS[2].toString() : NO_COMMANDS, false), new TracepointData(LINE_NUMBER_4_BYTE_INSTR, useCond ? CONDITIONS[3] : NO_CONDITION, useCount ? PASS_COUNTS[3] : 0, enabled, useActions ? COLLECT_ACTIONS[3].toString() : NO_COMMANDS, acceptsFastTpOnFourBytes()), new TracepointData(LINE_NUMBER_5_BYTE_INSTR, useCond ? CONDITIONS[4] : NO_CONDITION, useCount ? PASS_COUNTS[4] : 0, enabled, useActions ? COLLECT_ACTIONS[4].toString() : NO_COMMANDS, true), }; checkTracepoints(dataArray); } protected void createTracepoints(boolean useCond, boolean useCount, boolean enabled, boolean useActions) throws Throwable { Map<String, Object> attributes = null; int[] lineNumbers = { LINE_NUMBER_1_BYTE_INSTR, LINE_NUMBER_2_BYTE_INSTR, LINE_NUMBER_3_BYTE_INSTR, LINE_NUMBER_4_BYTE_INSTR, LINE_NUMBER_5_BYTE_INSTR }; for (int i = 0; i < lineNumbers.length; i++) { attributes = new HashMap<String, Object>(); attributes.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.TRACEPOINT); attributes.put(MIBreakpoints.FILE_NAME, SOURCE_NAME); attributes.put(MIBreakpoints.LINE_NUMBER, lineNumbers[i]); if (!enabled) attributes.put(MIBreakpoints.IS_ENABLED, enabled); if (useCount) attributes.put(MIBreakpoints.PASS_COUNT, PASS_COUNTS[i]); if (useCond) attributes.put(MIBreakpoints.CONDITION, CONDITIONS[i]); if (useActions) attributes.put(MIBreakpoints.COMMANDS, COLLECT_ACTIONS[i].getName()); fTracepoints[i] = insertBreakpoint(fBreakpointsDmc, attributes); waitForBreakpointEvent(); assertEquals("Incorrect number of breakpoint events", 1, fBreakpointEventCount); assertEquals("Incorrect number of breakpoint added events", 1, getBreakpointEventCount(BP_ADDED)); clearEventCounters(); } checkTracepoints(useCond, useCount, enabled, useActions); } /** * This test makes sure that the tracing status is correct when we start. * It also stores the total buffer size to be used by other tests. * This test is being run before every other test by being called * by the @Before method; this allows to verify every launch of GDB. */ @Test @Ignore public void checkTraceInitialStatus() { // checkTraceStatus(true, false, 0); } /** * This test sets different tracepoints in the program: * - using a method address * - using a method name * - using a filename and line number * * It also set a fast tracepoint by */ @Test public void createTracepoints() throws Throwable { createTracepoints(false, false, true, false); } /** * This test sets the different types of tracepoints and then deletes them */ @Test public void deleteTracepoints() throws Throwable { createTracepoints(); // Delete all tracepoints for (IBreakpointDMContext tp : fTracepoints) { if (tp == null) break; removeBreakpoint(tp); } // Fetch the bp list from the backend IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); assertTrue("BreakpointService problem: expected " + 0 + " breakpoints, received " + breakpoints.length, breakpoints.length == 0); } /** * This test sets the different types of tracepoints and then disables them */ @Test public void disableTracepoints() throws Throwable { createTracepoints(); Map<String, Object> delta = new HashMap<String, Object>(); delta.put(MIBreakpoints.IS_ENABLED, false); // Disable all tracepoints for (IBreakpointDMContext tp : fTracepoints) { if (tp == null) break; updateBreakpoint(tp, delta); } checkTracepoints(false, false, false, false); } /** * This test sets, disables the different types of tracepoints and then enables them */ @Test public void enableTracepoints() throws Throwable { disableTracepoints(); Map<String, Object> delta = new HashMap<String, Object>(); delta.put(MIBreakpoints.IS_ENABLED, true); // Enable all tracepoints for (IBreakpointDMContext tp : fTracepoints) { if (tp == null) break; updateBreakpoint(tp, delta); } checkTracepoints(false, false, true, false); } /** * This test sets the different types of tracepoints and then sets their passcount */ @Test public void tracepointPasscount() throws Throwable { createTracepoints(); Map<String, Object> delta = new HashMap<String, Object>(); // Set passcount for all tracepoints for (int i=0; i<fTracepoints.length; i++) { if (fTracepoints[i] == null) break; if (PASS_COUNTS[i] == 0) continue; delta.put(MIBreakpoints.PASS_COUNT, PASS_COUNTS[i]); updateBreakpoint(fTracepoints[i], delta); } checkTracepoints(false, true, true, false); } /** * This test sets the different types of tracepoints and then sets some conditions */ @Test public void tracepointCondition() throws Throwable { createTracepoints(); Map<String, Object> delta = new HashMap<String, Object>(); // Set conditions for all tracepoints for (int i=0; i<fTracepoints.length; i++) { if (fTracepoints[i] == null) break; if (CONDITIONS[i].equals(NO_CONDITION)) continue; delta.put(MIBreakpoints.CONDITION, CONDITIONS[i]); updateBreakpoint(fTracepoints[i], delta); } checkTracepoints(true, false, true, false); } /** * This test sets the different types of tracepoints and then sets some actions */ @Test public void tracepointActions() throws Throwable { createTracepoints(); Map<String, Object> delta = new HashMap<String, Object>(); // Set conditions for all tracepoints for (int i=0; i<fTracepoints.length; i++) { if (fTracepoints[i] == null) break; if (COLLECT_ACTIONS[i].equals(NO_COMMANDS)) continue; delta.put(MIBreakpoints.COMMANDS, COLLECT_ACTIONS[i].getName()); updateBreakpoint(fTracepoints[i], delta); } checkTracepoints(false, false, true, true); } /** * This test creates a tracepoint that starts disabled */ @Test public void createTracepointDisabled() throws Throwable { createTracepoints(false, false, false, false); } /** * This test creates a tracepoint that starts with a passcount */ @Test public void createTracepointWithPasscount() throws Throwable { createTracepoints(false, true, true, false); } /** * This test creates a tracepoint that starts with a condition */ @Test public void createTracepointWithCondition() throws Throwable { createTracepoints(true, false, true, false); } /** * This test creates tracepoints that start a command */ @Test public void createTracepointWithCommand() throws Throwable { createTracepoints(false, false, true, true); } /** * This test creates tracepoints that start with more than one command */ @Test public void createTracepointWithMultipleCommands() throws Throwable { String commandsNames1 = COLLECT_ACTIONS[0].getName() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[1].getName() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[3].getName(); String commandsResult1 = COLLECT_ACTIONS[0].toString() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[1].toString() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[3].toString(); String commandsNames2 = COLLECT_ACTIONS[2].getName() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[2].getName() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[1].getName(); String commandsResult2 = COLLECT_ACTIONS[2].toString() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[2].toString() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[1].toString(); String commandsNames3 = COLLECT_ACTIONS[4].getName() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[0].getName() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[1].getName(); String commandsResult3 = COLLECT_ACTIONS[4].toString() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[0].toString() + TracepointActionManager.TRACEPOINT_ACTION_DELIMITER + COLLECT_ACTIONS[1].toString(); String cmdNames[] = new String[] { commandsNames1, COLLECT_ACTIONS[0].getName(), commandsNames2, COLLECT_ACTIONS[2].getName(), commandsNames3 }; String cmdResults[] = new String[] { commandsResult1, COLLECT_ACTIONS[0].toString(), commandsResult2, COLLECT_ACTIONS[2].toString(), commandsResult3}; Map<String, Object> attributes = null; int[] lineNumbers = { LINE_NUMBER_1_BYTE_INSTR, LINE_NUMBER_2_BYTE_INSTR, LINE_NUMBER_3_BYTE_INSTR, LINE_NUMBER_4_BYTE_INSTR, LINE_NUMBER_5_BYTE_INSTR }; for (int i = 0; i < lineNumbers.length; i++) { attributes = new HashMap<String, Object>(); attributes.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.TRACEPOINT); attributes.put(MIBreakpoints.FILE_NAME, SOURCE_NAME); attributes.put(MIBreakpoints.LINE_NUMBER, lineNumbers[i]); attributes.put(MIBreakpoints.COMMANDS, cmdNames[i]); fTracepoints[i] = insertBreakpoint(fBreakpointsDmc, attributes); waitForBreakpointEvent(); assertEquals("Incorrect number of breakpoint events", 1, fBreakpointEventCount); assertEquals("Incorrect number of breakpoint added events", 1, getBreakpointEventCount(BP_ADDED)); clearEventCounters(); } TracepointData[] dataArray = new TracepointData[] { new TracepointData(LINE_NUMBER_1_BYTE_INSTR, NO_CONDITION, 0, true, cmdResults[0], false), new TracepointData(LINE_NUMBER_2_BYTE_INSTR, NO_CONDITION, 0, true, cmdResults[1], false), new TracepointData(LINE_NUMBER_3_BYTE_INSTR, NO_CONDITION, 0, true, cmdResults[2], false), new TracepointData(LINE_NUMBER_4_BYTE_INSTR, NO_CONDITION, 0, true, cmdResults[3], acceptsFastTpOnFourBytes()), new TracepointData(LINE_NUMBER_5_BYTE_INSTR, NO_CONDITION, 0, true, cmdResults[4], true), }; checkTracepoints(dataArray); } /** * This test creates an enabled tracepoint that starts with commands, condition and passcount */ @Test public void createTracepointEnabledWithCommandsConditionPasscount() throws Throwable { createTracepoints(true, true, true, true); } /** * This test creates a disabled tracepoint that starts with commands, condition and passcount */ @Test public void createTracepointDisabledWithCommandsConditionPasscount() throws Throwable { createTracepoints(true, true, false, true); } // /** // * This test sets the different types of tracepoints and then sets some eval actions // */ // @Test // public void testEvalActions() throws Throwable { // final String ACTIONS1 = EVAL_ACTION_1.getName()+","+EVAL_ACTION_2.getName()+","+EVAL_ACTION_3.getName(); // final String ACTIONS2 = EVAL_ACTION_1.getName()+","+EVAL_ACTION_3.getName(); // final String ACTIONS3 = EVAL_ACTION_3.getName(); // // testCreateTracepoints(); // testActions(new String[] {ACTIONS1, ACTIONS2, ACTIONS3, ""}); // } // // /** // * This test sets the different types of tracepoints and then sets some while-stepping actions // */ // //@Test // public void testSteppingActions() throws Throwable { //// final String ACTIONS1 = STEPPING_ACTION_1.getName()+","+STEPPING_ACTION_2.getName()+","+STEPPING_ACTION_3.getName(); //// final String ACTIONS2 = STEPPING_ACTION_1.getName()+","+STEPPING_ACTION_3.getName(); //// final String ACTIONS3 = STEPPING_ACTION_3.getName(); //// //// testCreateTracepoints(); //// testActions(new String[] {ACTIONS1, ACTIONS2, ACTIONS3, ""}); // } // // /** // * This test sets the different types of tracepoints and then sets a mix of different // * tracepoint actions // */ // //@Test // public void testMixedActions() throws Throwable { //// final String ACTIONS1 = COLLECT_ACTION_1.getName() + "," + //// EVAL_ACTION_2.getName() + "," + //// STEPPING_ACTION_3.getName(); //// final String ACTIONS2 = STEPPING_ACTION_1.getName() + "," + //// COLLECT_ACTION_2.getName() + "," + //// EVAL_ACTION_1.getName() + "," + //// COLLECT_ACTION_3.getName() + "," + //// EVAL_ACTION_2.getName() + "," + //// EVAL_ACTION_3.getName(); //// final String ACTIONS3 = EVAL_ACTION_3.getName() + "," + //// COLLECT_ACTION_1.getName() + "," + //// EVAL_ACTION_2.getName() + "," + //// STEPPING_ACTION_3.getName(); //// //// testCreateTracepoints(); //// testActions(new String[] {ACTIONS1, ACTIONS2, ACTIONS3, ""}); // } // // /** // * This test sets the different types of tracepoints and then sets some default collect actions // */ // //@Test // public void testDefaultCollectAction() throws Throwable { // testCreateTracepoints(); // } // // // ********************************************************************* // // Below are the tests for the control of tracing // // ********************************************************************* // // /** // * This test sets different tracepoints in the program: // * - using a filename and line number // * - using a method name // * - using a method address // * // * and confirms they are installed when tracing starts // */ // @Test // public void testCreateAndRunTracepoints() throws Throwable { // testCreateTracepoints(); // startTracing(); // SyncUtil.SyncRunToLocation(Integer.toString(LAST_LINE_NUMBER)); // checkTraceStatus(true, true, TOTAL_FRAMES_TO_BE_COLLECTED); // stopTracing(); // checkTraceStatus(true, false, TOTAL_FRAMES_TO_BE_COLLECTED); // } // // /** // * This test sets the different types of tracepoints and then deletes them // * and confirms they are not installed when tracing starts // */ // @Test // public void testDeleteAndRunTracepoints() throws Throwable { // testDeleteTracepoints(); // startTracing("No tracepoints available to download"); // SyncUtil.SyncRunToLocation(Integer.toString(LAST_LINE_NUMBER)); // checkTraceStatus(true, false, 0); // } // // /** // * This test sets the different types of tracepoints and then disables them // * and confirms they are not hit when tracing starts // */ // @Test // public void testDisableAndRunTracepoints() throws Throwable { // testDisableTracepoints(); // startTracing("None of the downloadable tracepoints enabled"); // SyncUtil.SyncRunToLocation(Integer.toString(LAST_LINE_NUMBER)); // checkTraceStatus(true, false, 0); // } // // /** // * This test sets, disables the different types of tracepoints and then enables them // * and confirms they are hit when tracing starts // */ // @Test // public void testEnableAndRunTracepoints() throws Throwable { // testEnableTracepoints(); // startTracing(); // SyncUtil.SyncRunToLocation(Integer.toString(LAST_LINE_NUMBER)); // checkTraceStatus(true, true, TOTAL_FRAMES_TO_BE_COLLECTED); // stopTracing(); // checkTraceStatus(true, false, TOTAL_FRAMES_TO_BE_COLLECTED); // } // // /** // * This test sets the different types of tracepoints and then sets their passcount // * and confirms the passcount is respected // */ // @Test // public void testTracepointPasscountAndRun1() throws Throwable { // testTracepointPasscount(); // startTracing(); // SyncUtil.SyncRunToLocation(Integer.toString(LAST_LINE_NUMBER)); // // checkTraceStatus(true, false, // 1 + 1 + 10 + 1 + PASS_COUNTS[4], // STOP_REASON_ENUM.PASSCOUNT, 6); // } // // /** // * This test sets the passcount of the a tracepoint that is hit before some // * other tracepoints are hit, to confirm tracing really stops. // */ // @Test // public void testTracepointPasscountAndRun2() throws Throwable { // testTracepointPasscount(); // // // Set the passcount of the forth tp to make it stop the tracing // Map<String, Object> delta = new HashMap<String, Object>(); // delta.put(MIBreakpoints.IGNORE_COUNT, 1); // updateBreakpoint(fTracepoints[3], delta); // // startTracing(); // SyncUtil.SyncRunToLocation(Integer.toString(LAST_LINE_NUMBER)); // // checkTraceStatus(true, false, // 1 + 1 + 10 + 1, // STOP_REASON_ENUM.PASSCOUNT, 5); // } // // /** // * This test sets a tracepoint and then gives it a condition // * and confirms the condition is respected // */ // //@Test // public void testTracepointConditionAndRun() throws Throwable { // // Use trace state variables and stuff // } // // /** // * This test sets the different types of tracepoints and then sets some collect actions // * and confirms the proper information is collected // */ // //@Test // public void testCollectActionsAndRun() throws Throwable { // testCreateTracepoints(); // } // // /** // * This test sets the different types of tracepoints and then sets some eval actions // * and confirms the trace variables are properly updated // */ // //@Test // public void testEvalActionsAndRun() throws Throwable { // testCreateTracepoints(); // } // // /** // * This test sets the different types of tracepoints and then sets some while-stepping actions // * and confirms the proper information is collected // */ // //@Test // public void testSteppingActionsAndRun() throws Throwable { // testCreateTracepoints(); // } // // /** // * This test sets the different types of tracepoints and then sets a mix of different // * tracepoint actions and confirms the proper information is collected // */ // //@Test // public void testMixedActionsAndRun() throws Throwable { // testCreateTracepoints(); // } // // /** // * This test sets the different types of tracepoints and then sets some default collect actions // * and confirms the proper information is collected // */ // //@Test // public void testDefaultCollectActionAndRun() throws Throwable { // testCreateTracepoints(); // } // protected boolean acceptsFastTpOnFourBytes() { String gdbVersion = getGdbVersion(); boolean isLower = LaunchUtils.compareVersions(ITestConstants.SUFFIX_GDB_7_4, gdbVersion) > 0; if (isLower) return false; // With GDB 7.4, fast tracepoints only need an // instruction of 4 bytes or more when on a 32bit architecture, instead of 5. if (Platform.getOS().equals(Platform.ARCH_X86)) { return true; } return false; } /** * This test sets the different types of tracepoints and then sets some string collection actions */ @Test public void tracepointActionsWithCollectStrings() throws Throwable { assumeGdbVersionAtLeast(ITestConstants.SUFFIX_GDB_7_4); TracepointActionManager tracepointActionMgr = TracepointActionManager.getInstance(); CollectAction action1 = new CollectAction(); action1.setCollectString("/s $locals"); action1.setName("Collect string locals"); tracepointActionMgr.addAction(action1); CollectAction action2 = new CollectAction(); action2.setCollectString("/s3 $locals, $reg"); action2.setName("Collect string locals, reg"); tracepointActionMgr.addAction(action2); createTracepoints(); Map<String, Object> delta = new HashMap<String, Object>(); // Set conditions for all tracepoints delta.put(MIBreakpoints.COMMANDS, action1.getName()); updateBreakpoint(fTracepoints[0], delta); delta.put(MIBreakpoints.COMMANDS, action2.getName()); updateBreakpoint(fTracepoints[1], delta); delta.put(MIBreakpoints.COMMANDS, action1.getName()); updateBreakpoint(fTracepoints[2], delta); delta.put(MIBreakpoints.COMMANDS, action1.getName()); updateBreakpoint(fTracepoints[3], delta); delta.put(MIBreakpoints.COMMANDS, action2.getName()); updateBreakpoint(fTracepoints[4], delta); TracepointData[] dataArray = new TracepointData[] { new TracepointData(LINE_NUMBER_1_BYTE_INSTR, NO_CONDITION, 0, true, action1.toString(), false), new TracepointData(LINE_NUMBER_2_BYTE_INSTR, NO_CONDITION, 0, true, action2.toString(), false), new TracepointData(LINE_NUMBER_3_BYTE_INSTR, NO_CONDITION, 0, true, action1.toString(), false), new TracepointData(LINE_NUMBER_4_BYTE_INSTR, NO_CONDITION, 0, true, action1.toString(), acceptsFastTpOnFourBytes()), new TracepointData(LINE_NUMBER_5_BYTE_INSTR, NO_CONDITION, 0, true, action2.toString(), true), }; checkTracepoints(dataArray); } }