/*
   * 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));
    }
  }
Exemple #9
0
 /** @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));
 }
Exemple #15
0
 /* (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));
    }
  }