int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 aEvent)
 {
     // Called by the SDM to indicate that a synchronous debug event, previously sent by the DE to the SDM,
     // was received and processed. The only event the  engine sends in this fashion is Program Destroy.
     // It responds to that event by shutting down the engine.
     //
     // This is used in some cases - I set a BP here and it does get hit sometime during breakpoints
     // being triggered for example.
     try
     {
         if (aEvent is AD7ProgramDestroyEvent)
         {
             mEngineCallback = null;
             mProgramID      = Guid.Empty;
             mThread         = null;
             mProgNode       = null;
         }
         else
         {
             System.Diagnostics.Debug.Fail("Unknown synchronious event");
         }
     }
     catch (Exception e)
     {
         return(EngineUtils.UnexpectedException(e));
     }
     return(VSConstants.S_OK);
 }
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            // Attach the debug engine to a program.
            //
            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process.
            // So could we simplify and move code from LaunchSuspended to here and maybe even
            // eliminate the debughost? Although I supposed DebugHost has some other uses as well.

            if (aCeltPrograms != 1)
            {
                System.Diagnostics.Debug.Fail("Cosmos Debugger only supports one debug target at a time.");
                throw new ArgumentException();
            }

            try
            {
                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out mProgramID));

                mProgram = rgpPrograms[0];
                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                AD7ModuleLoadEvent.Send(this, mModule, true);

                // Dummy main thread
                // We dont support threads yet, but the debugger expects threads.
                // So we create a dummy object to represente our only "thread".
                mThread = new AD7Thread(this, mProcess);
                AD7LoadCompleteEvent.Send(this, mThread);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
Exemple #3
0
        internal static void Send(AD7Engine aEngine, AD7Thread aThread)
        {
            var xMessage = new AD7LoadCompleteEvent();

            aEngine.Callback.Send(xMessage, IID, aThread);
        }
Exemple #4
0
        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);
            //}
            //}
        }
        internal AD7Process(Dictionary <string, string> aDebugInfo, EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort)
        {
            mCallback  = aCallback;
            mDebugInfo = aDebugInfo;

            mLaunch = (LaunchType)Enum.Parse(typeof(LaunchType), aDebugInfo[BuildPropertyNames.LaunchString]);

            if (mDebugDownPipe == null)
            {
                mDebugDownPipe = new PipeClient(Pipes.DownName);

                mDebugUpPipe = new PipeServer(Pipes.UpName);
                mDebugUpPipe.DataPacketReceived += mDebugUpPipe_DataPacketReceived;
                mDebugUpPipe.Start();
            }
            else
            {
                mDebugUpPipe.CleanHandlers();
                mDebugUpPipe.DataPacketReceived += mDebugUpPipe_DataPacketReceived;
            }

            // Must be after mDebugDownPipe is initialized
            OutputClear();
            OutputText("Debugger process initialized.");

            mISO = mDebugInfo["ISOFile"];
            OutputText("Using ISO file " + mISO + ".");
            mProjectFile = mDebugInfo["ProjectFile"];
            //
            bool xUseGDB = string.Equals(mDebugInfo[BuildPropertyNames.EnableGDBString], "true", StringComparison.InvariantCultureIgnoreCase);

            OutputText("GDB " + (xUseGDB ? "Enabled" : "Disabled") + ".");
            //
            var xGDBClient = false;

            Boolean.TryParse(mDebugInfo[BuildPropertyNames.StartCosmosGDBString], out xGDBClient);

            switch (mLaunch)
            {
            case LaunchType.VMware:
                #region CheckIfHyperVServiceIsRunning

                using (System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController("vmms"))
                {
                    try
                    {
                        if (sc.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                        {
                            AD7Util.MessageBox(
                                "The Hyper-V Virtual Machine Management Service will be stopped. This is needed to allow to run VMware. If you press \"No\" the debug will stop.",
                                "Question");
                            sc.Stop();
                        }
                    }
                    catch (InvalidOperationException)
                    {
                        // service not present
                    }
                }

                #endregion CheckIfHyperVServiceIsRunning

                mHost = new VMware(mDebugInfo, xUseGDB);
                break;

#if SERIAL_PORT
            case LaunchType.Slave:
                mHost = new Slave(mDebugInfo, xUseGDB);
                break;
#endif
            case LaunchType.Bochs:
                // The project has been created on another machine or Bochs has been uninstalled since the project has
                // been created.
                if (!BochsSupport.BochsEnabled)
                {
                    throw new Exception(Resources.BochsIsNotInstalled);
                }

                string bochsConfigurationFileName;
                mDebugInfo.TryGetValue(BuildProperties.BochsEmulatorConfigurationFileString, out bochsConfigurationFileName);

                if (string.IsNullOrEmpty(bochsConfigurationFileName))
                {
                    bochsConfigurationFileName = BuildProperties.BochsDefaultConfigurationFileName;
                }

                if (!Path.IsPathRooted(bochsConfigurationFileName))
                {
                    // Assume the configuration file name is relative to project output path.
                    bochsConfigurationFileName = Path.Combine(new FileInfo(mDebugInfo["ProjectFile"]).Directory.FullName,
                                                              mDebugInfo["OutputPath"], bochsConfigurationFileName);
                }
                FileInfo bochsConfigurationFile = new FileInfo(bochsConfigurationFileName);
                // TODO : What if the configuration file doesn't exist ? This will throw a FileNotFoundException in
                // the Bochs class constructor. Is this appropriate behavior ?
                mHost = new Bochs(mDebugInfo, xUseGDB, bochsConfigurationFile);

                //((Host.Bochs)mHost).FixBochsConfiguration(new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("IsoFileName", mISO) });
                break;

            case LaunchType.IntelEdison:
                mHost = new IntelEdison(mDebugInfo, false);
                break;

            case LaunchType.HyperV:
                mHost = new HyperV(mDebugInfo, false);
                break;

            default:
                throw new Exception("Invalid Launch value: '" + mLaunch + "'.");
            }
            mHost.OnShutDown += HostShutdown;

            string xDbPath = Path.ChangeExtension(mISO, "cdb");
            if (!File.Exists(xDbPath))
            {
                throw new Exception("Debug data file " + xDbPath + " not found. Could be a omitted build process of Cosmos project so that not created.");
            }

            mDebugInfoDb = new DebugInfo(xDbPath);
            mDebugInfoDb.LoadLookups();

            CreateDebugConnector();
            aEngine.BPMgr.SetDebugConnector(mDbgConnector);

            mEngine = aEngine;
            mThread = new AD7Thread(aEngine, this);
            mCallback.OnThreadStart(mThread);
            mPort = aPort;

            if (xUseGDB && xGDBClient)
            {
                LaunchGdbClient();
            }
        }