From: Jan P. <jp...@us...> - 2006-12-12 20:47:50
|
Update of /cvsroot/e-p-i-c/org.epic.debug/src/org/epic/debug/db In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv4984/src/org/epic/debug/db Modified Files: PerlDB.java IPPosition.java StackFrame.java DebuggerInterface.java Log Message: - Refactored all code which referred to PathMapper. - Fixed bug [ 1614061 ] Unreliable breakpoints in Test::Unit::TestCase. Index: PerlDB.java =================================================================== RCS file: /cvsroot/e-p-i-c/org.epic.debug/src/org/epic/debug/db/PerlDB.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- PerlDB.java 12 Dec 2006 15:43:12 -0000 1.3 +++ PerlDB.java 12 Dec 2006 20:47:43 -0000 1.4 @@ -25,9 +25,6 @@ private final PerlDebugThread thread; - // Working directory of the "perl -d" process - private final IPath workingDir; - private final DebuggerInterface db; private final BreakpointMap activeBreakpoints; private final BreakpointMap pendingBreakpoints; @@ -52,9 +49,7 @@ public PerlDB(DebugTarget target) throws CoreException { - this.target = target; - - workingDir = target.getLocalWorkingDir(); + this.target = target; pendingBreakpoints = new BreakpointMap(); activeBreakpoints = new BreakpointMap(); @@ -80,7 +75,7 @@ final int ioPort, final int errorPort) throws DebugException { - if (db == null) return; + if (db == null) return; // This method is separate from the constructor because // callbacks to our DebugTarget may occur during its execution. @@ -92,6 +87,9 @@ redirectIO(ioHost, ioPort); redirectError(ioHost, errorPort); } + + if (target.getPathMapper().requiresEffectiveIncPath()) + target.getPathMapper().setEffectiveIncPath(getEffectiveIncPath()); PerlDebugPlugin.getPerlBreakPointManager().addDebugger(this); target.perlDBstarted(this); @@ -203,19 +201,6 @@ return target.getModelIdentifier(); } - public void getRemoteInc(List out) throws CoreException - { - try - { - String output = db.eval( - ";{foreach $t(@INC) {print $DB::OUT $t.\"\\n\";}}"); - - StringTokenizer s = new StringTokenizer(output, "\r\n"); - while (s.hasMoreTokens()) out.add(s.nextToken()); - } - catch (IOException e) { throwDebugException(e); } - } - public IThread[] getThreads() { return new IThread[] { thread }; @@ -276,9 +261,20 @@ try { - db.switchToFile(bp.getResourcePath()); - db.removeLineBreakpoint( - ((PerlLineBreakpoint) bp).getLineNumber()); + IPath dbPath = getDebuggerPath(bp.getResourcePath()); + + if (dbPath != null) + { + db.switchToFile(dbPath); + db.removeLineBreakpoint( + ((PerlLineBreakpoint) bp).getLineNumber()); + } + else + { + PerlDebugPlugin.errorDialog( + "Could not remove breakpoint. Reason: unknown " + + "remote mapping of local path " + bp.getResourcePath()); + } } catch (IOException e) { @@ -406,9 +402,6 @@ IPPosition endIP = maybeSkipStringEval(cmd); - if (startIP != null && !endIP.getPath().equals(startIP.getPath())) - insertPendingBreakpoints(); - updateStackFrames(); switch (cmd.getType()) @@ -422,7 +415,19 @@ : DebugEvent.STEP_END); break; case DebuggerInterface.CMD_RESUME: - fireDebugEvent(DebugEvent.SUSPEND, DebugEvent.BREAKPOINT); + if (isBreakPointReached()) + { + fireDebugEvent(DebugEvent.SUSPEND, DebugEvent.BREAKPOINT); + } + else + { + // We hit a "source file load" breakpoint. + // Insert pending line breakpoints and continue. + if (startIP != null && !endIP.getPath().equals(startIP.getPath())) + insertPendingBreakpoints(); + + resume(thread); + } break; } } @@ -445,8 +450,6 @@ return new DebuggerInterface( in, out, - workingDir, - target.getPathMapper(), commandListener); } catch (IOException e) @@ -467,12 +470,44 @@ DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event }); } + private IPath getDebuggerPath(IPath epicPath) + { + return target.getPathMapper().getDebuggerPath(epicPath); + } + + private List getEffectiveIncPath() throws DebugException + { + try + { + List ret = new ArrayList(); + String output = db.eval( + ";{foreach $t(@INC) {print $DB::OUT $t.\"\\n\";}}"); + + StringTokenizer s = new StringTokenizer(output, "\r\n"); + while (s.hasMoreTokens()) ret.add(new Path(s.nextToken())); + return ret; + } + catch (IOException e) { throwDebugException(e); return null; } + } + + private IPath getEpicPath(IPath dbPath) + { + return target.getPathMapper().getEpicPath(dbPath); + } + private boolean insertPendingBreakpoints() throws CoreException { try { - IPPosition pos = db.getCurrentIP(); - Set bps = pendingBreakpoints.getBreakpoints(pos.getPath()); + IPPosition pos = db.getCurrentIP(); + IPath epicPath = getEpicPath(pos.getPath()); + if (epicPath == null) + { + unresolvedDebuggerPath(pos.getPath()); + return false; + } + + Set bps = pendingBreakpoints.getBreakpoints(epicPath); if (bps.isEmpty()) return false; for (Iterator i = bps.iterator(); i.hasNext();) @@ -499,11 +534,17 @@ { IPPosition pos = db.getCurrentIP(); if (pos == null) return false; + + IPath epicPath = getEpicPath(pos.getPath()); + if (epicPath == null) + { + unresolvedDebuggerPath(pos.getPath()); + return false; + } // XXX: this breaks if new breakpoint types are installed! PerlLineBreakpoint bp = (PerlLineBreakpoint) - activeBreakpoints.getBreakpoint( - pos.getPath(), pos.getLine()); + activeBreakpoints.getBreakpoint(epicPath, pos.getLine()); return bp != null; } @@ -546,15 +587,20 @@ private boolean setBreakpoint(PerlBreakpoint bp, boolean isPending) throws IOException { - boolean success; + IPath dbPath = getDebuggerPath(bp.getResourcePath()); + if (dbPath == null) + { + unresolvedEpicPath(bp.getResourcePath()); + return false; + } if (!isPending) { - success = db.switchToFile(bp.getResourcePath()); + boolean success = db.switchToFile(dbPath); if (!success) { pendingBreakpoints.add(bp); - db.setLoadBreakpoint(bp.getResourcePath()); + db.setLoadBreakpoint(dbPath); return true; } } @@ -609,15 +655,19 @@ thread, currentIP.getPath(), currentIP.getLine(), + getEpicPath(currentIP.getPath()), db, previousTopFrame); for (int pos = 0; pos < matches.length; ++pos) { + IPath dbPath = new Path(matches[pos].toString(3)); + frames[pos + 1] = new StackFrame( thread, - db.getPathFor(matches[pos].toString(3)), + dbPath, Integer.parseInt(matches[pos].toString(4)), + getEpicPath(dbPath), matches[pos].toString(1), matches[pos].toString(2)); } @@ -629,4 +679,26 @@ throwDebugException(e); } } + + private void unresolvedDebuggerPath(IPath dbPath) + { + PerlDebugPlugin.log(new Status( + IStatus.WARNING, + PerlDebugPlugin.getUniqueIdentifier(), + IStatus.OK, + "Could not map remote path " + dbPath + + " to a local path. Some breakpoints may be ignored.", + null)); + } + + private void unresolvedEpicPath(IPath epicPath) + { + PerlDebugPlugin.log(new Status( + IStatus.WARNING, + PerlDebugPlugin.getUniqueIdentifier(), + IStatus.OK, + "Could not map local path " + epicPath + + " to a remote path. Some breakpoints may be ignored.", + null)); + } } \ No newline at end of file Index: StackFrame.java =================================================================== RCS file: /cvsroot/e-p-i-c/org.epic.debug/src/org/epic/debug/db/StackFrame.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- StackFrame.java 4 Dec 2006 17:15:03 -0000 1.2 +++ StackFrame.java 12 Dec 2006 20:47:43 -0000 1.3 @@ -39,11 +39,12 @@ private final PerlDebugThread thread; private final IPath path; + private final IPath localPath; private final int lineNumber; private final boolean topFrame; private final DebuggerInterface db; - private StackFrame previous; + private StackFrame previous; private PerlDebugVar[] actualVars; private PerlDebugVar[] displayedVars; @@ -61,6 +62,7 @@ PerlDebugThread thread, IPath path, int lineNumber, + IPath localPath, DebuggerInterface db, StackFrame previous) throws DebugException { @@ -68,6 +70,7 @@ this.thread = thread; this.path = path; + this.localPath = localPath; this.lineNumber = lineNumber; this.topFrame = true; this.db = db; @@ -82,6 +85,7 @@ PerlDebugThread thread, IPath path, int lineNumber, + IPath localPath, String returnType, String calledSub) throws DebugException { @@ -89,6 +93,7 @@ this.thread = thread; this.path = path; + this.localPath = localPath; this.lineNumber = lineNumber; this.topFrame = false; this.db = null; @@ -161,6 +166,19 @@ return thread.getDebugTarget(); } + /** + * @return path of the stack frame, valid in the file system + * of EPIC, or null if the path could not be resolved + */ + public IPath getLocalPath() + { + return localPath; + } + + /** + * @return path of the stack frame, valid in the file system + * of "perl -d"; this path is not necessarily local to EPIC + */ public IPath getPath() { return path; @@ -363,7 +381,8 @@ { try { - if (!db.isSuspended()) return new PerlDebugVar[] { + if (db.isDisposed()) return new PerlDebugVar[0]; + else if (!db.isSuspended()) return new PerlDebugVar[] { createSpecialVar( "Warning", "Variables are only available in suspended mode") }; Index: DebuggerInterface.java =================================================================== RCS file: /cvsroot/e-p-i-c/org.epic.debug/src/org/epic/debug/db/DebuggerInterface.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- DebuggerInterface.java 3 Dec 2006 12:27:07 -0000 1.3 +++ DebuggerInterface.java 12 Dec 2006 20:47:43 -0000 1.4 @@ -6,7 +6,6 @@ import org.eclipse.core.runtime.*; import org.eclipse.swt.widgets.Display; -import org.epic.debug.util.PathMapper; /** * A low-level interface to the "perl -d" debugger process. @@ -27,8 +26,6 @@ private final BufferedReader in; private final PrintWriter out; - private final IPath workingDir; - private final PathMapper pathMapper; private final IListener listener; private final Thread thread; @@ -53,14 +50,10 @@ public DebuggerInterface( BufferedReader in, PrintWriter out, - IPath workingDir, - PathMapper pathMapper, IListener listener) throws IOException { this.in = in; this.out = out; - this.workingDir = workingDir; - this.pathMapper = pathMapper; this.listener = listener; thread = new Thread(new Runnable() { @@ -114,6 +107,11 @@ return runSyncCommand(CMD_EXEC, code); } + public boolean isDisposed() + { + return disposed; + } + public boolean isSuspended() { return asyncCommand == null; @@ -140,10 +138,9 @@ if (temp != null) result = temp; } - int line = Integer.parseInt(result.toString(2)); - IPath file = getPathFor(result.toString(1)); - - return new IPPosition(file, line); + return new IPPosition( + new Path(result.toString(1)), + Integer.parseInt(result.toString(2))); } public String getPerlVersion() throws IOException @@ -213,9 +210,17 @@ return re.SET_LINE_BREAKPOINT.getAllMatches(output).length == 0; } + /** + * Sets a breakpoint that will be triggered on loading of a given + * source file. + * + * @param path + * path to the source file, specific to the debugger's + * environment + */ public void setLoadBreakpoint(IPath path) throws IOException { - runSyncCommand(CMD_EXEC, "b load " + getRelativePath(path)); + runSyncCommand(CMD_EXEC, "b load " + path); } public Command asyncStepInto() @@ -248,38 +253,23 @@ runSyncCommand(CMD_STEP_RETURN, null); } + /** + * Switches the debugging context to the given source file. + * This affects commands such as {@link #setLineBreakpoint(int)}. + * + * @param path + * path to the source file, specific to the debugger's + * environment + * @return true if the operation succeeded, + * false if the source file has not been loaded yet + */ public boolean switchToFile(IPath path) throws IOException { - String output = - runSyncCommand(CMD_EXEC, "f " + getRelativePath(path)); + String output = runSyncCommand(CMD_EXEC, "f " + path); return re.SWITCH_FILE_FAIL.getAllMatches(output).length == 0; } - public IPath getPathFor(String filename) - { - IPath file = new Path(filename); - - if (!file.isAbsolute()) - { - file = workingDir.append(file); - } - else if (pathMapper != null) - { - file = pathMapper.mapPath(file); - } - return file; - } - - private String getRelativePath(IPath fPath) - { - if (!workingDir.isPrefixOf(fPath)) return fPath.toString(); - - int match = workingDir.matchingFirstSegments(fPath); - IPath path = fPath.removeFirstSegments(match).makeRelative().setDevice(null); - return path.toString(); - } - private Command runAsyncCommand(int command, String code, boolean notifyOnFinish) { synchronized (LOCK) Index: IPPosition.java =================================================================== RCS file: /cvsroot/e-p-i-c/org.epic.debug/src/org/epic/debug/db/IPPosition.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- IPPosition.java 2 Dec 2006 16:04:46 -0000 1.1 +++ IPPosition.java 12 Dec 2006 20:47:43 -0000 1.2 @@ -31,6 +31,10 @@ return line; } + /** + * @return path of the stack frame, valid in the file system + * of "perl -d"; this path is not necessarily local to EPIC + */ public IPath getPath() { return path; |