/* * Expands and returns the location attribute of the given launch configuration. The location is verified to point * to an existing file, in the local file system. * * @param configuration launch configuration * * @return an absolute path to a file in the local file system * * @throws CoreException if unable to retrieve the associated launch configuration attribute, if unable to resolve * any variables, or if the resolved location does not point to an existing file in the local file system */ public static IPath[] getLocation(ILaunchConfiguration configuration, IPythonNature nature) throws CoreException { String locationsStr = configuration.getAttribute(Constants.ATTR_ALTERNATE_LOCATION, (String) null); if (locationsStr == null) { locationsStr = configuration.getAttribute(Constants.ATTR_LOCATION, (String) null); } if (locationsStr == null) { throw new CoreException( PydevDebugPlugin.makeStatus(IStatus.ERROR, "Unable to get location for run", null)); } List<String> locations = StringUtils.splitAndRemoveEmptyTrimmed(locationsStr, '|'); Path[] ret = new Path[locations.size()]; int i = 0; for (String location : locations) { String expandedLocation = getStringSubstitution(nature).performStringSubstitution(location); if (expandedLocation == null || expandedLocation.length() == 0) { throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "Unable to get expanded location for run", null)); } else { ret[i] = new Path(expandedLocation); } i++; } return ret; }
/** ThreadRun event processing */ private void processThreadRun(String payload) { try { Tuple<String, String> threadIdAndReason = getThreadIdAndReason(payload); int resumeReason = DebugEvent.UNSPECIFIED; try { int raw_reason = Integer.parseInt(threadIdAndReason.o2); if (raw_reason == AbstractDebuggerCommand.CMD_STEP_OVER) resumeReason = DebugEvent.STEP_OVER; else if (raw_reason == AbstractDebuggerCommand.CMD_STEP_RETURN) resumeReason = DebugEvent.STEP_RETURN; else if (raw_reason == AbstractDebuggerCommand.CMD_STEP_INTO) resumeReason = DebugEvent.STEP_INTO; else if (raw_reason == AbstractDebuggerCommand.CMD_RUN_TO_LINE) resumeReason = DebugEvent.UNSPECIFIED; else if (raw_reason == AbstractDebuggerCommand.CMD_SET_NEXT_STATEMENT) resumeReason = DebugEvent.UNSPECIFIED; else if (raw_reason == AbstractDebuggerCommand.CMD_THREAD_RUN) resumeReason = DebugEvent.CLIENT_REQUEST; else { PydevDebugPlugin.log(IStatus.ERROR, "Unexpected resume reason code", null); resumeReason = DebugEvent.UNSPECIFIED; } } catch (NumberFormatException e) { // expected, when pydevd reports "None" resumeReason = DebugEvent.UNSPECIFIED; } String threadID = threadIdAndReason.o1; PyThread t = (PyThread) findThreadByID(threadID); if (t != null) { t.setSuspended(false, null); fireEvent(new DebugEvent(t, DebugEvent.RESUME, resumeReason)); } else { FastStringBuffer buf = new FastStringBuffer(); for (PyThread thread : threads) { if (buf.length() > 0) { buf.append(", "); } buf.append("id: " + thread.getId()); } String msg = "Unable to find thread: " + threadID + " available: " + buf; PydevDebugPlugin.log(IStatus.ERROR, msg, new RuntimeException(msg)); } } catch (CoreException e1) { Log.log(e1); } }
/** * Launches the python process. * * <p>Modelled after Ant & Java runners see WorkbenchLaunchConfigurationDelegate::launch */ public void launch( ILaunchConfiguration conf, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { if (monitor == null) { monitor = new NullProgressMonitor(); } monitor.beginTask("Preparing configuration", 3); try { PythonRunnerConfig runConfig = new PythonRunnerConfig(conf, mode, getRunnerConfigRun(conf, mode, launch)); monitor.worked(1); try { PythonRunner.run(runConfig, launch, monitor); } catch (IOException e) { Log.log(e); finishLaunchWithError(launch); throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "Unexpected IO Exception in Pydev debugger", null)); } } catch (final InvalidRunException e) { handleError(launch, e); } catch (final MisconfigurationException e) { handleError(launch, e); } }
/** * Gets the project that should be used for a launch configuration * * @param conf the launch configuration from where the project should be gotten * @return the related IProject * @throws CoreException */ public static IProject getProjectFromConfiguration(ILaunchConfiguration conf) throws CoreException { String projName = conf.getAttribute(Constants.ATTR_PROJECT, ""); if (projName == null || projName.length() == 0) { throw new CoreException( PydevDebugPlugin.makeStatus(IStatus.ERROR, "Unable to get project for the run", null)); } IWorkspace w = ResourcesPlugin.getWorkspace(); IProject p = w.getRoot().getProject(projName); if (p == null || !p.exists()) { // Ok, we could not find it out throw new CoreException( PydevDebugPlugin.makeStatus(IStatus.ERROR, "Could not get project: " + projName, null)); } return p; }
/** * @param resource may be the file open in the editor or the workspace root (if it is an external * file) * @param document is the document opened in the editor * @param externalFileEditorInput is not-null if this is an external file * @param info is the vertical ruler info (only used if this is not an external file) * @param onlyIncludeLastLineActivity if only the markers that are in the last mouse-click should * be included * @return the markers that correspond to the markers from the current editor. */ @SuppressWarnings({"unchecked", "rawtypes"}) public static List<Tuple<IMarker, IBreakpoint>> getMarkersAndBreakpointsFromEditorResource( IResource resource, IDocument document, IEditorInput externalFileEditorInput, int lastLineActivity, boolean onlyIncludeLastLineActivity, IAnnotationModel annotationModel) { List<Tuple<IMarker, IBreakpoint>> breakpoints = new ArrayList<Tuple<IMarker, IBreakpoint>>(); try { List<IMarker> markers = new ArrayList<IMarker>(); boolean isExternalFile = false; markers.addAll( Arrays.asList( resource.findMarkers(PyBreakpoint.PY_BREAK_MARKER, true, IResource.DEPTH_INFINITE))); markers.addAll( Arrays.asList( resource.findMarkers( PyBreakpoint.PY_CONDITIONAL_BREAK_MARKER, true, IResource.DEPTH_INFINITE))); if (!(resource instanceof IFile)) { // it was created from an external file isExternalFile = true; } IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager(); for (IMarker marker : markers) { if (marker == null) { continue; } IBreakpoint breakpoint = breakpointManager.getBreakpoint(marker); if (breakpoint != null && breakpointManager.isRegistered(breakpoint)) { Position pos = PyMarkerUtils.getMarkerPosition(document, marker, annotationModel); if (!isExternalFile) { if (!onlyIncludeLastLineActivity) { breakpoints.add(new Tuple(marker, breakpoint)); } else if (includesRulerLine(pos, document, lastLineActivity)) { breakpoints.add(new Tuple(marker, breakpoint)); } } else { if (isInSameExternalEditor(marker, externalFileEditorInput)) { if (!onlyIncludeLastLineActivity) { breakpoints.add(new Tuple(marker, breakpoint)); } else if (includesRulerLine(pos, document, lastLineActivity)) { breakpoints.add(new Tuple(marker, breakpoint)); } } } } } } catch (CoreException x) { PydevDebugPlugin.log(IStatus.ERROR, "Unexpected getMarkers error (recovered properly)", x); } return breakpoints; }
/** * @param payload a string in the format: thread_id\tresume_reason E.g.: pid3720_zad_seq1\t108 * @return a tuple with the thread id and the reason it stopped. * @throws CoreException */ public static Tuple<String, String> getThreadIdAndReason(String payload) throws CoreException { List<String> split = StringUtils.split(payload.trim(), '\t'); if (split.size() != 2) { String msg = "Unexpected threadRun payload " + payload + "(unable to match)"; throw new CoreException( PydevDebugPlugin.makeStatus(IStatus.ERROR, msg, new RuntimeException(msg))); } return new Tuple<String, String>(split.get(0), split.get(1)); }
/** * Expands and returns the python interpreter attribute of the given launch configuration. The * interpreter path is verified to point to an existing file in the local file system. * * @param configuration launch configuration * @return an absolute path to the interpreter in the local file system * @throws CoreException if unable to retrieve the associated launch configuration attribute, if * unable to resolve any variables, or if the resolved location does not point to an existing * directory in the local file system * @throws InvalidRunException */ private IPath getInterpreter( IInterpreterInfo location, ILaunchConfiguration configuration, IPythonNature nature) throws CoreException, InvalidRunException { if (location == null) { throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "Unable to get python interpreter for run", null)); } else { String expandedLocation = getStringSubstitution(nature).performStringSubstitution(location.getExecutableOrJar()); if (expandedLocation == null || expandedLocation.length() == 0) { throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "Unable to get expanded interpreter for run", null)); } else { return new Path(expandedLocation); } } }
private void processThreadSuspended(String payload) { Object[] threadNstack; try { threadNstack = XMLUtils.XMLToStack(this, payload); } catch (CoreException e) { PydevDebugPlugin.errorDialog("Error reading ThreadSuspended", e); return; } PyThread t = (PyThread) threadNstack[0]; int reason = DebugEvent.UNSPECIFIED; String stopReason = (String) threadNstack[1]; if (stopReason != null) { int stopReason_i = Integer.parseInt(stopReason); if (stopReason_i == AbstractDebuggerCommand.CMD_STEP_OVER || stopReason_i == AbstractDebuggerCommand.CMD_STEP_INTO || stopReason_i == AbstractDebuggerCommand.CMD_STEP_RETURN || stopReason_i == AbstractDebuggerCommand.CMD_RUN_TO_LINE || stopReason_i == AbstractDebuggerCommand.CMD_SET_NEXT_STATEMENT) { reason = DebugEvent.STEP_END; } else if (stopReason_i == AbstractDebuggerCommand.CMD_THREAD_SUSPEND) { reason = DebugEvent.CLIENT_REQUEST; } else if (stopReason_i == AbstractDebuggerCommand.CMD_SET_BREAK) { reason = DebugEvent.BREAKPOINT; } else { PydevDebugPlugin.log(IStatus.ERROR, "Unexpected reason for suspension", null); reason = DebugEvent.UNSPECIFIED; } } if (t != null) { modificationChecker.onlyLeaveThreads((PyThread[]) this.threads); IStackFrame stackFrame[] = (IStackFrame[]) threadNstack[2]; t.setSuspended(true, stackFrame); fireEvent(new DebugEvent(t, DebugEvent.SUSPEND, reason)); } }
/** @return the initial commands set in the preferences */ @Override public String getInitialCommands() { String str = PydevDebugPlugin.getDefault() .getPreferenceStore() .getString(PydevConsoleConstants.INITIAL_INTERPRETER_CMDS); if (additionalInitialComands != null) { str += additionalInitialComands; } return str; }
/** * Can be used to extract the pythonpath used from a given configuration. * * @param conf the configuration from where we want to get the pythonpath * @return a string with the pythonpath used (with | as a separator) * @throws CoreException * @throws InvalidRunException * @throws MisconfigurationException */ public static String getPythonpathFromConfiguration( ILaunchConfiguration conf, IInterpreterManager manager) throws CoreException, InvalidRunException, MisconfigurationException { IProject p = getProjectFromConfiguration(conf); PythonNature pythonNature = PythonNature.getPythonNature(p); if (pythonNature == null) { throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "Project should have a python nature: " + p.getName(), null)); } IInterpreterInfo l = getInterpreterLocation(conf, pythonNature, manager); return SimpleRunner.makePythonPathEnvString(pythonNature, l, manager); }
/** * When a command that originates from daemon is received, this routine processes it. The * responses to commands originating from here are processed by commands themselves */ public void processCommand(String sCmdCode, String sSeqCode, String payload) { if (DEBUG) { System.out.println( "process command:" + sCmdCode + "\tseq:" + sSeqCode + "\tpayload:" + payload + "\n\n"); } try { int cmdCode = Integer.parseInt(sCmdCode); if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_CREATED) { processThreadCreated(payload); } else if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_KILL) { processThreadKilled(payload); } else if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_SUSPEND) { processThreadSuspended(payload); } else if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_RUN) { processThreadRun(payload); } else { PydevDebugPlugin.log( IStatus.WARNING, "Unexpected debugger command:" + sCmdCode + "\nseq:" + sSeqCode + "\npayload:" + payload, null); } } catch (Exception e) { PydevDebugPlugin.log( IStatus.ERROR, "Error processing: " + sCmdCode + "\npayload: " + payload, e); } }
/** * Adds the breakpoints associated with a container. * * @param container the container we're interested in (usually workspace root) */ private void addBreakpointsFor(IContainer container) { try { IMarker[] markers = container.findMarkers(PyBreakpoint.PY_BREAK_MARKER, true, IResource.DEPTH_INFINITE); IMarker[] condMarkers = container.findMarkers( PyBreakpoint.PY_CONDITIONAL_BREAK_MARKER, true, IResource.DEPTH_INFINITE); IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager(); for (IMarker marker : markers) { PyBreakpoint brk = (PyBreakpoint) breakpointManager.getBreakpoint(marker); breakpointAdded(brk); } for (IMarker marker : condMarkers) { PyBreakpoint brk = (PyBreakpoint) breakpointManager.getBreakpoint(marker); breakpointAdded(brk); } } catch (Throwable t) { PydevDebugPlugin.errorDialog("Error setting breakpoints", t); } }
/** * Expands and returns the working directory attribute of the given launch configuration. Returns * <code>null</code> if a working directory is not specified. If specified, the working is * verified to point to an existing directory in the local file system. * * @param configuration launch configuration * @return an absolute path to a directory in the local file system, or <code>null</code> if * unspecified * @throws CoreException if unable to retrieve the associated launch configuration attribute, if * unable to resolve any variables, or if the resolved location does not point to an existing * directory in the local file system */ public static IPath getWorkingDirectory(ILaunchConfiguration configuration, IPythonNature nature) throws CoreException { IProject project = nature.getProject(); String location = configuration.getAttribute( Constants.ATTR_WORKING_DIRECTORY, "${project_loc:/" + project.getName() + "}"); if (location != null) { String expandedLocation = getStringSubstitution(nature).performStringSubstitution(location); if (expandedLocation.length() > 0) { File path = new File(expandedLocation); if (path.isDirectory()) { return new Path(expandedLocation); } throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "Unable to get working location for the run \n(the location: '" + expandedLocation + "' is not a valid directory).", null)); } } return null; }
/** * Request that pydevconsole connect (with pydevd) to the specified port * * @param localPort port for pydevd to connect to. * @throws Exception if connection fails */ public void connectToDebugger(int localPort) throws Exception { if (waitingForInput) { throw new Exception("Can't connect debugger now, waiting for input"); } Object result = client.execute("connectToDebugger", new Object[] {localPort}); Exception exception = null; if (result instanceof Object[]) { Object[] resultarray = (Object[]) result; if (resultarray.length == 1) { if ("connect complete".equals(resultarray[0])) { return; } if (resultarray[0] instanceof String) { exception = new Exception((String) resultarray[0]); } if (resultarray[0] instanceof Exception) { exception = (Exception) resultarray[0]; } } } throw new CoreException( PydevDebugPlugin.makeStatus( IStatus.ERROR, "pydevconsole failed to execute connectToDebugger", exception)); }
/* (non-Javadoc) * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() */ public Image getImage() { return PydevDebugPlugin.getImageCache().get(Constants.ARGUMENTS_ICON); }
/** * @return * @throws CoreException */ public static String getCoverageScript() throws CoreException { return FileUtils.getFileAbsolutePath( PydevDebugPlugin.getScriptWithinPySrc("pydev_coverage.py")); }
public static String getRunFilesScript() throws CoreException { return FileUtils.getFileAbsolutePath(PydevDebugPlugin.getScriptWithinPySrc("runfiles.py")); }
/** Add it to the list of threads */ private void processThreadCreated(String payload) { PyThread[] newThreads; try { newThreads = XMLUtils.ThreadsFromXML(this, payload); } catch (CoreException e) { PydevDebugPlugin.errorDialog("Error in processThreadCreated", e); return; } // Hide Pydevd threads if requested if (PydevDebugPlugin.getDefault() .getPreferenceStore() .getBoolean(PydevDebugPreferencesInitializer.HIDE_PYDEVD_THREADS)) { int removeThisMany = 0; for (int i = 0; i < newThreads.length; i++) { if (((PyThread) newThreads[i]).isPydevThread()) { removeThisMany++; } } if (removeThisMany > 0) { int newSize = newThreads.length - removeThisMany; if (newSize == 0) { // no threads to add return; } else { PyThread[] newnewThreads = new PyThread[newSize]; int i = 0; for (PyThread newThread : newThreads) { if (!((PyThread) newThread).isPydevThread()) { newnewThreads[i] = newThread; i += 1; } } newThreads = newnewThreads; } } } // add threads to the thread list, and fire event if (threads == null) { threads = newThreads; } else { PyThread[] combined = new PyThread[threads.length + newThreads.length]; int i = 0; for (i = 0; i < threads.length; i++) { combined[i] = threads[i]; } for (int j = 0; j < newThreads.length; i++, j++) { combined[i] = newThreads[j]; } threads = combined; } // Now notify debugger that new threads were added for (int i = 0; i < newThreads.length; i++) { fireEvent(new DebugEvent(newThreads[i], DebugEvent.CREATE)); } }