@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(); } }); }
@Override public IStatus runInUIThread(IProgressMonitor monitor) { final Status NO_PID_STATUS = new Status( IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, -1, LaunchMessages.getString( "LocalAttachLaunchDelegate.No_Process_ID_selected"), //$NON-NLS-1$ null); try { PrompterInfo info = new PrompterInfo(fNewProcessSupported, fProcessList); Object result = new ProcessPrompter().handleStatus(null, info); if (result == null) { fRequestMonitor.cancel(); } else if (result instanceof IProcessExtendedInfo[] || result instanceof String) { fRequestMonitor.setData(result); } else { fRequestMonitor.setStatus(NO_PID_STATUS); } } catch (CoreException e) { fRequestMonitor.setStatus(NO_PID_STATUS); } fRequestMonitor.done(); return Status.OK_STATUS; }
@Override public void getCPUs( final IHardwareTargetDMContext dmc, final DataRequestMonitor<ICPUDMContext[]> rm) { if (!fSessionInitializationComplete) { // We are not ready to answer yet rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Debug session not initialized yet", null)); //$NON-NLS-1$ return; } if (supportsProcPseudoFS()) { fFetchCPUInfoCache.execute( new MIMetaGetCPUInfo(fCommandControl.getContext()), new ImmediateDataRequestMonitor<MIMetaGetCPUInfoInfo>() { @Override protected void handleSuccess() { rm.done(parseCoresInfoForCPUs(dmc, getData().getInfo())); } }); } else { // No way to know the CPUs for Windows session. rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$ } }
/* (non-Javadoc) * @see org.eclipse.cdt.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) */ public void getMixedInstructions( IDisassemblyDMContext context, String filename, int linenum, int lines, final DataRequestMonitor<IMixedInstruction[]> drm) { // Validate the context if (context == null) { drm.setStatus( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); drm.done(); return; } // Go for it fConnection.queueCommand( fCommandFactory.createMIDataDisassemble(context, filename, linenum, lines, true), new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) { @Override protected void handleSuccess() { IMixedInstruction[] result = getData().getMIMixedCode(); drm.setData(result); drm.done(); } }); }
/* (non-Javadoc) * @see org.eclipse.cdt.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) */ public void getInstructions( IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, final DataRequestMonitor<IInstruction[]> drm) { // Validate the context if (context == null) { drm.setStatus( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); drm.done(); return; } // Go for it String start = (startAddress != null) ? startAddress.toString() : "$pc"; // $NON-NLS-1$ String end = (endAddress != null) ? endAddress.toString() : "$pc + 100"; // $NON-NLS-1$ fConnection.queueCommand( fCommandFactory.createMIDataDisassemble(context, start, end, false), new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) { @Override protected void handleSuccess() { IInstruction[] result = getData().getMIAssemblyCode(); drm.setData(result); drm.done(); } }); }
@Override public void getExecutionData(IDMContext dmc, DataRequestMonitor<IDMData> rm) { if (dmc instanceof ICoreDMContext) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Not done yet", null)); //$NON-NLS-1$ } else if (dmc instanceof ICPUDMContext) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Not done yet", null)); //$NON-NLS-1$ } else { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$ } }
private void processCountRequest(CountRequest request) { @SuppressWarnings("unchecked") // Suppress warning about lost type info. DataRequestMonitor<Integer> rm = (DataRequestMonitor<Integer>) request.fRequestMonitor; rm.setData(fCount); rm.done(); }
/** * For a given "load info" request, this method processes the load obtained from the proc stat * parser and creates/sends the response. * * @param context * @param rm * @param loads */ private void processLoads( final IDMContext context, final DataRequestMonitor<ILoadInfo> rm, final ProcStatCoreLoads loads) { // problem with fetching load info if (loads == null) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info", null)); //$NON-NLS-1$ return; } // core context? if (context instanceof ICoreDMContext) { String coreId = ((ICoreDMContext) context).getId(); // Integer precision sufficient for our purpose float load = loads.getLoad(coreId); rm.done(new GDBLoadInfo(Integer.toString((int) load))); } else if (context instanceof ICPUDMContext) { // get the list of cores in that CPU getCores( context, new ImmediateDataRequestMonitor<ICoreDMContext[]>() { @Override protected void handleCompleted() { ICoreDMContext[] coreContexts = getData(); if (!isSuccess() || coreContexts == null || coreContexts.length < 1) { // Unable to get any core data rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ return; } int i = 0; float load = 0.0f; // compute the average load of cores in that CPU for (ICoreDMContext coreCtx : coreContexts) { String coreId = coreCtx.getId(); load += loads.getLoad(coreId); i++; } load /= i; rm.done(new GDBLoadInfo(Integer.toString((int) load))); } }); } }
@Override public void getValue(int index, DataRequestMonitor<Integer> rm) { if (!fShutdown.get()) { fQueue.add(new ItemRequest(index, rm)); } else { rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); rm.done(); } }
private void processItemRequest(ItemRequest request) { @SuppressWarnings("unchecked") // Suppress warning about lost type info. DataRequestMonitor<Integer> rm = (DataRequestMonitor<Integer>) request.fRequestMonitor; if (fChangedValues.containsKey(request.fIndex)) { rm.setData(fChangedValues.get(request.fIndex)); } else { rm.setData(request.fIndex); } rm.done(); }
/** Start executing the program. */ @Execute public void stepStartExecution(final RequestMonitor rm) { if (fBackend.getSessionType() != SessionType.CORE) { // Overwrite the program name to use the binary name that was specified. // This is important for multi-process // Bug 342351 fAttributes.put(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, fBinaryName); fProcService.start( getContainerContext(), fAttributes, new DataRequestMonitor<IContainerDMContext>(ImmediateExecutor.getInstance(), rm) { @Override protected void handleSuccess() { assert getData() instanceof IMIContainerDMContext; // Set the container that we created setContainerContext( DMContexts.getAncestorOfType(getData(), IMIContainerDMContext.class)); fDataRequestMonitor.setData(getContainerContext()); // Don't call fDataRequestMonitor.done(), the sequence will // automatically do that when it completes; rm.done(); } }); } else { fDataRequestMonitor.setData(getContainerContext()); rm.done(); } }
/** @since 4.2 */ @Override public void getResourceClasses(IDMContext dmc, DataRequestMonitor<IResourceClass[]> rm) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$ }
@Override public void sourceContainersChanged( final ISourceLookupDMContext sourceLookupCtx, final DataRequestMonitor<Boolean> rm) { if (!fDirectors.containsKey(sourceLookupCtx)) { rm.setStatus( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$ ); rm.done(); return; } Map<String, String> entries = getSubstitutionsPaths(sourceLookupCtx); if (entries.equals(fCachedEntries)) { rm.done(false); } else { /* * Issue the clear and set commands back to back so that the * executor thread atomically changes the source lookup settings. * Any commands to GDB issued after this call will get the new * source substitute settings. */ CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { @Override protected void handleSuccess() { rm.done(true); } }; fCommand.queueCommand( fCommandFactory.createCLIUnsetSubstitutePath(sourceLookupCtx), new DataRequestMonitor<MIInfo>(getExecutor(), countingRm)); initializeSourceSubstitutions(sourceLookupCtx, new RequestMonitor(getExecutor(), countingRm)); countingRm.setDoneCount(2); } }
@Override protected void execute(final DataRequestMonitor<V> rm) { /* * We're in another dispatch, so we must guard against executor * shutdown again. */ final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { rm.setStatus( new Status( IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Debug session already shut down.", null)); //$NON-NLS-1$ rm.done(); return; } /* * Guard against a disposed service */ IRegisters service = getService(); if (service == null) { rm.setStatus( new Status( IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } doExecute(service, rm); }
@Override protected IStatus run(IProgressMonitor monitor) { final IStatus promptStatus = new Status( IStatus.INFO, "org.eclipse.debug.ui", 200 /*STATUS_HANDLER_PROMPT*/, "", null); //$NON-NLS-1$//$NON-NLS-2$ final IStatus filePrompt = new Status( IStatus.INFO, "org.eclipse.cdt.dsf.gdb.ui", 1001, "", null); //$NON-NLS-1$//$NON-NLS-2$ // consult a status handler final IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus); final Status NO_CORE_STATUS = new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, LaunchMessages.getString("LocalCDILaunchDelegate.6"), // $NON-NLS-1$ null); if (prompter == null) { fRequestMonitor.setStatus(NO_CORE_STATUS); fRequestMonitor.done(); return Status.OK_STATUS; } try { Object result = prompter.handleStatus(filePrompt, null); if (result == null) { fRequestMonitor.cancel(); } else if (result instanceof String) { fRequestMonitor.setData((String) result); } else { fRequestMonitor.setStatus(NO_CORE_STATUS); } } catch (CoreException e) { fRequestMonitor.setStatus(NO_CORE_STATUS); } fRequestMonitor.done(); return Status.OK_STATUS; }
@Override public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) { rm.setData(AVAILABLE_FORMATS); rm.done(); }
/** * Tests whether the given element matches the given expression. * * @param element Element to test against the given expression. * @param expression Expression to use to check if the element is matching. * @param rm The request monitor for the result. */ @ConfinedToDsfExecutor("#getSession#getExecutor") protected void testElementForExpression( Object element, IExpression expression, final DataRequestMonitor<Boolean> rm) { rm.setData(false); rm.done(); }
@Override public <V extends ICommandResult> ICommandToken queueCommand( final ICommand<V> command, DataRequestMonitor<V> rm) { final ICommandToken token = new ICommandToken() { @Override public ICommand<? extends ICommandResult> getCommand() { return command; } }; // The class does not buffer commands itself, but sends them directly to the real // MICommandControl service. Therefore, we must immediately tell our calling cache that the // command // has been sent, since we can never cancel it. processCommandSent(token); if (command instanceof MIMetaGetCPUInfo) { @SuppressWarnings("unchecked") final DataRequestMonitor<MIMetaGetCPUInfoInfo> drm = (DataRequestMonitor<MIMetaGetCPUInfoInfo>) rm; final ICommandControlDMContext dmc = (ICommandControlDMContext) command.getContext(); if (fBackend.getSessionType() == SessionType.REMOTE) { // Ask GDB to fetch /proc/cpuinfo from the remote target, and then we parse it. String remoteFile = "/proc/cpuinfo"; // $NON-NLS-1$ final String localFile = sTempFolder + "proc.cpuinfo." + getSession().getId(); // $NON-NLS-1$ fCommandControl.queueCommand( fCommandFactory.createCLIRemoteGet(dmc, remoteFile, localFile), new ImmediateDataRequestMonitor<MIInfo>(rm) { @Override protected void handleSuccess() { ICoreInfo[] info = new CoreList(localFile).getCoreList(); // Now that we processed the file, remove it to avoid polluting the file system new File(localFile).delete(); drm.done(new MIMetaGetCPUInfoInfo(info)); processCommandDone(token, drm.getData()); } @Override protected void handleError() { // On some older linux versions, gdbserver is not able to read from /proc // because it is a pseudo filesystem. // We need to find some other method of getting the info we need. // For a remote session, we can use GDB's -list-thread-groups --available // command, which shows on which cores a process is running. This does // not necessarily give the exhaustive list of cores, but that is the best // we have in this case. // // In this case, we don't have knowledge about CPUs, so we lump all cores // into a single CPU. fCommandControl.queueCommand( fCommandFactory.createMIListThreadGroups(dmc, true), new ImmediateDataRequestMonitor<MIListThreadGroupsInfo>(drm) { @Override protected void handleSuccess() { // First extract the string id for every core GDB reports Set<String> coreIds = new HashSet<String>(); IThreadGroupInfo[] groups = getData().getGroupList(); for (IThreadGroupInfo group : groups) { coreIds.addAll(Arrays.asList(group.getCores())); } // Now create the context for each distinct core // // We don't have CPU info in this case so let's put them all under a // single CPU final String defaultCPUId = "0"; // $NON-NLS-1$ ICoreInfo[] info = new ICoreInfo[coreIds.size()]; int i = 0; for (String id : coreIds) { info[i++] = new CoreInfo(id, defaultCPUId); } drm.done(new MIMetaGetCPUInfoInfo(info)); processCommandDone(token, drm.getData()); } }); } }); } else { // For a local session, parse /proc/cpuinfo directly. ICoreInfo[] info = new CoreList("/proc/cpuinfo").getCoreList(); // $NON-NLS-1$ drm.done(new MIMetaGetCPUInfoInfo(info)); processCommandDone(token, drm.getData()); } } else { rm.setStatus( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Unexpected Meta command", null)); //$NON-NLS-1$ rm.done(); } return token; }
@Override public void getFormattedExpressionValue( FormattedValueDMContext dmc, DataRequestMonitor<FormattedValueDMData> rm) { rm.setData(new FormattedValueDMData(dmc.getFormatID())); rm.done(); }
/** * This method processes "load info" requests. The load is computed using a sampling method; two * readings of a local or remote /proc/stat file are done with a delay in between. Then the load * is computed from the two samples, for all CPUs/cores known in the system. * * <p>Because of the method used, it's possible that fast variations in CPU usage will be missed. * However longer load trends should be reflected in the results. * * <p>To avoid generating too much load in the remote case, there is a cache that will return the * already computed load, if requested multiple times in a short period. There is also a mechanism * to queue subsequent requests if one is ongoing. Upon completion of the ongoing request, any * queued request is answered with the load that was just computed. * * @since 4.2 */ @Override public void getLoadInfo(final IDMContext context, final DataRequestMonitor<ILoadInfo> rm) { if (!(context instanceof ICoreDMContext) && !(context instanceof ICPUDMContext)) { // we only support getting the load for a CPU or a core rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Load information not supported for this context type", null)); //$NON-NLS-1$ return; } // The measurement interval should be of a minimum length to be meaningful assert (LOAD_SAMPLE_DELAY >= 100); // so the cache is useful assert (LOAD_CACHE_LIFETIME >= LOAD_SAMPLE_DELAY); // This way of computing the CPU load is only applicable to Linux if (!supportsProcPseudoFS()) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$ return; } // Is a request is already ongoing? if (fLoadRequestOngoing) { // queue current new request fLoadInfoRequestCache.put(context, rm); return; } // no request ongoing, so proceed fLoadRequestOngoing = true; // caching mechanism to keep things sane, even if the views(s) // request load information very often. long currentTime = System.currentTimeMillis(); // time to fetch fresh load information? if (fLastCpuLoadRefresh + LOAD_CACHE_LIFETIME < currentTime) { fLastCpuLoadRefresh = currentTime; } else { // not time yet... re-use cached load data processLoads(context, rm, fCachedLoads); fLoadRequestOngoing = false; return; } final ProcStatParser procStatParser = new ProcStatParser(); final ICommandControlDMContext dmc = DMContexts.getAncestorOfType(context, ICommandControlDMContext.class); final String statFile = "/proc/stat"; // $NON-NLS-1$ final String localFile = sTempFolder + "proc.stat." + getSession().getId(); // $NON-NLS-1$ // Remote debugging? We will ask GDB to get us the /proc/stat file from target, twice, with a // delay between. if (fBackend.getSessionType() == SessionType.REMOTE) { fCommandControl.queueCommand( fCommandFactory.createCLIRemoteGet(dmc, statFile, localFile), new ImmediateDataRequestMonitor<MIInfo>(rm) { @Override protected void handleCompleted() { if (!isSuccess()) { fLoadRequestOngoing = false; rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ return; } // Success - parse first set of stat counters try { procStatParser.parseStatFile(localFile); } catch (Exception e) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ fLoadRequestOngoing = false; return; } // delete temp file new File(localFile).delete(); getExecutor() .schedule( new Runnable() { @Override public void run() { fCommandControl.queueCommand( fCommandFactory.createCLIRemoteGet(dmc, statFile, localFile), new ImmediateDataRequestMonitor<MIInfo>(rm) { @Override protected void handleCompleted() { if (!isSuccess()) { fLoadRequestOngoing = false; rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ return; } // Success - parse the second set of stat counters and compute // loads try { procStatParser.parseStatFile(localFile); } catch (Exception e) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ fLoadRequestOngoing = false; return; } // delete temp file new File(localFile).delete(); // Compute load fCachedLoads = procStatParser.getCpuLoad(); processLoads(context, rm, fCachedLoads); // done with request fLoadRequestOngoing = false; // process any queued request for (Entry<IDMContext, DataRequestMonitor<ILoadInfo>> e : fLoadInfoRequestCache.entrySet()) { processLoads(e.getKey(), e.getValue(), fCachedLoads); } fLoadInfoRequestCache.clear(); } }); } }, LOAD_SAMPLE_DELAY, TimeUnit.MILLISECONDS); } }); // Local debugging? Then we can read /proc/stat directly } else { // Read /proc/stat file for the first time try { procStatParser.parseStatFile(statFile); } catch (Exception e) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ fLoadRequestOngoing = false; return; } // Read /proc/stat file again after a delay getExecutor() .schedule( new Runnable() { @Override public void run() { try { procStatParser.parseStatFile(statFile); } catch (Exception e) { rm.done( new Status( IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Can't get load info for CPU", null)); //$NON-NLS-1$ fLoadRequestOngoing = false; return; } // compute load fCachedLoads = procStatParser.getCpuLoad(); processLoads(context, rm, fCachedLoads); // done with request fLoadRequestOngoing = false; // process any queued request for (Entry<IDMContext, DataRequestMonitor<ILoadInfo>> e : fLoadInfoRequestCache.entrySet()) { processLoads(e.getKey(), e.getValue(), fCachedLoads); } fLoadInfoRequestCache.clear(); } }, LOAD_SAMPLE_DELAY, TimeUnit.MILLISECONDS); } }