public int Terminate()
        {
            OutputText("Debugger terminating.");

            try
            {
                mHost.Stop();

                OutputText("Debugger terminated.");
                return(VSConstants.S_OK);
            }
            catch (ApplicationException)
            {
                OutputText("Failed to stop debugger!");
                OutputText("\r\n");
                OutputText("You need to install the VMWare VIX API!");

                AD7Util.MessageBox("Failed to stop debugger! You need to install the VMWare VIX API!", "Information");
            }
            catch (Exception ex)
            {
                OutputText("Failed to stop debugger! Exception message: " + ex.Message);
                OutputText("\r\n");
                OutputText("You probably need to install the VMWare VIX API!");

                AD7Util.MessageBox(
                    "Failed to stop debugger! You probably need to install the VMWare VIX API!\r\n\r\nCheck Output window for more details.",
                    "Information");
            }

            return(VSConstants.E_FAIL);
        }
 protected void LaunchGdbClient()
 {
     OutputText("Launching GDB client.");
     if (File.Exists(Cosmos.Build.Common.CosmosPaths.GdbClientExe))
     {
         var xPSInfo = new ProcessStartInfo(Cosmos.Build.Common.CosmosPaths.GdbClientExe);
         xPSInfo.Arguments              = "\"" + Path.ChangeExtension(mProjectFile, ".cgdb") + "\"" + @" /Connect";
         xPSInfo.UseShellExecute        = false;
         xPSInfo.RedirectStandardInput  = false;
         xPSInfo.RedirectStandardError  = false;
         xPSInfo.RedirectStandardOutput = false;
         xPSInfo.CreateNoWindow         = false;
         Process.Start(xPSInfo);
     }
     else
     {
         AD7Util.MessageBox(string.Format(
                                "The GDB-Client could not be found at \"{0}\". Please deactivate it under \"Properties/Debug/Enable GDB\"",
                                Cosmos.Build.Common.CosmosPaths.GdbClientExe), "GDB-Client");
     }
 }
Ejemplo n.º 3
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 void Step(enum_STEPKIND aKind)
        {
            if (aKind == enum_STEPKIND.STEP_INTO)
            { // F11
                mStepping = true;
                if (ASMSteppingMode)
                {
                    mDbgConnector.SendCmd(Vs2Ds.AsmStepInto);
                    mDbgConnector.SendRegisters();
                }
                else
                {
                    SetINT3sOnCurrentMethod();
                    mDbgConnector.SendCmd(Vs2Ds.StepInto);
                }
            }
            else if (aKind == enum_STEPKIND.STEP_OVER)
            { // F10
                mStepping = true;
                if (ASMSteppingMode)
                {
                    ASMStepOver();
                }
                else
                {
                    SetINT3sOnCurrentMethod();
                    mDbgConnector.SendCmd(Vs2Ds.StepOver);
                }
            }
            else if (aKind == enum_STEPKIND.STEP_OUT)
            { // Shift-F11
                ClearINT3sOnCurrentMethod();

                mStepping = true;
                if (ASMSteppingMode)
                {
                    mASMSteppingOut = true;
                    mASMSteppingOut_NumEndMethodLabelsPassed = 0;
                    mDbgConnector.SendCmd(Vs2Ds.AsmStepInto);

                    //Set a condition to say we should be doing step out
                    //On break, check line just stepped.

                    //If current line is RET - do one more step then break.
                    //Else do another step
                }
                else
                {
                    mDbgConnector.SendCmd(Vs2Ds.StepOut);
                }
            }
            else if (aKind == enum_STEPKIND.STEP_BACKWARDS)
            {
                // STEP_BACKWARDS - Supported at all by VS?
                //
                // Possibly, by dragging the execution location up
                // or down through the source code? -Orvid
                AD7Util.MessageBox("Step backwards is not supported.");
                mCallback.OnStepComplete(); // Have to call this otherwise VS gets "stuck"
            }
            else
            {
                AD7Util.MessageBox("Unknown step type requested.");
                mCallback.OnStepComplete(); // Have to call this otherwise VS gets "stuck"
            }
        }
 void DbgCmdKernelPanic(uint nr)
 {
     AD7Util.MessageBox("Kernel panic: 0x" + nr.ToString());
 }
        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();
            }
        }
 private void DbgCmdMessageBox(string message)
 {
     AD7Util.MessageBox("Message from your Cosmos operating system:\r\n\r\n" + message);
 }
 private void DbgCmdNullReferenceOccurred(uint lastEIPAddress)
 {
     AD7Util.MessageBox(String.Format("NullReferenceException occurred at address 0x{0:X8}! Halting now.", lastEIPAddress));
 }
 private void DbgCmdStackOverflowOccurred(uint lastEIPAddress)
 {
     AD7Util.MessageBox(String.Format("Stack overflow occurred at address 0x{0:X8}! Halting now.", lastEIPAddress));
 }
Ejemplo n.º 10
0
 private void DbgCmdStackCorruptionOccurred(uint lastEIPAddress)
 {
     AD7Util.MessageBox(String.Format("Stack corruption occurred at address 0x{0:X8}! Halting now.", lastEIPAddress));
 }
Ejemplo n.º 11
0
        public void SendAssembly(bool noDisplay = false)
        {
            AD7Util.Log("SendAssembly");
            ASMWindow_CurrentLineUpdated.Reset();
            ASMWindow_NextAddress1Updated.Reset();
            ASMWindow_NextLine1Updated.Reset();

            uint xAddress     = mCurrentAddress.Value;
            var  xSourceInfos = mDebugInfoDb.GetSourceInfos(xAddress);

            AD7Util.Log("SendAssembly - SourceInfos retrieved for address 0x{0}", xAddress.ToString("X8"));
            if (xSourceInfos.Count > 0)
            {
                //We should be able to display the asesembler source for any address regardless of whether a C#
                //line is associated with it.
                //However, we do not store all labels in the debug database because that would make the compile
                //time insane.
                //So:
                // - We take the current address amd find the method it is part of
                // - We use the method header label as a start point and find all asm labels till the method footer label
                // - We then find all the asm for these labels and display it.

                Label[] xLabels = mDebugInfoDb.GetMethodLabels(xAddress);
                AD7Util.Log("SendAssembly - MethodLabels retrieved");
                // get the label of our current position, or the closest one before
                var curPosLabel = xLabels.Where(i => i.Address <= xAddress).OrderByDescending(i => i.Address).FirstOrDefault();
                // if curPosLabel is null, grab the first one.
                if (curPosLabel == null)
                {
                    curPosLabel = xLabels[0];
                }

                var curPosIndex = Array.IndexOf(xLabels, curPosLabel);
                // we want 50 items before and after the current item, so 100 in total.
                var itemsBefore = 10;
                var itemsAfter  = 10;

                if (curPosIndex < itemsBefore)
                {
                    // there are no 50 items before the current one, so adjust
                    itemsBefore = curPosIndex;
                }
                if ((curPosIndex + itemsAfter) >= xLabels.Length)
                {
                    // there are no 50 items after the current one, so adjust
                    itemsAfter = xLabels.Length - curPosIndex;
                }

                var newArr = new Label[itemsBefore + itemsAfter];
                for (int i = 0; i < newArr.Length; i++)
                {
                    newArr[i] = xLabels[(curPosIndex - itemsBefore) + i];
                }
                xLabels = newArr;

                //The ":" has to be added in because labels in asm code have it on the end - it's easier to add it here than
                //strip them out of the read asm
                var xLabelNames = xLabels.Select(x => x.Name + ":").ToList();

                // Get assembly source
                var xCode = AsmSource.GetSourceForLabels(Path.ChangeExtension(mISO, ".asm"), xLabelNames);
                AD7Util.Log("SendAssembly - SourceForLabels retrieved");

                // Get label for current address.
                // A single address can have multiple labels (IL, Asm). Because of this we search
                // for the one with the Asm tag. We dont have the tags in this debug info though,
                // so instead if there is more than one label we use the longest one which is the Asm tag.
                string xCurrentLabel  = "";
                var    xCurrentLabels = mDebugInfoDb.GetLabels(xAddress);
                if (xCurrentLabels.Length > 0)
                {
                    xCurrentLabel = xCurrentLabels.OrderBy(q => q.Length).Last();
                }
                if (string.IsNullOrEmpty(xCurrentLabel))
                {
                    xCurrentLabel = "NO_METHOD_LABEL_FOUND";
                }

                // Insert filter labels list as THIRD(!) line of our data stream
                string filterLabelsList = "";
                foreach (var addressInfo in INT3sSet)
                {
                    //"We have to add the ".00:" because of how the ASM window works...
                    filterLabelsList += "|" + addressInfo.Value + ".00";
                }
                if (filterLabelsList.Length > 0)
                {
                    filterLabelsList = filterLabelsList.Substring(1);
                }
                xCode.Insert(0, filterLabelsList + "\r\n");
                // Insert parameters as SECOND(!) line of our data stream
                xCode.Insert(0, (noDisplay ? "NoDisplay" : "") + "|" + (ASMSteppingMode ? "AsmStepMode" : "") + "\r\n");
                // Insert current line's label as FIRST(!) line of our data stream
                xCode.Insert(0, xCurrentLabel + "\r\n");
                //THINK ABOUT THE ORDER that he above lines occur in and where they insert data into the stream - don't switch it!
                AD7Util.Log("SendAssembly - Sending through pipe now");
                mDebugDownPipe.SendCommand(Debugger2Windows.AssemblySource, Encoding.UTF8.GetBytes(xCode.ToString()));
                AD7Util.Log("SendAssembly - Done");
            }
        }