@Override
  protected String evaluateExpression(String expression) {
    IFrameDMContext frame = getFrame();
    if (frame == null) {
      return null;
    }

    String sessionId = frame.getSessionId();
    DsfServicesTracker dsfServicesTracker =
        new DsfServicesTracker(DsfUIPlugin.getBundleContext(), sessionId);
    try {
      GetExpressionValueQuery query =
          new GetExpressionValueQuery(frame, expression, dsfServicesTracker);
      DsfSession session = DsfSession.getSession(sessionId);
      if (session != null) {
        session.getExecutor().execute(query);
        try {
          FormattedValueDMData data = query.get();
          if (data != null) return data.getFormattedValue();
        } catch (Exception e) {
        }
      }
    } finally {
      dsfServicesTracker.dispose();
    }
    return null;
  }
  /**
   * Initialize the members of the StartOrRestartProcessSequence_7_0 class. This step is mandatory
   * for the rest of the sequence to complete.
   */
  @Execute
  public void stepInitializeBaseSequence(RequestMonitor rm) {
    fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fContainerDmc.getSessionId());
    fCommandControl = fTracker.getService(IGDBControl.class);
    fCommandFactory = fTracker.getService(IMICommandControl.class).getCommandFactory();
    fProcService = fTracker.getService(IGDBProcesses.class);
    fBackend = fTracker.getService(IGDBBackend.class);

    if (fCommandControl == null || fCommandFactory == null || fProcService == null) {
      rm.setStatus(
          new Status(
              IStatus.ERROR,
              GdbPlugin.PLUGIN_ID,
              IDsfStatusConstants.INTERNAL_ERROR,
              "Cannot obtain service",
              null)); //$NON-NLS-1$
      rm.done();
      return;
    }

    fReverseService = fTracker.getService(IReverseRunControl.class);
    if (fReverseService != null) {
      // Although the option to use reverse debugging could be on, we only check
      // it if we actually have a reverse debugging service.  There is no point
      // in trying to handle reverse debugging if it is not available.
      fReverseEnabled =
          CDebugUtils.getAttribute(
              fAttributes,
              IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
              IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
    }

    rm.done();
  }
  /**
   * Initialize the members of the DebugNewProcessSequence class. This step is mandatory for the
   * rest of the sequence to complete.
   */
  @Execute
  public void stepInitializeBaseSequence(RequestMonitor rm) {
    fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fContext.getSessionId());
    fBackend = fTracker.getService(IGDBBackend.class);
    fCommandControl = fTracker.getService(IGDBControl.class);
    fCommandFactory = fTracker.getService(IMICommandControl.class).getCommandFactory();
    fProcService = fTracker.getService(IGDBProcesses.class);

    if (fBackend == null
        || fCommandControl == null
        || fCommandFactory == null
        || fProcService == null) {
      rm.setStatus(
          new Status(
              IStatus.ERROR,
              GdbPlugin.PLUGIN_ID,
              IDsfStatusConstants.INTERNAL_ERROR,
              "Cannot obtain service",
              null)); //$NON-NLS-1$
      rm.done();
      return;
    }

    // When we are starting to debug a new process, the container is the default process used by
    // GDB.
    // We don't have a pid yet, so we can simply create the container with the UNIQUE_GROUP_ID
    setContainerContext(
        fProcService.createContainerContextFromGroupId(
            fCommandControl.getContext(), MIProcesses.UNIQUE_GROUP_ID));

    rm.done();
  }
    @Override
    protected void execute(final DataRequestMonitor<FormattedValueDMData> rm) {
      DsfSession session = DsfSession.getSession(frame.getSessionId());
      IExpressions expressions = dsfServicesTracker.getService(IExpressions.class);
      if (expressions == null) {
        rm.setStatus(
            DsfUIPlugin.newErrorStatus(
                IDsfStatusConstants.REQUEST_FAILED, "No expression service", null)); // $NON-NLS-1$
        rm.done();
        return;
      }
      IExpressionDMContext expressionDMC = expressions.createExpression(frame, expression);
      FormattedValueDMContext formattedValueContext =
          expressions.getFormattedValueContext(expressionDMC, getHoverFormat());
      expressions.getFormattedExpressionValue(
          formattedValueContext,
          new DataRequestMonitor<FormattedValueDMData>(session.getExecutor(), rm) {
            @Override
            protected void handleSuccess() {
              rm.setData(getData());
              rm.done();
            }

            @Override
            protected void handleFailure() {
              rm.done();
            }
          });
    }
Example #5
0
 private void startNewProcess(
     ICommandControlDMContext controlDmc, String binaryPath, RequestMonitor rm) {
   IGDBProcesses procService = fTracker.getService(IGDBProcesses.class);
   procService.debugNewProcess(
       controlDmc,
       binaryPath,
       new HashMap<String, Object>(),
       new DataRequestMonitor<IDMContext>(fExecutor, rm));
 }
 /**
  * In case of a restart, we must mark reverse debugging as disabled because GDB has turned it off.
  * We may have to turn it back on after.
  */
 @Execute
 public void stepSetReverseOff(RequestMonitor rm) {
   if (fRestart) {
     GDBRunControl_7_0 reverseService = fTracker.getService(GDBRunControl_7_0.class);
     if (reverseService != null) {
       reverseService.setReverseModeEnabled(false);
     }
   }
   rm.done();
 }
 /**
  * Start tracking the breakpoints. Note that for remote debugging we should first connect to the
  * target.
  */
 @Execute
 public void stepStartTrackingBreakpoints(RequestMonitor rm) {
   if (fBackend.getSessionType() != SessionType.CORE) {
     MIBreakpointsManager bpmService = fTracker.getService(MIBreakpointsManager.class);
     IBreakpointsTargetDMContext bpTargetDmc =
         DMContexts.getAncestorOfType(getContainerContext(), IBreakpointsTargetDMContext.class);
     bpmService.startTrackingBreakpoints(bpTargetDmc, rm);
   } else {
     rm.done();
   }
 }
 /**
  * This method indicates if we should use the -exec-continue command instead of the -exec-run
  * command. This method can be overridden to allow for customization.
  */
 protected boolean useContinueCommand() {
   // Note that restart does not apply to remote sessions
   IGDBBackend backend = fTracker.getService(IGDBBackend.class);
   if (backend == null) {
     return false;
   }
   // When doing remote non-attach debugging, we use -exec-continue instead of -exec-run
   // For remote attach, if we get here it is that we are starting a new process
   // (multi-process), so we want to use -exec-run
   return backend.getSessionType() == SessionType.REMOTE && !backend.getIsAttachSession();
 }
  @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();
  }
  @Override
  @After
  public void doAfterTest() throws Exception {
    if (fSession != null) {
      fSession
          .getExecutor()
          .submit(() -> fSession.removeServiceEventListener(GDBConsoleBreakpointsTest.this))
          .get();
    }

    fBreakpointEvents.clear();
    if (fServicesTracker != null) {
      fServicesTracker.dispose();
      fServicesTracker = null;
    }

    super.doAfterTest();

    deleteAllPlatformBreakpoints();
  }
  @Override
  public void doAfterTest() throws Exception {
    super.doAfterTest();

    if (fServicesTracker != null) fServicesTracker.dispose();
  }
Example #12
0
  private void attachToProcesses(
      final ICommandControlDMContext controlDmc,
      IProcessExtendedInfo[] processes,
      final RequestMonitor rm) {

    // For a local attach, GDB can figure out the binary automatically,
    // so we don't need to prompt for it.
    final IGDBProcesses procService = fTracker.getService(IGDBProcesses.class);
    final IGDBBackend backend = fTracker.getService(IGDBBackend.class);

    if (procService != null && backend != null) {
      // Attach to each process in a sequential fashion.  We must do this
      // to be able to check if we are allowed to attach to the next process.
      // Attaching to all of them in parallel would assume that all attach are supported.

      // Create a list of all our processes so we can attach to one at a time.
      // We need to create a new list so that we can remove elements from it.
      final List<IProcessExtendedInfo> procList =
          new ArrayList<IProcessExtendedInfo>(Arrays.asList(processes));

      class AttachToProcessRequestMonitor extends ImmediateDataRequestMonitor<IDMContext> {
        public AttachToProcessRequestMonitor() {
          super();
        }

        @Override
        protected void handleCompleted() {
          if (!isSuccess()) {
            // Failed to attach to a process.  Just ignore it and move on.
          }

          // Check that we have a process to attach to
          if (procList.size() > 0) {

            // Check that we can actually attach to the process.
            // This is because some backends may not support multi-process.
            // If the backend does not support multi-process, we only attach to the first process.
            procService.isDebuggerAttachSupported(
                controlDmc,
                new ImmediateDataRequestMonitor<Boolean>() {
                  @Override
                  protected void handleCompleted() {
                    if (isSuccess() && getData()) {
                      // Can attach to process

                      // Remove process from list and attach to it.
                      IProcessExtendedInfo process = procList.remove(0);
                      String pidStr = Integer.toString(process.getPid());

                      if (backend.getSessionType() == SessionType.REMOTE) {
                        // For remote attach, we must set the binary first so we need to prompt the
                        // user.

                        // If this is the very first attach of a remote session, check if the user
                        // specified the binary in the launch.  If so, let's add it to our map to
                        // avoid having to prompt the user for that binary.
                        // This would be particularly annoying since we didn't use to have
                        // to do that before we supported multi-process.
                        // Must do this here to be in the executor
                        // Bug 350365
                        if (fProcessNameToBinaryMap.isEmpty()) {
                          IPath binaryPath = backend.getProgramPath();
                          if (binaryPath != null && !binaryPath.isEmpty()) {
                            fProcessNameToBinaryMap.put(
                                binaryPath.lastSegment(), binaryPath.toOSString());
                          }
                        }

                        // Because the prompt is a very long operation, we need to run outside the
                        // executor, so we don't lock it.
                        // Bug 344892
                        IPath processPath = new Path(process.getName());
                        String processShortName = processPath.lastSegment();
                        new PromptAndAttachToProcessJob(
                                pidStr,
                                LaunchUIMessages.getString("ProcessPrompterDialog.TitlePrefix")
                                    + process.getName(), // $NON-NLS-1$
                                processShortName,
                                new AttachToProcessRequestMonitor())
                            .schedule();
                      } else {
                        // For a local attach, we can attach directly without looking for the binary
                        // since GDB will figure it out by itself
                        IProcessDMContext procDmc =
                            procService.createProcessContext(controlDmc, pidStr);
                        procService.attachDebuggerToProcess(
                            procDmc, null, new AttachToProcessRequestMonitor());
                      }
                    } else {
                      // Not allowed to attach to another process.  Just stop.
                      rm.done();
                    }
                  }
                });
          } else {
            // No other process to attach to
            rm.done();
          }
        }
      };

      // Trigger the first attach.
      new AttachToProcessRequestMonitor().done();

    } else {
      rm.done(
          new Status(
              IStatus.ERROR,
              GdbUIPlugin.PLUGIN_ID,
              IDsfStatusConstants.INTERNAL_ERROR,
              "Cannot find service",
              null)); //$NON-NLS-1$
    }
  }
Example #13
0
 public void dispose() {
   fTracker.dispose();
 }
  /** Before running the program, we must create its console for IO. */
  @Execute
  public void stepCreateConsole(final RequestMonitor rm) {
    Process inferiorProcess;
    if (fPty == null) {
      inferiorProcess = new MIInferiorProcess(fContainerDmc, fBackend.getMIOutputStream());
    } else {
      inferiorProcess = new MIInferiorProcess(fContainerDmc, fPty);
    }

    final Process inferior = inferiorProcess;
    final ILaunch launch = (ILaunch) getContainerContext().getAdapter(ILaunch.class);

    // This is the groupId of the new process that will be started, even in the
    // case of a restart.
    final String groupId = ((IMIContainerDMContext) getContainerContext()).getGroupId();

    // For multi-process, we cannot simply use the name given by the backend service
    // because we may not be starting that process, but another one.
    // Instead, we can look in the attributes for the binary name, which we stored
    // there for this case, specifically.
    // Bug 342351
    IGDBBackend backend = fTracker.getService(IGDBBackend.class);
    String defaultPathName = backend.getProgramPath().lastSegment();
    if (defaultPathName == null) {
      defaultPathName = ""; // $NON-NLS-1$
    }
    String progPathName =
        CDebugUtils.getAttribute(
            fAttributes, ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, defaultPathName);
    final String pathLabel = new Path(progPathName).lastSegment();

    // Add the inferior to the launch.
    // This cannot be done on the executor or things deadlock.
    DebugPlugin.getDefault()
        .asyncExec(
            new Runnable() {
              @Override
              public void run() {
                String label = pathLabel;

                if (fRestart) {
                  // For a restart, remove the old inferior
                  IProcess[] launchProcesses = launch.getProcesses();
                  for (IProcess process : launchProcesses) {
                    if (process instanceof InferiorRuntimeProcess) {
                      String groupAttribute =
                          process.getAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR);

                      // if the groupAttribute is not set in the process we know we are dealing
                      // with single process debugging so the one process is the one we want.
                      // If the groupAttribute is set, then we must make sure it is the proper
                      // inferior
                      if (groupAttribute == null
                          || groupAttribute.equals(MIProcesses.UNIQUE_GROUP_ID)
                          || groupAttribute.equals(groupId)) {
                        launch.removeProcess(process);
                        // Use the exact same label as before
                        label = process.getLabel();
                        break;
                      }
                    }
                  }
                }

                // Add the inferior
                InferiorRuntimeProcess runtimeInferior =
                    new InferiorRuntimeProcess(launch, inferior, label, null);
                runtimeInferior.setAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR, groupId);
                launch.addProcess(runtimeInferior);

                rm.done();
              }
            });
  }
 /**
  * Cleanup now that the sequence has been run.
  *
  * @since 4.0
  */
 @Execute
 public void stepCleanupBaseSequence(RequestMonitor rm) {
   fTracker.dispose();
   fTracker = null;
   rm.done();
 }
Example #16
0
 @After
 public void tearDown() {
   fServicesTracker.dispose();
   fRegService = null;
 }
  /**
   * If we are dealing with a postmortem session, connect to the core/trace file.
   *
   * @since 4.0
   */
  @Execute
  public void stepSpecifyCoreFile(final RequestMonitor rm) {
    // If we are dealing with a postmortem session, it is now time to connect
    // to the core/trace file.  We have to do this step after
    // we have specified the executable, so we have to do it here.
    // It is safe to do it here because a postmortem session does not support
    // multi-process so this step will not be executed more than once.
    // Bug 338730
    if (fBackend.getSessionType() == SessionType.CORE) {
      String coreFile =
          CDebugUtils.getAttribute(
              fAttributes, ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, ""); // $NON-NLS-1$
      final String coreType =
          CDebugUtils.getAttribute(
              fAttributes,
              IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_POST_MORTEM_TYPE,
              IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TYPE_DEFAULT);

      if (coreFile.length() == 0) {
        new PromptForCoreJob(
                "Prompt for post mortem file", //$NON-NLS-1$
                new DataRequestMonitor<String>(getExecutor(), rm) {
                  @Override
                  protected void handleCancel() {
                    rm.cancel();
                    rm.done();
                  }

                  @Override
                  protected void handleSuccess() {
                    String newCoreFile = getData();
                    if (newCoreFile == null || newCoreFile.length() == 0) {
                      rm.setStatus(
                          new Status(
                              IStatus.ERROR,
                              GdbPlugin.PLUGIN_ID,
                              -1,
                              "Cannot get post mortem file path",
                              null)); //$NON-NLS-1$
                      rm.done();
                    } else {
                      if (coreType.equals(
                          IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) {
                        fCommandControl.queueCommand(
                            fCommandFactory.createMITargetSelectCore(
                                fCommandControl.getContext(), newCoreFile),
                            new DataRequestMonitor<MIInfo>(getExecutor(), rm));
                      } else if (coreType.equals(
                          IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE)) {
                        IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
                        if (traceControl != null) {
                          ITraceTargetDMContext targetDmc =
                              DMContexts.getAncestorOfType(
                                  fCommandControl.getContext(), ITraceTargetDMContext.class);
                          traceControl.loadTraceData(targetDmc, newCoreFile, rm);
                        } else {
                          rm.setStatus(
                              new Status(
                                  IStatus.ERROR,
                                  GdbPlugin.PLUGIN_ID,
                                  -1,
                                  "Tracing not supported",
                                  null));
                          rm.done();
                        }
                      } else {
                        rm.setStatus(
                            new Status(
                                IStatus.ERROR,
                                GdbPlugin.PLUGIN_ID,
                                -1,
                                "Invalid post-mortem type",
                                null));
                        rm.done();
                      }
                    }
                  }
                })
            .schedule();
      } else {
        if (coreType.equals(IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE)) {
          fCommandControl.queueCommand(
              fCommandFactory.createMITargetSelectCore(fCommandControl.getContext(), coreFile),
              new DataRequestMonitor<MIInfo>(getExecutor(), rm));
        } else if (coreType.equals(
            IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_TRACE_FILE)) {
          IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
          if (traceControl != null) {
            ITraceTargetDMContext targetDmc =
                DMContexts.getAncestorOfType(
                    fCommandControl.getContext(), ITraceTargetDMContext.class);
            traceControl.loadTraceData(targetDmc, coreFile, rm);
          } else {
            rm.setStatus(
                new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Tracing not supported", null));
            rm.done();
          }
        } else {
          rm.setStatus(
              new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Invalid post-mortem type", null));
          rm.done();
        }
      }
    } else {
      rm.done();
    }
  }
 /**
  * Rollback method for {@link #stepInitializeBaseSequence()}
  *
  * @since 4.0
  */
 @RollBack("stepInitializeBaseSequence")
 public void rollBackInitializeBaseSequence(RequestMonitor rm) {
   if (fTracker != null) fTracker.dispose();
   fTracker = null;
   rm.done();
 }