From 115e1208c35e3f0e5a672bfb3e4c27a7f6b00c12 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Sat, 18 Oct 2003 01:22:27 +0000 Subject: [PATCH] Framework to deferred breakpoint --- .../cdt/debug/mi/core/CygwinGDBDebugger.java | 23 +- .../cdt/debug/mi/core/GDBDebugger.java | 23 +- .../eclipse/cdt/debug/mi/core/RxThread.java | 7 + .../debug/mi/core/cdi/BreakpointManager.java | 82 +++++-- .../cdt/debug/mi/core/cdi/EventManager.java | 221 ++++++++++++++++-- .../mi/core/cdi/SharedLibraryManager.java | 26 ++- .../debug/mi/core/cdi/event/ResumedEvent.java | 4 +- .../debug/mi/core/cdi/model/Breakpoint.java | 43 +++- .../debug/mi/core/cdi/model/StackFrame.java | 2 +- .../cdt/debug/mi/core/cdi/model/Thread.java | 9 +- .../debug/mi/core/cdi/model/Watchpoint.java | 25 +- .../debug/mi/core/event/MIRunningEvent.java | 1 + .../debug/mi/core/output/MIBreakpoint.java | 6 +- 13 files changed, 413 insertions(+), 59 deletions(-) diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinGDBDebugger.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinGDBDebugger.java index 19cacfa0f46..53f86a78e10 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinGDBDebugger.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinGDBDebugger.java @@ -33,11 +33,21 @@ public class CygwinGDBDebugger extends GDBDebugger { protected void initializeLibraries(ILaunchConfiguration config, Session session) throws CDIException { try { - ICDISharedLibraryManager mgr = session.getSharedLibraryManager(); - if (mgr instanceof SharedLibraryManager) { + ICDISharedLibraryManager manager = session.getSharedLibraryManager(); + if (manager instanceof SharedLibraryManager) { + SharedLibraryManager mgr = (SharedLibraryManager)manager; boolean stopOnSolibEvents = config.getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_STOP_ON_SOLIB_EVENTS, false); try { - ((SharedLibraryManager)mgr).setStopOnSolibEvents(stopOnSolibEvents); + mgr.setStopOnSolibEvents(stopOnSolibEvents); + // By default, we provide with the capability of deferred breakpoints + // And we set setStopOnSolib events for them(but they should not see the dll events ). + // + // If the user explicitly set stopOnSolibEvents well it probably + // means that they wanted to see those events so do no do deferred breakpoints. + if (!stopOnSolibEvents) { + mgr.setStopOnSolibEvents(true); + mgr.setDeferredBreakpoint(true); + } } catch (CDIException e) { // Ignore this error // it seems to be a real problem on many gdb platform @@ -45,11 +55,11 @@ public class CygwinGDBDebugger extends GDBDebugger { } List p = config.getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, Collections.EMPTY_LIST); if (p.size() > 0) { - String[] oldPaths = mgr.getSharedLibraryPaths(); + String[] oldPaths = manager.getSharedLibraryPaths(); String[] paths = new String[oldPaths.length + p.size()]; System.arraycopy((String[])p.toArray(new String[p.size()]), 0, paths, 0, p.size()); System.arraycopy(oldPaths, 0, paths, p.size(), oldPaths.length); - mgr.setSharedLibraryPaths(paths); + manager.setSharedLibraryPaths(paths); } } catch (CoreException e) { throw new CDIException("Error initializing shared library options: " + e.getMessage()); @@ -77,6 +87,7 @@ public class CygwinGDBDebugger extends GDBDebugger { // We ignore this exception, for example // on GNU/Linux the new-console is an error. } + initializeLibraries(config, session); return session; } @@ -88,6 +99,7 @@ public class CygwinGDBDebugger extends GDBDebugger { Session session = (Session) super.createAttachSession(config, exe, pid); session.getMISession().setCommandFactory(commandFactory); + initializeLibraries(config, session); return session; } @@ -99,6 +111,7 @@ public class CygwinGDBDebugger extends GDBDebugger { Session session = (Session) super.createCoreSession(config, exe, corefile); session.getMISession().setCommandFactory(commandFactory); + initializeLibraries(config, session); return session; } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBDebugger.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBDebugger.java index 0ddf8889e20..5cede42edc8 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBDebugger.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBDebugger.java @@ -24,13 +24,24 @@ public class GDBDebugger implements ICDebugger { protected void initializeLibraries(ILaunchConfiguration config, Session session) throws CDIException { try { - ICDISharedLibraryManager mgr = session.getSharedLibraryManager(); - if (mgr instanceof SharedLibraryManager) { + ICDISharedLibraryManager manager = session.getSharedLibraryManager(); + if (manager instanceof SharedLibraryManager) { + SharedLibraryManager mgr = (SharedLibraryManager)manager; boolean autolib = config.getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB, false); boolean stopOnSolibEvents = config.getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_STOP_ON_SOLIB_EVENTS, false); try { - ((SharedLibraryManager)mgr).setAutoLoadSymbols(autolib); - ((SharedLibraryManager)mgr).setStopOnSolibEvents(stopOnSolibEvents); + mgr.setAutoLoadSymbols(autolib); + mgr.setStopOnSolibEvents(stopOnSolibEvents); + // The idea is that if the user set autolib, by default + // we provide with the capability of deferred breakpoints + // And we set setStopOnSolib events for them(but they should not see those things. + // + // If the user explicitly set stopOnSolibEvents well it probably + // means that they wanted to see those events so do no do deferred breakpoints. + if (autolib && !stopOnSolibEvents) { + mgr.setDeferredBreakpoint(true); + mgr.setStopOnSolibEvents(true); + } } catch (CDIException e) { // Ignore this error // it seems to be a real problem on many gdb platform @@ -38,11 +49,11 @@ public class GDBDebugger implements ICDebugger { } List p = config.getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, Collections.EMPTY_LIST); if (p.size() > 0) { - String[] oldPaths = mgr.getSharedLibraryPaths(); + String[] oldPaths = manager.getSharedLibraryPaths(); String[] paths = new String[oldPaths.length + p.size()]; System.arraycopy((String[])p.toArray(new String[p.size()]), 0, paths, 0, p.size()); System.arraycopy(oldPaths, 0, paths, p.size(), oldPaths.length); - mgr.setSharedLibraryPaths(paths); + manager.setSharedLibraryPaths(paths); } } catch (CoreException e) { throw new CDIException("Error initializing shared library options: " + e.getMessage()); diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/RxThread.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/RxThread.java index 7445f0e3f58..93bac3fb00f 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/RxThread.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/RxThread.java @@ -12,9 +12,11 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.debug.mi.core.command.Command; +import org.eclipse.cdt.debug.mi.core.command.MIExecContinue; import org.eclipse.cdt.debug.mi.core.command.MIExecFinish; import org.eclipse.cdt.debug.mi.core.command.MIExecNext; import org.eclipse.cdt.debug.mi.core.command.MIExecNextInstruction; +import org.eclipse.cdt.debug.mi.core.command.MIExecReturn; import org.eclipse.cdt.debug.mi.core.command.MIExecStep; import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction; import org.eclipse.cdt.debug.mi.core.command.MIExecUntil; @@ -146,6 +148,10 @@ public class RxThread extends Thread { type = MIRunningEvent.UNTIL; } else if (cmd instanceof MIExecFinish) { type = MIRunningEvent.FINISH; + } else if (cmd instanceof MIExecReturn) { + type = MIRunningEvent.RETURN; + } else if (cmd instanceof MIExecContinue) { + type = MIRunningEvent.CONTINUE; } else { type = MIRunningEvent.CONTINUE; } @@ -199,6 +205,7 @@ public class RxThread extends Thread { void processMIOOBRecord(MIOOBRecord oob, List list) { if (oob instanceof MIAsyncRecord) { processMIOOBRecord((MIAsyncRecord) oob, list); + oobList.clear(); } else if (oob instanceof MIStreamRecord) { processMIOOBRecord((MIStreamRecord) oob); } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java index c9cf28df339..a641d53793f 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java @@ -14,6 +14,7 @@ import org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager; import org.eclipse.cdt.debug.core.cdi.ICDICatchEvent; import org.eclipse.cdt.debug.core.cdi.ICDICondition; import org.eclipse.cdt.debug.core.cdi.ICDILocation; +import org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryManager; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDICatchpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILocationBreakpoint; @@ -50,12 +51,14 @@ import org.eclipse.cdt.debug.mi.core.output.MIInfo; public class BreakpointManager extends SessionObject implements ICDIBreakpointManager { List breakList; + List deferredList; boolean allowInterrupt; boolean autoupdate; public BreakpointManager(Session session) { super(session); breakList = Collections.synchronizedList(new ArrayList()); + deferredList = Collections.synchronizedList(new ArrayList()); allowInterrupt = true; autoupdate = false; } @@ -265,6 +268,8 @@ public class BreakpointManager extends SessionObject implements ICDIBreakpointMa // Fire ChangedEvent bp.setMIBreakpoint(newMIBreakpoints[i]); eventList.add(new MIBreakpointChangedEvent(no)); + } else { + eventList.add(new MIBreakpointCreatedEvent(no)); } } else { // add the new breakpoint and fire CreatedEvent @@ -318,6 +323,14 @@ public class BreakpointManager extends SessionObject implements ICDIBreakpointMa deleteBreakpoints(new ICDIBreakpoint[] { breakpoint }); } + public void deleteFromDeferredList(Breakpoint bkpt) { + deferredList.remove(bkpt); + } + + public void addToBreakpointList(Breakpoint bkpt) { + breakList.add(bkpt); + } + /** * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#deleteBreakpoints(ICDIBreakpoint[]) */ @@ -364,6 +377,10 @@ public class BreakpointManager extends SessionObject implements ICDIBreakpointMa return (ICDIBreakpoint[]) breakList.toArray(new ICDIBreakpoint[0]); } + public ICDIBreakpoint[] getDeferredBreakpoints() throws CDIException { + return (ICDIBreakpoint[]) deferredList.toArray(new ICDIBreakpoint[0]); + } + /** * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#setCatchpoint(int, ICDICatchEvent, String, ICDICondition, boolean) */ @@ -377,18 +394,58 @@ public class BreakpointManager extends SessionObject implements ICDIBreakpointMa */ public ICDILocationBreakpoint setLocationBreakpoint(int type, ICDILocation location, ICDICondition condition, String threadId) throws CDIException { + return setLocationBreakpoint(type, location, condition, threadId, false); + } - boolean hardware = (type == ICDIBreakpoint.HARDWARE); - boolean temporary = (type == ICDIBreakpoint.TEMPORARY); + /** + * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#setLocationBreakpoint(int, ICDILocation, ICDICondition, boolean, String) + */ + public ICDILocationBreakpoint setLocationBreakpoint(int type, ICDILocation location, + ICDICondition condition, String threadId, boolean deferred) throws CDIException { + + Breakpoint bkpt = new Breakpoint(this, type, location, condition, threadId); + try { + setLocationBreakpoint(bkpt); + breakList.add(bkpt); + + // Fire a created Event. + Session session = (Session)getSession(); + MISession mi = session.getMISession(); + mi.fireEvent(new MIBreakpointCreatedEvent(bkpt.getMIBreakpoint().getNumber())); + } catch (CDIException e) { + if (!deferred) { + throw e; + } else { + Session session = (Session)getSession(); + ICDISharedLibraryManager sharedMgr = session.getSharedLibraryManager(); + if (sharedMgr instanceof SharedLibraryManager) { + SharedLibraryManager mgr = (SharedLibraryManager)sharedMgr; + if (mgr.isDeferredBreakpoint()) { + deferredList.add(bkpt); + } else { + throw e; + } + } + } + } + return bkpt; + } + + MIBreakInsert createMIBreakInsert(Breakpoint bkpt) throws CDIException { + boolean hardware = bkpt.isHardware(); + boolean temporary = bkpt.isTemporary(); String exprCond = null; int ignoreCount = 0; StringBuffer line = new StringBuffer(); - if (condition != null) { + + if (bkpt.getCondition() != null) { + ICDICondition condition = bkpt.getCondition(); exprCond = condition.getExpression(); ignoreCount = condition.getIgnoreCount(); } - if (location != null) { + if (bkpt.getLocation() != null) { + ICDILocation location = bkpt.getLocation(); String file = location.getFile(); String function = location.getFunction(); if (file != null && file.length() > 0) { @@ -406,13 +463,15 @@ public class BreakpointManager extends SessionObject implements ICDIBreakpointMa line.append('*').append(location.getAddress()); } } + Session session = (Session)getSession(); + CommandFactory factory = session.getMISession().getCommandFactory(); + return factory.createMIBreakInsert(temporary, hardware, exprCond, ignoreCount, line.toString()); + } + public void setLocationBreakpoint (Breakpoint bkpt) throws CDIException { Session session = (Session)getSession(); boolean state = suspendInferior(session.getCurrentTarget()); - CommandFactory factory = session.getMISession().getCommandFactory(); - MIBreakInsert breakInsert = - factory.createMIBreakInsert( temporary, hardware, exprCond, - ignoreCount, line.toString()); + MIBreakInsert breakInsert = createMIBreakInsert(bkpt); MIBreakpoint[] points = null; try { session.getMISession().postCommand(breakInsert); @@ -429,13 +488,8 @@ public class BreakpointManager extends SessionObject implements ICDIBreakpointMa } finally { resumeInferior(session.getCurrentTarget(), state); } - Breakpoint bkpt = new Breakpoint(this, points[0]); - breakList.add(bkpt); - // Fire a created Event. - MISession mi = session.getMISession(); - mi.fireEvent(new MIBreakpointCreatedEvent(bkpt.getMIBreakpoint().getNumber())); - return bkpt; + bkpt.setMIBreakpoint(points[0]); } /** diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/EventManager.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/EventManager.java index cb3597df71d..5699846b9e4 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/EventManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/EventManager.java @@ -23,7 +23,12 @@ import org.eclipse.cdt.debug.core.cdi.ICDISourceManager; import org.eclipse.cdt.debug.core.cdi.ICDIVariableManager; import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent; import org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; +import org.eclipse.cdt.debug.core.cdi.model.ICDIThread; +import org.eclipse.cdt.debug.mi.core.MIException; +import org.eclipse.cdt.debug.mi.core.MISession; import org.eclipse.cdt.debug.mi.core.cdi.event.ChangedEvent; import org.eclipse.cdt.debug.mi.core.cdi.event.CreatedEvent; import org.eclipse.cdt.debug.mi.core.cdi.event.DestroyedEvent; @@ -32,8 +37,17 @@ import org.eclipse.cdt.debug.mi.core.cdi.event.ExitedEvent; import org.eclipse.cdt.debug.mi.core.cdi.event.MemoryChangedEvent; import org.eclipse.cdt.debug.mi.core.cdi.event.ResumedEvent; import org.eclipse.cdt.debug.mi.core.cdi.event.SuspendedEvent; +import org.eclipse.cdt.debug.mi.core.cdi.model.Breakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.MemoryBlock; import org.eclipse.cdt.debug.mi.core.cdi.model.Target; +import org.eclipse.cdt.debug.mi.core.cdi.model.Thread; +import org.eclipse.cdt.debug.mi.core.command.Command; +import org.eclipse.cdt.debug.mi.core.command.CommandFactory; +import org.eclipse.cdt.debug.mi.core.command.MIExecContinue; +import org.eclipse.cdt.debug.mi.core.command.MIExecFinish; +import org.eclipse.cdt.debug.mi.core.command.MIStackInfoDepth; +import org.eclipse.cdt.debug.mi.core.command.MIStackSelectFrame; +import org.eclipse.cdt.debug.mi.core.command.MIThreadSelect; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointChangedEvent; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointDeletedEvent; @@ -52,6 +66,7 @@ import org.eclipse.cdt.debug.mi.core.event.MIRegisterCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MIRunningEvent; import org.eclipse.cdt.debug.mi.core.event.MISharedLibChangedEvent; import org.eclipse.cdt.debug.mi.core.event.MISharedLibCreatedEvent; +import org.eclipse.cdt.debug.mi.core.event.MISharedLibEvent; import org.eclipse.cdt.debug.mi.core.event.MISharedLibUnloadedEvent; import org.eclipse.cdt.debug.mi.core.event.MISignalChangedEvent; import org.eclipse.cdt.debug.mi.core.event.MIStoppedEvent; @@ -60,6 +75,8 @@ import org.eclipse.cdt.debug.mi.core.event.MIThreadExitEvent; import org.eclipse.cdt.debug.mi.core.event.MIVarChangedEvent; import org.eclipse.cdt.debug.mi.core.event.MIVarCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MIVarDeletedEvent; +import org.eclipse.cdt.debug.mi.core.output.MIInfo; +import org.eclipse.cdt.debug.mi.core.output.MIStackInfoDepthInfo; /** */ @@ -67,6 +84,8 @@ public class EventManager extends SessionObject implements ICDIEventManager, Obs List list = Collections.synchronizedList(new ArrayList(1)); List tokenList = new ArrayList(1); + MIRunningEvent lastRunningEvent; + Command lastUserCommand = null; /** * Process the event from MI, do any state work on the CDI, @@ -80,10 +99,12 @@ public class EventManager extends SessionObject implements ICDIEventManager, Obs if (ignoreEventToken(miEvent.getToken())) { // Ignore the event if it is on the ignore list. } else if (miEvent instanceof MIStoppedEvent) { - processSuspendedEvent((MIStoppedEvent)miEvent); - cdiList.add(new SuspendedEvent(session, miEvent)); + if (processSuspendedEvent((MIStoppedEvent)miEvent)) { + cdiList.add(new SuspendedEvent(session, miEvent)); + } } else if (miEvent instanceof MIRunningEvent) { - cdiList.add(new ResumedEvent(session, (MIRunningEvent)miEvent)); + if (processRunningEvent((MIRunningEvent)miEvent)) + cdiList.add(new ResumedEvent(session, (MIRunningEvent)miEvent)); } else if (miEvent instanceof MIChangedEvent) { if (miEvent instanceof MIVarChangedEvent) { cdiList.add(new ChangedEvent(session, (MIVarChangedEvent)miEvent)); @@ -238,24 +259,36 @@ public class EventManager extends SessionObject implements ICDIEventManager, Obs * Alse the variable and the memory needs to be updated and events * fired for changes. */ - void processSuspendedEvent(MIStoppedEvent stopped) { + boolean processSuspendedEvent(MIStoppedEvent stopped) { Session session = (Session)getSession(); ICDITarget currentTarget = session.getCurrentTarget(); - // Set the current thread. + + if (processSharedLibEvent(stopped)) { + // Event was consumed by the shared lib processing bailout + return false; + } + int threadId = threadId = stopped.getThreadId(); if (currentTarget instanceof Target) { - ((Target)currentTarget).updateState(threadId); + Target cTarget = (Target)currentTarget; + cTarget.updateState(threadId); + try { + cTarget.getCurrentThread().getCurrentStackFrame(); + } catch (CDIException e1) { + //e1.printStackTrace(); + } } + // Update the managers. // For the Variable/Expression Managers call only the updateManager. ICDIVariableManager varMgr = session.getVariableManager(); ICDIExpressionManager expMgr = session.getExpressionManager(); ICDIRegisterManager regMgr = session.getRegisterManager(); ICDIMemoryManager memMgr = session.getMemoryManager(); - ICDISharedLibraryManager libMgr = session.getSharedLibraryManager(); ICDIBreakpointManager bpMgr = session.getBreakpointManager(); ICDISignalManager sigMgr = session.getSignalManager(); ICDISourceManager srcMgr = session.getSourceManager(); + ICDISharedLibraryManager libMgr = session.getSharedLibraryManager(); try { if (varMgr.isAutoUpdate()) { varMgr.update(); @@ -269,29 +302,191 @@ public class EventManager extends SessionObject implements ICDIEventManager, Obs if (memMgr.isAutoUpdate()) { memMgr.update(); } - if (libMgr.isAutoUpdate()) { - libMgr.update(); - } if (bpMgr.isAutoUpdate()) { bpMgr.update(); } if (sigMgr.isAutoUpdate()) { sigMgr.update(); } + if (libMgr.isAutoUpdate()) { + libMgr.update(); + } if (srcMgr.isAutoUpdate()) { srcMgr.update(); } } catch (CDIException e) { //System.out.println(e); } + return true; + } + + /** + * If the deferredBreakpoint processing is set + * catch the shared-lib-event go to the last known + * stackframe and try to finish. + * Save the last user command and issue it again. + * @param stopped + * @return + */ + boolean processSharedLibEvent(MIStoppedEvent stopped) { + Session session = (Session)getSession(); + MISession mi = session.getMISession(); + + ICDITarget currentTarget = session.getCurrentTarget(); + ICDISharedLibraryManager libMgr = session.getSharedLibraryManager(); + SharedLibraryManager mgr = null; + + if (libMgr instanceof SharedLibraryManager) { + mgr = (SharedLibraryManager)libMgr; + } + + if (mgr !=null && mgr.isDeferredBreakpoint()) { + if (stopped instanceof MISharedLibEvent) { + // Check if we have a new library loaded + List eventList = null; + try { + eventList = mgr.updateState(); + } catch (CDIException e3) { + eventList = Collections.EMPTY_LIST; + } + // A new Libraries loaded, try to set the breakpoints. + if (eventList.size() > 0) { + boolean breakpointSet = false; + ICDIBreakpointManager manager = session.getBreakpointManager(); + if (manager instanceof BreakpointManager) { + BreakpointManager bpMgr = (BreakpointManager)manager; + ICDIBreakpoint bpoints[] = null; + try { + bpoints = bpMgr.getDeferredBreakpoints(); + } catch (CDIException e) { + bpoints = new ICDIBreakpoint[0]; + } + for (int i = 0; i < bpoints.length; i++) { + if (bpoints[i] instanceof Breakpoint) { + Breakpoint bkpt = (Breakpoint)bpoints[i]; + try { + bpMgr.setLocationBreakpoint(bkpt); + bpMgr.deleteFromDeferredList(bkpt); + bpMgr.addToBreakpointList(bkpt); + eventList.add(new MIBreakpointCreatedEvent(bkpt.getMIBreakpoint().getNumber())); + } catch (CDIException e) { + } + } + } + } + MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]); + mi.fireEvents(events); + } + CommandFactory factory = mi.getCommandFactory(); + int type = (lastRunningEvent == null) ? MIRunningEvent.CONTINUE : lastRunningEvent.getType(); + if (lastUserCommand == null) { + switch (type) { + case MIRunningEvent.NEXT: + lastUserCommand = factory.createMIExecNext(); + break; + case MIRunningEvent.NEXTI: + lastUserCommand = factory.createMIExecNextInstruction(); + break; + case MIRunningEvent.STEP: + lastUserCommand = factory.createMIExecStep(); + break; + case MIRunningEvent.STEPI: + lastUserCommand = factory.createMIExecStepInstruction(); + break; + case MIRunningEvent.FINISH: + lastUserCommand = factory.createMIExecFinish(); + break; + case MIRunningEvent.RETURN: + lastUserCommand = factory.createMIExecReturn(); + break; + case MIRunningEvent.CONTINUE: { + MIExecContinue cont = factory.createMIExecContinue(); + try { + mi.postCommand(cont); + MIInfo info = cont.getMIInfo(); + if (info == null) { + // throw new CDIException("Target is not responding"); + } + } catch (MIException e) { + // throw new MI2CDIException(e); + } + return true; // for the continue bailout early no need to the stuff below + } + } + } + + int miLevel = 0; + int tid = 0; + ICDIThread currentThread = null; + try { + currentThread = currentTarget.getCurrentThread(); + } catch (CDIException e1) { + } + if (currentThread instanceof Thread) { + tid = ((Thread)currentThread).getId(); + } + ICDIStackFrame frame = null; + try { + frame = currentThread.getCurrentStackFrame(); + } catch (CDIException e2) { + } + int count = 0; + try { + MIStackInfoDepth depth = factory.createMIStackInfoDepth(); + mi.postCommand(depth); + MIStackInfoDepthInfo info = depth.getMIStackInfoDepthInfo(); + if (info == null) { + //throw new CDIException("No answer"); + } + count = info.getDepth(); + } catch (MIException e) { + //throw new MI2CDIException(e); + //System.out.println(e); + } + if (frame != null) { + // Fortunately the ICDIStackFrame store the level + // in ascending level the higher the stack the higher the level + // GDB does the opposite the highest stack is 0. + // This allow us to do some calculation, in figure out the + // level of the old stack. The -1 is because gdb level is zero-based + miLevel = count - frame.getLevel() - 1; + } + if (tid > 0) { + MIThreadSelect selectThread = factory.createMIThreadSelect(tid); + try { + mi.postCommand(selectThread); + } catch (MIException e) { + } + } + if (miLevel > 0) { + MIStackSelectFrame selectFrame = factory.createMIStackSelectFrame(miLevel); + MIExecFinish finish = factory.createMIExecFinish(); + try { + mi.postCommand(selectFrame); + mi.postCommand(finish); + } catch (MIException e) { + } + } + return true; + } else if (lastUserCommand != null) { + Command cmd = lastUserCommand; + lastUserCommand = null; + try { + mi.postCommand(cmd); + } catch (MIException e) { + } + return true; + } + } + return false; } /** * Do any processing of before a running event. */ - void processRunningEvent() { - //Target target = getCSession().getCTarget(); - //target.clearState(); + boolean processRunningEvent(MIRunningEvent running) { + lastRunningEvent = running; + return true; } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java index 5318dd6f363..532200c8ca3 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java @@ -7,6 +7,7 @@ package org.eclipse.cdt.debug.mi.core.cdi; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.eclipse.cdt.debug.core.cdi.CDIException; @@ -41,6 +42,7 @@ public class SharedLibraryManager extends SessionObject implements ICDISharedLib List sharedList; boolean autoupdate; + boolean isDeferred; public SharedLibraryManager (Session session) { super(session); @@ -70,14 +72,22 @@ public class SharedLibraryManager extends SessionObject implements ICDISharedLib * @see org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryManager#update() */ public void update() throws CDIException { + Session session = (Session)getSession(); + MISession mi = session.getMISession(); + List eventList = updateState(); + MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]); + mi.fireEvents(events); + } + + public List updateState() throws CDIException { Session session = (Session)getSession(); ICDIConfiguration conf = session.getConfiguration(); if (!conf.supportsSharedLibrary()) { - return; // Bail out early; + return Collections.EMPTY_LIST; // Bail out early; } MIShared[] miLibs = getMIShareds(); - List eventList = new ArrayList(miLibs.length); + ArrayList eventList = new ArrayList(miLibs.length); for (int i = 0; i < miLibs.length; i++) { ICDISharedLibrary sharedlib = getSharedLibrary(miLibs[i].getName()); if (sharedlib != null) { @@ -107,9 +117,7 @@ public class SharedLibraryManager extends SessionObject implements ICDISharedLib eventList.add(new MISharedLibUnloadedEvent(oldlibs[i].getFileName())); } } - MISession mi = session.getMISession(); - MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]); - mi.fireEvents(events); + return eventList; } public boolean hasSharedLibChanged(ICDISharedLibrary lib, MIShared miLib) { @@ -133,6 +141,14 @@ public class SharedLibraryManager extends SessionObject implements ICDISharedLib return null; } + public void setDeferredBreakpoint (boolean set) { + isDeferred = set; + } + + public boolean isDeferredBreakpoint() { + return isDeferred; + } + /** * @see org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryManager#setSharedLibraryPaths(String[]) */ diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/event/ResumedEvent.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/event/ResumedEvent.java index a962213b301..60d6cbe0419 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/event/ResumedEvent.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/event/ResumedEvent.java @@ -58,13 +58,11 @@ public class ResumedEvent implements ICDIResumedEvent { cdiType = ICDIResumedEvent.STEP_INTO_INSTRUCTION; break; + case MIRunningEvent.RETURN: case MIRunningEvent.FINISH: cdiType = ICDIResumedEvent.STEP_RETURN; break; - //MIRunningEvent.UNTIL: - //cdiType = ICDIResumedEvent.STEP_UNTIL; - //break; } return cdiType; } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Breakpoint.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Breakpoint.java index f4ae937862d..9eb28458d57 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Breakpoint.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Breakpoint.java @@ -7,6 +7,7 @@ package org.eclipse.cdt.debug.mi.core.cdi.model; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.ICDICondition; import org.eclipse.cdt.debug.core.cdi.ICDILocation; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILocationBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.BreakpointManager; import org.eclipse.cdt.debug.mi.core.cdi.Condition; @@ -21,6 +22,17 @@ public class Breakpoint extends CObject implements ICDILocationBreakpoint { ICDICondition condition; MIBreakpoint miBreakpoint; BreakpointManager mgr; + int type; + String tid; + + public Breakpoint(BreakpointManager m, int kind, ICDILocation loc, ICDICondition cond, String threadId) { + super(m.getSession().getCurrentTarget()); + mgr = m; + type = kind; + location = loc; + condition = cond; + tid = threadId; + } public Breakpoint(BreakpointManager m, MIBreakpoint miBreak) { super(m.getSession().getCurrentTarget()); @@ -39,13 +51,17 @@ public class Breakpoint extends CObject implements ICDILocationBreakpoint { condition = null; } + public boolean isDeferred() { + return (miBreakpoint == null); + } + /** * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpoint#getCondition() */ public ICDICondition getCondition() throws CDIException { if (condition == null) { - condition = new Condition(miBreakpoint.getIgnoreCount(), - miBreakpoint.getCondition()); + if (miBreakpoint != null) + condition = new Condition(miBreakpoint.getIgnoreCount(), miBreakpoint.getCondition()); } return condition; } @@ -54,28 +70,36 @@ public class Breakpoint extends CObject implements ICDILocationBreakpoint { * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpoint#getThreadId() */ public String getThreadId() throws CDIException { - return miBreakpoint.getThreadId(); + if (miBreakpoint != null) + return miBreakpoint.getThreadId(); + return tid; } /** * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpoint#isEnabled() */ public boolean isEnabled() throws CDIException { - return miBreakpoint.isEnabled(); + if (miBreakpoint != null) + return miBreakpoint.isEnabled(); + return false; } /** * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpoint#isHardware() */ public boolean isHardware() { - return miBreakpoint.isHardware(); + if (miBreakpoint != null) + return miBreakpoint.isHardware(); + return (type == ICDIBreakpoint.HARDWARE); } /** * @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpoint#isTemporary() */ public boolean isTemporary() { - return miBreakpoint.isTemporary(); + if (miBreakpoint != null) + return miBreakpoint.isTemporary(); + return (type == ICDIBreakpoint.TEMPORARY); } /** @@ -104,11 +128,16 @@ public class Breakpoint extends CObject implements ICDILocationBreakpoint { */ public ICDILocation getLocation() throws CDIException { if (location == null) { - location = new Location (miBreakpoint.getFile(), + if (miBreakpoint != null) + location = new Location (miBreakpoint.getFile(), miBreakpoint.getFunction(), miBreakpoint.getLine(), miBreakpoint.getAddress()); } return location; } + + public void setLocation(ICDILocation loc) { + location = loc; + } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/StackFrame.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/StackFrame.java index 60a7e4945bd..be5872b325c 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/StackFrame.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/StackFrame.java @@ -58,7 +58,7 @@ public class StackFrame extends CObject implements ICDIStackFrame { level = l; } - MIFrame getMIFrame() { + public MIFrame getMIFrame() { return frame; } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Thread.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Thread.java index 20ad608bf8a..ecd3ba20c18 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Thread.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Thread.java @@ -40,7 +40,7 @@ public class Thread extends CObject implements ICDIThread { id = threadId; } - int getId() { + public int getId() { return id; } @@ -53,6 +53,13 @@ public class Thread extends CObject implements ICDIThread { return Integer.toString(id); } + public void updateState() { + try { + getCurrentStackFrame(); + } catch (CDIException e) { + } + } + public ICDIStackFrame getCurrentStackFrame() throws CDIException { if (currentFrame == null) { ICDIStackFrame[] frames = getStackFrames(0, 0); diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Watchpoint.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Watchpoint.java index c47ce15d4b0..7ab814166de 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Watchpoint.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/model/Watchpoint.java @@ -6,6 +6,7 @@ package org.eclipse.cdt.debug.mi.core.cdi.model; import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.ICDICondition; import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint; import org.eclipse.cdt.debug.mi.core.cdi.BreakpointManager; import org.eclipse.cdt.debug.mi.core.output.MIBreakpoint; @@ -14,6 +15,15 @@ import org.eclipse.cdt.debug.mi.core.output.MIBreakpoint; */ public class Watchpoint extends Breakpoint implements ICDIWatchpoint { + int watchType; + String what; + + public Watchpoint(BreakpointManager m, String expression, int type, int wType, ICDICondition cond) { + super(m, type, null, cond, ""); + watchType = wType; + what = expression; + } + public Watchpoint(BreakpointManager m, MIBreakpoint miBreak) { super(m, miBreak); } @@ -22,21 +32,30 @@ public class Watchpoint extends Breakpoint implements ICDIWatchpoint { * @see org.eclipse.cdt.debug.core.cdi.ICDIWatchpoint#getWatchExpression() */ public String getWatchExpression() throws CDIException { - return getMIBreakpoint().getWhat(); + MIBreakpoint miPoint = getMIBreakpoint(); + if (miPoint != null) + return getMIBreakpoint().getWhat(); + return what; } /** * @see org.eclipse.cdt.debug.core.cdi.ICDIWatchpoint#isReadType() */ public boolean isReadType() { - return getMIBreakpoint().isReadWatchpoint() || getMIBreakpoint().isAccessWatchpoint(); + MIBreakpoint miPoint = getMIBreakpoint(); + if (miPoint != null) + return getMIBreakpoint().isReadWatchpoint() || getMIBreakpoint().isAccessWatchpoint(); + return ((watchType & ICDIWatchpoint.READ) == ICDIWatchpoint.READ); } /** * @see org.eclipse.cdt.debug.core.cdi.ICDIWatchpoint#isWriteType() */ public boolean isWriteType() { - return getMIBreakpoint().isAccessWatchpoint() || getMIBreakpoint().isWriteWatchpoint(); + MIBreakpoint miPoint = getMIBreakpoint(); + if (miPoint != null) + return getMIBreakpoint().isAccessWatchpoint() || getMIBreakpoint().isWriteWatchpoint(); + return ((watchType & ICDIWatchpoint.WRITE) == ICDIWatchpoint.WRITE); } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/event/MIRunningEvent.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/event/MIRunningEvent.java index 442a0275be9..d5b5167d810 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/event/MIRunningEvent.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/event/MIRunningEvent.java @@ -20,6 +20,7 @@ public class MIRunningEvent extends MIEvent { public static final int STEPI = 4; public static final int FINISH = 5; public static final int UNTIL = 6; + public static final int RETURN = 7; int type; diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIBreakpoint.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIBreakpoint.java index ac8d674add1..3da45ea10c6 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIBreakpoint.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIBreakpoint.java @@ -72,6 +72,10 @@ public class MIBreakpoint { return number; } + public void setNumber(int num) { + number = num; + } + public String getType() { return type; } @@ -84,7 +88,7 @@ public class MIBreakpoint { return isWpt; } - public void setWatcpoint(boolean w) { + public void setWatchpoint(boolean w) { isWpt = w; }