// During startup these methods are called in this order: // -LaunchSuspended // -ResumeProcess // -Attach - Triggered by Attach int IDebugEngineLaunch2.LaunchSuspended(string aPszServer, IDebugPort2 aPort, string aDebugInfo , string aArgs, string aDir, string aEnv, string aOptions, enum_LAUNCH_FLAGS aLaunchFlags , uint aStdInputHandle, uint aStdOutputHandle, uint hStdError, IDebugEventCallback2 aAD7Callback , out IDebugProcess2 oProcess) { // Launches a process by means of the debug engine. // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language), // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. oProcess = null; try { mEngineCallback = new EngineCallback(this, aAD7Callback); var xDebugInfo = new Dictionary <string, string>(); DictionaryHelper.LoadFromString(xDebugInfo, aDebugInfo); //TODO: In the future we might support command line args for kernel etc //string xCmdLine = EngineUtils.BuildCommandLine(exe, args); //var processLaunchInfo = new ProcessLaunchInfo(exe, xCmdLine, dir, env, options, launchFlags, hStdInput, hStdOutput, hStdError); AD7EngineCreateEvent.Send(this); oProcess = mProcess = new AD7Process(xDebugInfo, mEngineCallback, this, aPort); // We only support one process, so just use its ID for the program ID mProgramID = mProcess.ID; //AD7ThreadCreateEvent.Send(this, xProcess.Thread); mModule = new AD7Module(); mProgNode = new AD7ProgramNode(mProcess.PhysID); } catch (NotSupportedException) { return(VSConstants.S_FALSE); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } return(VSConstants.S_OK); }
public AD7Property(DebugLocalInfo localInfo, AD7Process process, AD7StackFrame stackFrame) { m_variableInformation = localInfo; mProcess = process; mStackFrame = stackFrame; if (localInfo.IsLocal) { mDebugInfo = mStackFrame.mLocalInfos[m_variableInformation.Index]; } else if (localInfo.IsReference) { mDebugInfo = new LOCAL_ARGUMENT_INFO() { TYPENAME = localInfo.Type, NAME = localInfo.Name, OFFSET = localInfo.Offset }; } else { mDebugInfo = mStackFrame.mArgumentInfos[m_variableInformation.Index]; } }
public AD7StackFrame(AD7Engine aEngine, AD7Thread aThread, AD7Process aProcess) { mEngine = aEngine; mThread = aThread; mProcess = aProcess; var xProcess = mEngine.mProcess; if (mHasSource = xProcess.mCurrentAddress.HasValue) { var xAddress = xProcess.mCurrentAddress.Value; var xSourceInfos = xProcess.mDebugInfoDb.GetSourceInfos(xAddress); if (!xSourceInfos.ContainsKey(xAddress)) { //Attempt to find the ASM address of the first ASM line of the C# line that contains //the current ASM address line // Because of Asm breakpoints the address we have might be in the middle of a C# line. // So we find the closest address to ours that is less or equal to ours. var xQry = from x in xSourceInfos where x.Key <= xAddress orderby x.Key descending select x.Key; if (xQry.Count() > 0) { xAddress = xQry.First(); } } if (mHasSource = xSourceInfos.ContainsKey(xAddress)) { var xSourceInfo = xSourceInfos[xAddress]; mDocName = xSourceInfo.SourceFile; mFunctionName = xSourceInfo.MethodName; mLineNum = (uint)xSourceInfo.LineStart; // Multiple labels that point to a single address can happen because of exception handling exits etc. // Because of this given an address, we might find more than one label that matches the address. // Currently, the label we are looking for will always be the first one so we choose that one. // In the future this might "break", so be careful about this. In the future we may need to classify // labels in the output and mark them somehow. var xLabelsForAddr = xProcess.mDebugInfoDb.GetLabels(xAddress); if (xLabelsForAddr.Length > 0) { MethodIlOp xSymbolInfo; string xLabel = xLabelsForAddr[0]; // Necessary for LINQ xSymbolInfo = aProcess.mDebugInfoDb.TryGetFirstMethodIlOpByLabelName(xLabel); if (xSymbolInfo != null) { var xMethod = mProcess.mDebugInfoDb.GetMethod(xSymbolInfo.MethodID.Value); var xAllInfos = aProcess.mDebugInfoDb.GetAllLocalsAndArgumentsInfosByMethodLabelName(xMethod.LabelCall); mLocalInfos = xAllInfos.Where(q => !q.IsArgument).ToArray(); mArgumentInfos = xAllInfos.Where(q => q.IsArgument).ToArray(); if (mArgumentInfos.Length > 0) { mParams = new DebugLocalInfo[mArgumentInfos.Length]; for (int i = 0; i < mArgumentInfos.Length; i++) { mParams[i] = new DebugLocalInfo { Name = mArgumentInfos[i].NAME, Index = i, IsLocal = false }; } mParams = mParams.OrderBy(i => i.Name, StringComparer.OrdinalIgnoreCase).ToArray(); } if (mLocalInfos.Length > 0) { mLocals = new DebugLocalInfo[mLocalInfos.Length]; for (int i = 0; i < mLocalInfos.Length; i++) { mLocals[i] = new DebugLocalInfo { Name = mLocalInfos[i].NAME, Index = i, IsLocal = true }; } mLocals = mLocals.OrderBy(i => i.Name, StringComparer.OrdinalIgnoreCase).ToArray(); } } } else { AD7Util.ShowError("No Symbol found for address 0x" + xAddress.ToString("X8").ToUpper()); } xProcess.DebugMsg(String.Format("StackFrame: Returning: {0}#{1}[{2}]", mDocName, mFunctionName, mLineNum)); } } if (!mHasSource) { xProcess.DebugMsg("StackFrame: No Source available"); } // If source information is available, create the collections of locals and parameters and populate them with // values from the debuggee. //if (m_hasSource) { //if (mArgumentInfos.Length > 0) { //m_parameters = new VariableInformation[m_numParameters]; //m_engine.DebuggedProcess.GetFunctionArgumentsByIP(m_threadContext.eip, m_threadContext.ebp, m_parameters); //} //if (mLocalInfos.Length > 0) { //m_locals = new VariableInformation[m_numLocals]; //m_engine.DebuggedProcess.GetFunctionLocalsByIP(m_threadContext.eip, m_threadContext.ebp, m_locals); //} //} }
public AD7Expression(DebugLocalInfo pVar, AD7Process pProcess, AD7StackFrame pStackFrame) { m_var = pVar; Process = pProcess; StackFrame = pStackFrame; }
public AD7Thread(AD7Engine aEngine, AD7Process aProcess) //, DebuggedThread debuggedThread) { mEngine = aEngine; mProcess = aProcess; }