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

Bug 392512: Support GDB breakpoint notifications. JUnit tests.

Change-Id: I0c0ab0f2e419a931073f229192e0b70fcc25a7b6
Reviewed-on: https://git.eclipse.org/r/9006
Reviewed-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
IP-Clean: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
This commit is contained in:
Mikhail Khodjaiants 2012-12-17 16:03:15 -05:00
parent c5d08937e2
commit 88e488b1ff
9 changed files with 1087 additions and 4 deletions

View file

@ -0,0 +1,584 @@
/*******************************************************************************
* Copyright (c) 2012 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
import org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint;
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.IBreakpointsAddedEvent;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsChangedEvent;
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.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
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.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* This test case verifies whether breakpoints or watchpoints set from GDB console
* are properly synchronized with platform breakpoints.
*/
@SuppressWarnings( "restriction" )
@RunWith(BackgroundRunner.class)
public class GDBConsoleBreakpointsTest extends BaseTestCase {
final static private int DEFAULT_TIMEOUT = 20000;
final static private TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS;
final static private String FILE_NAME_VALID = new Path("data/launch/src/GDBMIGenericTestApp.cc").toFile().getAbsolutePath();
final static private int LINE_NUMBER_VALID = 8;
final static private String FILE_NAME_INVALID = new Path("x.c").toFile().getAbsolutePath();
final static private int LINE_NUMBER_INVALID = 2;
final static private String FUNCTION_VALID = "main()";
final static private String FUNCTION_INVALID = "xxx";
final static private String EXPRESSION_VALID = "path";
final static private String ATTR_FILE_NAME = "FILE_NAME";
final static private String ATTR_LINE_NUMBER = "LINE_NUMBER";
final static private String ATTR_FUNCTION = "FUNCTION";
final static private String ATTR_ADDRESS = "ADDRESS";
final static private String ATTR_EXPRESSION = "EXPRESSION";
final static private String ATTR_READ = "READ";
final static private String ATTR_WRITE = "WRITE";
private DsfSession fSession;
private DsfServicesTracker fServicesTracker;
protected IBreakpointsTargetDMContext fBreakpointsDmc;
private IGDBControl fCommandControl;
private List<IBreakpointsChangedEvent> fBreakpointEvents = new ArrayList<IBreakpointsChangedEvent>();
@Override
@Before
public void doBeforeTest() throws Exception {
deleteAllPlatformBreakpoints();
super.doBeforeTest();
Runnable runnable = new Runnable() {
@Override
public void run() {
fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId());
Assert.assertTrue(fServicesTracker != null);
fCommandControl = fServicesTracker.getService(IGDBControl.class);
Assert.assertTrue(fCommandControl != null);
// Register to breakpoint events
fSession.addServiceEventListener(GDBConsoleBreakpointsTest.this, null);
}
};
fSession = getGDBLaunch().getSession();
fSession.getExecutor().submit(runnable).get();
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
fBreakpointsDmc = DMContexts.getAncestorOfType(containerDmc, IBreakpointsTargetDMContext.class);
Assert.assertTrue(fBreakpointsDmc != null);
}
@Override
@After
public void doAfterTest() throws Exception {
Runnable runnable = new Runnable() {
@Override
public void run() {
fSession.removeServiceEventListener(GDBConsoleBreakpointsTest.this);
}
};
fSession.getExecutor().submit(runnable).get();
fBreakpointEvents.clear();
fServicesTracker.dispose();
fServicesTracker = null;
super.doAfterTest();
deleteAllPlatformBreakpoints();
}
@Test
public void testValidLineBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICLineBreakpoint.class,
getLocationBreakpointAttributes(ICLineBreakpoint.class, true));
}
@Test
public void testInvalidLineBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICLineBreakpoint.class,
getLocationBreakpointAttributes(ICLineBreakpoint.class, false));
}
@Test
public void testValidFunctionBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICFunctionBreakpoint.class,
getLocationBreakpointAttributes(ICFunctionBreakpoint.class, true));
}
@Test
public void testInvalidFunctionBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICFunctionBreakpoint.class,
getLocationBreakpointAttributes(ICFunctionBreakpoint.class, false));
}
@Test
public void testValidAddressBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICAddressBreakpoint.class,
getLocationBreakpointAttributes(ICAddressBreakpoint.class, true));
}
@Test
public void testAddressBreakpointsAtZeroAddress() throws Throwable {
testConsoleBreakpoint(
ICAddressBreakpoint.class,
getLocationBreakpointAttributes(ICAddressBreakpoint.class, false));
}
@Test
public void testWriteWatchpoints() throws Throwable {
testConsoleBreakpoint(
ICWatchpoint.class,
getWatchpointAttributes(ICWatchpoint.class, false, true));
}
@Test
public void testReadWatchpoints() throws Throwable {
testConsoleBreakpoint(
ICWatchpoint.class,
getWatchpointAttributes(ICWatchpoint.class, true, false));
}
@Test
public void testAccessWatchpoints() throws Throwable {
testConsoleBreakpoint(
ICWatchpoint.class,
getWatchpointAttributes(ICWatchpoint.class, true, true));
}
@DsfServiceEventHandler
public void eventDispatched(IBreakpointsChangedEvent e) {
synchronized(this) {
fBreakpointEvents.add(e);
notifyAll();
}
}
private void testConsoleBreakpoint(Class<? extends ICBreakpoint> type, Map<String, Object> attributes) throws Throwable {
// Set a console breakpoint and verify that
// the corresponding platform breakpoint is created
// and its install count is 1 if the breakpoint is installed
// and 0 if the breakpoint is pending.
// Check for a duplicate target breakpoint.
setConsoleBreakpoint(type, attributes);
MIBreakpoint[] miBpts = getTargetBreakpoints();
Assert.assertTrue(miBpts.length == 1);
waitForBreakpointEvent(IBreakpointsAddedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 1);
ICBreakpoint plBpt = findPlatformBreakpoint(type, attributes);
Assert.assertTrue(plBpt instanceof CBreakpoint);
// We can't rely on IBreakpointsAddedEvent because it is fired
// before the install count is incremented.
if (!miBpts[0].isPending()) {
// If the target breakpoint is not pending wait
// until the install count becomes 1.
waitForInstallCountChange((CBreakpoint)plBpt, 1);
}
else {
// For pending breakpoints the install count is expected to remain
// unchanged. Give it some time and verify that it is 0.
Thread.sleep(1000);
Assert.assertTrue(((CBreakpoint)plBpt).getInstallCount() == 0);
}
// Disable the console breakpoint and verify that
// the platform breakpoint is disabled.
enableConsoleBreakpoint(miBpts[0].getNumber(), false);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(!plBpt.isEnabled());
// Enable the console breakpoint and verify that
// the platform breakpoint is enabled.
enableConsoleBreakpoint(miBpts[0].getNumber(), true);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.isEnabled());
// Set the ignore count of the console breakpoint and
// verify that the platform breakpoint's ignore count
// is updated.
setConsoleBreakpointIgnoreCount(miBpts[0].getNumber(), 5);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getIgnoreCount() == 5);
// Reset the ignore count of the console breakpoint and
// verify that the platform breakpoint's ignore count
// is updated.
setConsoleBreakpointIgnoreCount(miBpts[0].getNumber(), 0);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getIgnoreCount() == 0);
// Set the condition of the console breakpoint and
// verify that the platform breakpoint's condition
// is updated.
setConsoleBreakpointCondition(miBpts[0].getNumber(), "path==0");
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getCondition().equals("path==0"));
// Reset the condition of the console breakpoint and
// verify that the platform breakpoint's condition
// is updated.
setConsoleBreakpointCondition(miBpts[0].getNumber(), "");
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getCondition().isEmpty());
// Delete the console breakpoint and verify that
// the install count of the platform breakpoint is 0.
deleteConsoleBreakpoint(miBpts[0].getNumber());
waitForBreakpointEvent(IBreakpointsRemovedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 1);
plBpt = findPlatformBreakpoint(type, attributes);
Assert.assertTrue(plBpt instanceof CBreakpoint);
waitForInstallCountChange((CBreakpoint)plBpt, 0);
// Set the console breakpoint again and verify that
// the install count of the platform breakpoint is 1
// for installed breakpoints and 0 for pending breakpoints.
setConsoleBreakpoint(type, attributes);
miBpts = getTargetBreakpoints();
Assert.assertTrue(miBpts.length == 1);
waitForBreakpointEvent(IBreakpointsAddedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 1);
plBpt = findPlatformBreakpoint(type, attributes);
Assert.assertTrue(plBpt instanceof CBreakpoint);
if (!miBpts[0].isPending()) {
waitForInstallCountChange((CBreakpoint)plBpt, 1);
}
else {
// For pending breakpoints the install count is expected to remain
// unchanged. Give it some time and verify that it is 0.
Thread.sleep(1000);
Assert.assertTrue(((CBreakpoint)plBpt).getInstallCount() == 0);
}
// Remove the platform breakpoint and verify that
// the target breakpoint is deleted.
deletePlatformBreakpoint(plBpt);
waitForBreakpointEvent(IBreakpointsRemovedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 0);
miBpts = getTargetBreakpoints();
Assert.assertTrue(miBpts.length == 0);
}
private void setConsoleLineBreakpoint(String fileName, int lineNumber) throws Throwable {
queueConsoleCommand(String.format("break %s:%d", fileName, lineNumber));
}
private void setConsoleFunctionBreakpoint(String fileName, String function) throws Throwable {
queueConsoleCommand(String.format("break %s:%s", fileName, function));
}
private void setConsoleAddressBreakpoint(String address) throws Throwable {
queueConsoleCommand(String.format("break *%s", address));
}
private void setConsoleWatchpoint(String expression, boolean read, boolean write) throws Throwable {
String command = (write) ? ((read) ? "awatch" : "watch") : "rwatch";
queueConsoleCommand(String.format("%s %s", command, expression));
}
private void deleteConsoleBreakpoint(int bpId) throws Throwable {
queueConsoleCommand(String.format("delete %d", bpId));
}
private void enableConsoleBreakpoint(int bpId, boolean enable) throws Throwable {
String cmd = (enable) ? "enable" : "disable";
queueConsoleCommand(String.format("%s %d", cmd, bpId));
}
private void setConsoleBreakpointIgnoreCount(int bpId, int ignoreCount) throws Throwable {
Assert.assertTrue(ignoreCount >= 0);
queueConsoleCommand(String.format("ignore %d %d", bpId, ignoreCount));
}
private void setConsoleBreakpointCondition(int bpId, String condition) throws Throwable {
queueConsoleCommand(String.format("condition %d %s", bpId, condition));
}
private MIBreakpoint[] getTargetBreakpoints() throws Throwable {
return getTargetBreakpoints(DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
}
private MIBreakpoint[] getTargetBreakpoints(int timeout, TimeUnit unit) throws Throwable {
Query<MIBreakListInfo> query = new Query<MIBreakListInfo>() {
@Override
protected void execute(DataRequestMonitor<MIBreakListInfo> rm) {
fCommandControl.queueCommand(
fCommandControl.getCommandFactory().createMIBreakList(fBreakpointsDmc),
rm);
}
};
fSession.getExecutor().execute(query);
return query.get(timeout, unit).getMIBreakpoints();
}
private void waitForBreakpointEvent(Class<? extends IBreakpointsChangedEvent> eventType) throws Exception {
waitForBreakpointEvent(eventType, DEFAULT_TIMEOUT);
}
private void waitForBreakpointEvent(Class<? extends IBreakpointsChangedEvent> eventType, int timeout) throws Exception {
if (!breakpointEventReceived(eventType)) {
synchronized(this) {
try {
wait(timeout);
}
catch (InterruptedException ex) {
}
}
if (!breakpointEventReceived(eventType)) {
throw new Exception(String.format("Timed out waiting for '%s' to occur.", eventType.getName()));
}
}
}
private void queueConsoleCommand(String command) throws Throwable {
queueConsoleCommand(command, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
}
private void queueConsoleCommand(final String command, int timeout, TimeUnit unit) throws Throwable {
Query<MIInfo> query = new Query<MIInfo>() {
@Override
protected void execute(DataRequestMonitor<MIInfo> rm) {
fCommandControl.queueCommand(
fCommandControl.getCommandFactory().createMIInterpreterExecConsole(
fCommandControl.getContext(),
command),
rm);
}
};
fSession.getExecutor().execute(query);
query.get(timeout, unit);
}
private ICLineBreakpoint findPlatformLineBreakpoint(String fileName, int lineNumber) throws Throwable {
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICLineBreakpoint
&& fileName.equals(((ICLineBreakpoint)b).getSourceHandle())
&& lineNumber == ((ICLineBreakpoint)b).getLineNumber()) {
return (ICLineBreakpoint)b;
}
}
return null;
}
private ICFunctionBreakpoint findPlatformFunctionBreakpoint(String fileName, String function) throws Throwable {
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICFunctionBreakpoint
&& fileName.equals(((ICLineBreakpoint)b).getSourceHandle())
&& function.equals(((ICLineBreakpoint)b).getFunction())) {
return (ICFunctionBreakpoint)b;
}
}
return null;
}
private ICAddressBreakpoint findPlatformAddressBreakpoint(String address) throws Throwable {
Addr64 a = new Addr64(address);
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICAddressBreakpoint
&& a.toHexAddressString().equals(((ICAddressBreakpoint)b).getAddress())) {
return (ICAddressBreakpoint)b;
}
}
return null;
}
private ICWatchpoint findPlatformWatchpoint(String expression, boolean read, boolean write) throws Throwable {
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICWatchpoint
&& ((ICWatchpoint)b).isReadType() == read
&& ((ICWatchpoint)b).isWriteType() == write) {
return (ICWatchpoint)b;
}
}
return null;
}
private void deletePlatformBreakpoint(final IBreakpoint plBpt) throws Throwable {
new Job("") {
@Override
protected IStatus run(IProgressMonitor monitor) {
IStatus result = Status.OK_STATUS;
try {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(plBpt, true);
}
catch(CoreException e) {
result = e.getStatus();
}
return result;
}
}.schedule();
}
private int getPlatformBreakpointCount() {
return DebugPlugin.getDefault().getBreakpointManager().getBreakpoints().length;
}
private void waitForInstallCountChange(CBreakpoint plBpt, int expected) throws Throwable {
waitForInstallCountChange(plBpt, expected, DEFAULT_TIMEOUT);
}
private void waitForInstallCountChange(CBreakpoint plBpt, int expected, long timeout) throws Throwable {
long startMs = System.currentTimeMillis();
while(plBpt.getInstallCount() != expected) {
synchronized(this) {
try {
wait(30);
}
catch (InterruptedException ex) {
}
if (System.currentTimeMillis() - startMs > timeout) {
throw new Exception("Timed out waiting for breakpoint's install count to change");
}
}
}
}
private synchronized boolean breakpointEventReceived(Class<? extends IBreakpointsChangedEvent> eventType) {
for (IBreakpointsChangedEvent e : fBreakpointEvents) {
if (eventType.isAssignableFrom(e.getClass())) {
return fBreakpointEvents.remove(e);
}
}
return false;
}
private Map<String, Object> getLocationBreakpointAttributes(Class<? extends ICBreakpoint> type, boolean valid) {
Map<String, Object> map = new HashMap<String, Object>();
if (ICFunctionBreakpoint.class.equals(type)) {
map.put(ATTR_FILE_NAME, (valid) ? FILE_NAME_VALID : FILE_NAME_INVALID);
map.put(ATTR_FUNCTION, (valid) ? FUNCTION_VALID : FUNCTION_INVALID);
}
else if (ICAddressBreakpoint.class.equals(type)) {
// '0x0" is not invalid address
map.put(ATTR_ADDRESS, (valid) ?
getInitialStoppedEvent().getFrame().getAddress() :
new Addr64("0x0").toHexAddressString());
}
else if (ICLineBreakpoint.class.equals(type)) {
map.put(ATTR_FILE_NAME, (valid) ? FILE_NAME_VALID : FILE_NAME_INVALID);
map.put(ATTR_LINE_NUMBER, (valid) ? LINE_NUMBER_VALID : LINE_NUMBER_INVALID);
}
return map;
}
public Map<String, Object> getWatchpointAttributes(Class<? extends ICWatchpoint> type, boolean read, boolean write) throws Throwable {
Assert.assertTrue(read || write);
Map<String, Object> map = new HashMap<String, Object>();
map.put(ATTR_EXPRESSION, EXPRESSION_VALID);
map.put(ATTR_READ, Boolean.valueOf(read));
map.put(ATTR_WRITE, Boolean.valueOf(write));
return map;
}
private void setConsoleBreakpoint(Class<? extends ICBreakpoint> type, Map<String, Object> attributes) throws Throwable {
if (ICFunctionBreakpoint.class.equals(type)) {
setConsoleFunctionBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
(String)attributes.get(ATTR_FUNCTION));
}
else if (ICAddressBreakpoint.class.equals(type)) {
setConsoleAddressBreakpoint((String)attributes.get(ATTR_ADDRESS));
}
else if (ICLineBreakpoint.class.equals(type)) {
setConsoleLineBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
((Integer)attributes.get(ATTR_LINE_NUMBER)).intValue());
}
else if (ICWatchpoint.class.equals(type)) {
setConsoleWatchpoint(
(String)attributes.get(ATTR_EXPRESSION),
((Boolean)attributes.get(ATTR_READ)).booleanValue(),
((Boolean)attributes.get(ATTR_WRITE)).booleanValue());
}
}
private ICBreakpoint findPlatformBreakpoint(Class<? extends ICBreakpoint> type, Map<String, Object> attributes) throws Throwable {
if (ICFunctionBreakpoint.class.equals(type)) {
return findPlatformFunctionBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
(String)attributes.get(ATTR_FUNCTION));
}
else if (ICAddressBreakpoint.class.equals(type)) {
return findPlatformAddressBreakpoint((String)attributes.get(ATTR_ADDRESS));
}
else if (ICLineBreakpoint.class.equals(type)) {
return findPlatformLineBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
((Integer)attributes.get(ATTR_LINE_NUMBER)).intValue());
}
else if (ICWatchpoint.class.equals(type)) {
return findPlatformWatchpoint(
(String)attributes.get(ATTR_EXPRESSION),
((Boolean)attributes.get(ATTR_READ)).booleanValue(),
((Boolean)attributes.get(ATTR_WRITE)).booleanValue());
}
throw new Exception(String.format("Invalid breakpoint type: %s", type.getName()));
}
private void deleteAllPlatformBreakpoints() throws Exception {
IBreakpointManager bm = DebugPlugin.getDefault().getBreakpointManager();
for (IBreakpoint b : bm.getBreakpoints()) {
bm.removeBreakpoint(b, true);
}
}
}

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2012 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_4;
import org.eclipse.cdt.tests.dsf.gdb.tests.GDBConsoleBreakpointsTest;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
public class GDBConsoleBreakpointsTest_7_4 extends GDBConsoleBreakpointsTest {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_4);
}
}

View file

@ -46,7 +46,8 @@ import org.junit.runners.Suite;
PostMortemCoreTest_7_4.class,
CommandTimeoutTest_7_4.class,
GDBMultiNonStopRunControlTest_7_4.class,
Suite_Sessionless_Tests.class,
Suite_Sessionless_Tests.class,
GDBConsoleBreakpointsTest_7_4.class,
/* Add your test class here */
})

View file

@ -46,7 +46,9 @@ import org.junit.runners.Suite;
OperationsWhileTargetIsRunningNonStopTest_7_4.class,
CommandTimeoutTest_7_4.class,
GDBMultiNonStopRunControlTest_7_4.class,
Suite_Sessionless_Tests.class
Suite_Sessionless_Tests.class,
GDBConsoleBreakpointsTest_7_4.class,
TraceFileTest_7_4.class,
/* Add your test class here */
})

View file

@ -0,0 +1,426 @@
/*******************************************************************************
* Copyright (c) 2012 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_4;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.breakpointactions.BreakpointActionManager;
import org.eclipse.cdt.debug.core.model.ICTracepoint;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
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.IBreakpointsTargetDMContext;
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.ITracepointAction;
import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.MIBreakpointDMContext;
import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.tests.dsf.gdb.framework.AsyncCompletionWaitor;
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.junit.After;
import org.junit.Test;
public class TraceFileTest_7_4 extends BaseTestCase {
private final static String FILE_NAME = "TracepointTestApp.cc";
private final static int LINE_NUMBER_1 = 97;
private final static int LINE_NUMBER_2 = 102;
private final static String TEVAL_STRING = "lBoolPtr2";
private final static String COLLECT_STRING1 = "counter";
private final static String COLLECT_STRING2 = "$regs";
private final static String TRACE_FILE = "data/launch/bin/trace";
private DsfSession fSession;
private DsfServicesTracker fServicesTracker;
private IBreakpoints fBreakpointService;
private IGDBTraceControl fTraceService;
private IBreakpointsTargetDMContext fBreakpointsDmc;
private ITraceTargetDMContext fTraceTargetDmc;
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_4);
}
@Override
public void doBeforeTest() throws Exception {
// Suppress settings of the launch attributes and launching.
// Each test sets its own launch attributes
}
@Override
@After
public void doAfterTest() throws Exception {
super.doAfterTest();
fBreakpointService = null;
fTraceService = null;
fBreakpointsDmc = null;
fTraceTargetDmc = null;
if (fServicesTracker != null) {
fServicesTracker.dispose();
fServicesTracker = null;
}
}
/**
* This test implements the following steps.
* 1. Starts a remote session
* 2. Sets two tracepoints at data/launch/src/TracepointTestApp.cc:97
* and data/launch/src/TracepointTestApp.cc:102.
* The first tracepoint's command is "teval lBoolPtr2".
* The second tracepoint's commands are "collect counter" and "collect $regs".
* 3. Sets a regular breakpoint at the end of the source file.
* 4. Starts tracing
* 5. Resumes and runs until the breakpoint is hit
* 6. Stops tracing
* 7. Saves the trace data into a file (data/launch/bin/trace).
*/
@Test
public void createTraceFile() throws Throwable {
deleteOldTraceFile();
startRemoteSession();
setTracepoints();
MIBreakpointDMContext bptDMC = setBreakpointAtEndLine();
startTracing();
MIStoppedEvent stoppedEvent = SyncUtil.resumeUntilStopped();
assertTrue(stoppedEvent instanceof MIBreakpointHitEvent
&& ((MIBreakpointHitEvent)stoppedEvent).getNumber() == bptDMC.getReference());
stopTracing();
saveTraceData();
}
/**
* This test removes all existing tracepoint actions and tracepoints
* and verifies that corresponding platform tracepoints with the proper
* actions are created.
*/
@Test
public void testTraceFile() throws Throwable {
// Make sure that there is no tracepoint actions and platform breakpoints
// are in the workspace.
deleteActionsAndBreakpoints();
startTraceFileSession();
// Verify that required tracepoints and new tracepoint actions are created.
checkActionsAndTracepoints();
}
/**
* This test verifies that the tracepoint actions and platform tracepoints
* created by 'testTraceFile()' are associated with the corresponding target
* tracepoints.
*/
@Test
public void testTraceFileWithExistingTracepoints() throws Throwable {
// Verify that actions and tracepoints required for this test are in place.
checkActionsAndTracepoints();
startTraceFileSession();
// Verify that no new platform tracepoints or new tracepoint actions are created.
checkActionsAndTracepoints();
}
private void startTraceFileSession() throws Throwable {
// Set launch attributes
super.setLaunchAttributes();
// Set a working directory for GDB that is different than eclipse's directory.
// This allows us to make sure we properly handle finding the core file,
// especially in the case of a relative path
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, "${workspace_loc}");
// Because we just set a different working directory, we must use an absolute path for the program
String absoluteProgram = new Path("data/launch/bin/TracepointTestApp.exe").toFile().getAbsolutePath();
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, absoluteProgram);
// Set post-mortem launch
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE);
// Set post-mortem type to trace file
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_POST_MORTEM_TYPE,
IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE);
// Set core file path
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, TRACE_FILE);
doLaunch();
// Allow time to create tracepoint actions
Thread.sleep(1000);
}
/**
* Deletes all tracepoint actions and all existing platform breakpoints.
*/
private void deleteActionsAndBreakpoints() throws Throwable {
TracepointActionManager tam = TracepointActionManager.getInstance();
IBreakpointManager bm = DebugPlugin.getDefault().getBreakpointManager();
// Delete all existing actions
@SuppressWarnings( "unchecked" )
ArrayList<ITracepointAction> actions = (ArrayList<ITracepointAction>)tam.getActions().clone();
for (ITracepointAction a : actions) {
tam.deleteAction(a);
}
IBreakpoint[] bpts = bm.getBreakpoints();
for (IBreakpoint b : bpts) {
bm.removeBreakpoint(b, true);
}
}
/**
* Checks whether there are only two platform tracepoints and three tracepoint actions.
*/
private void checkActionsAndTracepoints() throws Throwable {
TracepointActionManager tam = TracepointActionManager.getInstance();
IBreakpointManager bm = DebugPlugin.getDefault().getBreakpointManager();
ArrayList<ITracepointAction> actions = tam.getActions();
IBreakpoint[] bpts = bm.getBreakpoints();
actions = tam.getActions();
assertTrue(String.format("Unexpected count of tracepoint actions: %d", actions.size()), actions.size() == 3);
bpts = bm.getBreakpoints();
assertTrue(String.format("Unexpected count of breakpoints: %d", bpts.length), bpts.length == 2);
for (IBreakpoint b : bpts) {
assertTrue(b instanceof ICTracepoint);
checkTracepoint((ICTracepoint)b);
}
}
private void checkTracepoint(ICTracepoint tracepoint) throws Throwable {
TracepointActionManager tam = TracepointActionManager.getInstance();
assertTrue(FILE_NAME.equals(new Path(tracepoint.getFileName()).lastSegment()));
assertTrue(LINE_NUMBER_1 == tracepoint.getLineNumber() || LINE_NUMBER_2 == tracepoint.getLineNumber());
String[] actionNames =
((String)tracepoint.getMarker().getAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE)).split(TracepointActionManager.TRACEPOINT_ACTION_DELIMITER);
for (String name : actionNames) {
ITracepointAction a = tam.findAction(name);
assertNotNull(a);
if (a instanceof EvaluateAction) {
assertTrue(TEVAL_STRING.equals(((EvaluateAction)a).getEvalString()));
}
if (a instanceof CollectAction) {
assertTrue(COLLECT_STRING1.equals(((CollectAction)a).getCollectString())
|| COLLECT_STRING2.equals(((CollectAction)a).getCollectString()));
}
}
}
private void startRemoteSession() throws Throwable {
// Set launch attributes
super.setLaunchAttributes();
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/TracepointTestApp.exe");
// GDB tracepoints are only supported on a remote target (e.g., using gdbserver)
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE);
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
// Start the session
doLaunch();
// Initialize
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(IGDBTraceControl.class);
}
};
fSession.getExecutor().submit(runnable).get();
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
fBreakpointsDmc = DMContexts.getAncestorOfType(containerDmc, IBreakpointsTargetDMContext.class);
assertNotNull(fBreakpointsDmc);
fTraceTargetDmc = DMContexts.getAncestorOfType(containerDmc, ITraceTargetDMContext.class);
assertNotNull(fTraceTargetDmc);
}
private void startTracing() throws Throwable {
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
fSession.getExecutor().submit(new Runnable() {
@Override
public void run() {
fTraceService.getTraceStatus(
fTraceTargetDmc,
new DataRequestMonitor<ITraceStatusDMData>(fSession.getExecutor(), null) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleCompleted() {
if (isSuccess() && getData().isTracingSupported()) {
fTraceService.startTracing(
fTraceTargetDmc,
new RequestMonitor(fSession.getExecutor(), null) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleCompleted() {
wait.waitFinished(getStatus());
}
});
}
else {
wait.waitFinished(getStatus());
}
}
});
}
});
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
assertTrue(wait.getMessage(), wait.isOK());
}
private void stopTracing() throws Throwable {
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
fSession.getExecutor().submit(new Runnable() {
@Override
public void run() {
fTraceService.stopTracing(
fTraceTargetDmc,
new RequestMonitor(fSession.getExecutor(), null) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleCompleted() {
wait.waitFinished(getStatus());
}
});
}
});
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
assertTrue(wait.getMessage(), wait.isOK());
}
private MIBreakpointDMContext setBreakpointAtEndLine() throws Throwable {
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attributes.put(MIBreakpoints.FILE_NAME, FILE_NAME);
attributes.put(MIBreakpoints.LINE_NUMBER, 152);
IBreakpointDMContext bptDMC = insertBreakpoint(fBreakpointsDmc, attributes);
assertTrue(bptDMC instanceof MIBreakpointDMContext);
return (MIBreakpointDMContext)bptDMC;
}
private void setTracepoints() throws Throwable {
TracepointActionManager tam = TracepointActionManager.getInstance();
CollectAction collectAction1 = new CollectAction();
collectAction1.setCollectString(COLLECT_STRING1);
collectAction1.setName(String.format("Collect %s", COLLECT_STRING1));
tam.addAction(collectAction1);
CollectAction collectAction2 = new CollectAction();
collectAction2.setCollectString(COLLECT_STRING2);
collectAction2.setName(String.format("Collect %s", COLLECT_STRING2));
tam.addAction(collectAction2);
EvaluateAction evalAction = new EvaluateAction();
evalAction.setEvalString(TEVAL_STRING);
evalAction.setName(String.format("Evaluate %s", TEVAL_STRING));
tam.addAction(evalAction);
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.TRACEPOINT);
attributes.put(MIBreakpoints.FILE_NAME, FILE_NAME);
attributes.put(MIBreakpoints.LINE_NUMBER, LINE_NUMBER_1);
attributes.put(MIBreakpoints.COMMANDS, evalAction.getName());
insertBreakpoint(fBreakpointsDmc, attributes);
attributes.put(MIBreakpoints.LINE_NUMBER, LINE_NUMBER_2);
attributes.put(MIBreakpoints.COMMANDS,
String.format("%s%s%s", collectAction1.getName(),
TracepointActionManager.TRACEPOINT_ACTION_DELIMITER, collectAction2.getName()));
insertBreakpoint(fBreakpointsDmc, attributes);
}
private IBreakpointDMContext insertBreakpoint(
final IBreakpointsTargetDMContext context,
final Map<String,Object> attributes) throws InterruptedException {
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
fSession.getExecutor().submit(new Runnable() {
@Override
public void run() {
fBreakpointService.insertBreakpoint(context, attributes,
new DataRequestMonitor<IBreakpointDMContext>(fBreakpointService.getExecutor(), null) {
@Override
protected void handleCompleted() {
wait.setReturnInfo(getData());
wait.waitFinished(getStatus());
}
});
}
});
// Wait for the result and return the breakpoint context
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
assertTrue(wait.getMessage(), wait.isOK());
return (IBreakpointDMContext)wait.getReturnInfo();
}
private void saveTraceData() throws Throwable {
final File traceFile = new Path(TRACE_FILE).toFile();
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
fSession.getExecutor().submit(new Runnable() {
@Override
public void run() {
fTraceService.saveTraceData(
fTraceTargetDmc,
traceFile.getAbsolutePath(),
false,
new RequestMonitor(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
wait.waitFinished(getStatus());
}
});
}
});
// Wait for the result and verify the trace file is created
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
assertTrue(wait.getMessage(), wait.isOK());
assertTrue(traceFile.exists());
}
private void deleteOldTraceFile() throws Throwable {
File traceFile = new Path(TRACE_FILE).toFile();
traceFile.delete();
assertFalse(traceFile.exists());
}
}

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2012 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_5;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_4.GDBConsoleBreakpointsTest_7_4;
public class GDBConsoleBreakpointsTest_7_5 extends GDBConsoleBreakpointsTest_7_4 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_5);
}
}

View file

@ -46,7 +46,8 @@ import org.junit.runners.Suite;
PostMortemCoreTest_7_5.class,
CommandTimeoutTest_7_5.class,
GDBMultiNonStopRunControlTest_7_5.class,
Suite_Sessionless_Tests.class,
Suite_Sessionless_Tests.class,
GDBConsoleBreakpointsTest_7_5.class,
/* Add your test class here */
})

View file

@ -46,7 +46,9 @@ import org.junit.runners.Suite;
OperationsWhileTargetIsRunningNonStopTest_7_5.class,
CommandTimeoutTest_7_5.class,
GDBMultiNonStopRunControlTest_7_5.class,
Suite_Sessionless_Tests.class
Suite_Sessionless_Tests.class,
GDBConsoleBreakpointsTest_7_5.class,
TraceFileTest_7_5.class,
/* Add your test class here */
})

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2012 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_5;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_4.TraceFileTest_7_4;
public class TraceFileTest_7_5 extends TraceFileTest_7_4 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_5);
}
}