예제 #1
0
        // Creates an enumerator for properties associated with the stack frame, such as local variables.
        // The sample engine only supports returning locals and parameters. Other possible values include
        // class fields (this pointer), registers, exceptions...
        int IDebugStackFrame2.EnumProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, uint nRadix, ref Guid guidFilter, uint dwTimeout, out uint elementsReturned, out IEnumDebugPropertyInfo2 enumObject)
        {
            int hr;

            elementsReturned = 0;
            enumObject       = null;

            try
            {
                if (guidFilter == AD7Guids.guidFilterLocalsPlusArgs ||
                    guidFilter == AD7Guids.guidFilterAllLocalsPlusArgs)
                {
                    CreateLocalsPlusArgsProperties(out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else if (guidFilter == AD7Guids.guidFilterLocals)
                {
                    CreateLocalProperties(out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else if (guidFilter == AD7Guids.guidFilterArgs)
                {
                    CreateParameterProperties(out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else
                {
                    hr = VSConstants.E_NOTIMPL;
                }
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(hr);
        }
예제 #2
0
        // Gets the file statement range of the document context.
        // A statement range is the range of the lines that contributed the code to which this document context refers.
        int IDebugDocumentContext2.GetStatementRange(TEXT_POSITION[] pBegPosition, TEXT_POSITION[] pEndPosition)
        {
            try
            {
                pBegPosition[0].dwColumn = m_begPos.dwColumn;
                pBegPosition[0].dwLine   = m_begPos.dwLine;

                pEndPosition[0].dwColumn = m_endPos.dwColumn;
                pEndPosition[0].dwLine   = m_endPos.dwLine;
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(VSConstants.S_OK);
        }
예제 #3
0
        // Gets the file statement range of the document context.
        // A statement range is the range of the lines that contributed the code to which this document context refers.
        int IDebugDocumentContext2.GetStatementRange(TEXT_POSITION[] pBegPosition, TEXT_POSITION[] pEndPosition)
        {
            try
            {
                pBegPosition[0].dwColumn = _textPosition.BeginPosition.dwColumn;
                pBegPosition[0].dwLine   = _textPosition.BeginPosition.dwLine;

                pEndPosition[0].dwColumn = _textPosition.EndPosition.dwColumn;
                pEndPosition[0].dwLine   = _textPosition.EndPosition.dwLine;
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(Constants.S_OK);
        }
예제 #4
0
        public int GetStatementRange(TEXT_POSITION[] pBegPosition, TEXT_POSITION[] pEndPosition)
        {
            try
            {
                pBegPosition[0].dwColumn = start.dwColumn;
                pBegPosition[0].dwLine   = start.dwLine;

                pEndPosition[0].dwColumn = end.dwColumn;
                pEndPosition[0].dwLine   = end.dwLine;
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(VSConstants.S_OK);
        }
예제 #5
0
        public int Bind()
        {
            var    docPosition = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(requestInfo.bpLocation.unionmember2);
            string documentName;

            EngineUtils.CheckOk(docPosition.GetFileName(out documentName));

            // Remap document name  TODO: Implement this properly
            const string localRoot = @"C:/dev/TestDebug/TestDebug";

            documentName = documentName.Replace('\\', '/');
            const string remoteRoot = @"/mnt/c/dev/TestDebug/TestDebug";

            documentName = remoteRoot + documentName.Substring(localRoot.Length);

            var startPosition = new TEXT_POSITION[1];
            var endPosition   = new TEXT_POSITION[1];

            EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition));

            var engine = breakpointManager.Engine;

            breakpoint = engine.Session.Breakpoints.Add(documentName, (int)startPosition[0].dwLine + 1, (int)startPosition[0].dwColumn + 1);
            breakpointManager.Add(breakpoint, this);
            SetCondition(requestInfo.bpCondition);
            SetPassCount(requestInfo.bpPassCount);

            lock (boundBreakpoints)
            {
                uint address = 0;
                var  breakpointResolution = new MonoBreakpointResolution(engine, address, GetDocumentContext(address));
                var  boundBreakpoint      = new MonoBoundBreakpoint(engine, address, this, breakpointResolution);
                boundBreakpoints.Add(boundBreakpoint);

                engine.Send(new MonoBreakpointBoundEvent(this, boundBreakpoint), MonoBreakpointBoundEvent.IID, null);
            }

            return(VSConstants.S_OK);
        }
예제 #6
0
        private void SendStartDebuggingError(Exception exception)
        {
            if (exception is OperationCanceledException)
            {
                return; // don't show a message in this case
            }

            string description = EngineUtils.GetExceptionDescription(exception);
            string message     = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_UnableToStartDebugging, description);

            var initializationException = exception as MIDebuggerInitializeFailedException;

            if (initializationException != null)
            {
                string outputMessage = string.Join("\r\n", initializationException.OutputLines) + "\r\n";

                // NOTE: We can't write to the output window by sending an AD7 event because this may be called before the session create event
                LiveLogger.WriteLine(outputMessage);
            }

            _engineCallback.OnErrorImmediate(message);
        }
예제 #7
0
        // Gets the name of the stack frame.
        // The name of a stack frame is typically the name of the method being executed.
        int IDebugStackFrame2.GetName(out string name)
        {
            name = null;

            try
            {
                if (_functionName != null)
                {
                    name = _functionName;
                }

                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #8
0
        public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            var            program = programs[0];
            IDebugProcess2 process;

            program.GetProcess(out process);
            Guid processId;

            process.GetProcessId(out processId);
            if (processId != this.processId.guidProcessId)
            {
                return(VSConstants.S_FALSE);
            }

            EngineUtils.RequireOk(program.GetProgramId(out programId));

            Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("", new IPAddress(new byte[] { 192, 168, 137, 3 }), 12345)),
                        new DebuggerSessionOptions {
                EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false
            });

            return(VSConstants.S_OK);
        }
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            try
            {
                pinfo[0].dwFields = 0;

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
                {
                    //pinfo[0].bstrAddress = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch);
                    pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
                }

                // Fields not supported by the sample
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0)
                {
                }
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
                {
                    //pinfo[0].bstrAddressAbsolute = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch);
                    pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
                }

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0)
                {
                }

                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <summary>
        ///     Gets the document context for this stack frame. The debugger will call this when the current stack frame is changed
        ///     and will use it to open the correct source document for this stack frame.
        /// </summary>
        /// <param name="docContext">The document context.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int GetDocumentContext(out IDebugDocumentContext2 docContext)
        {
            docContext = null;
            try
            {
                if (_hasSource)
                {
                    // Assume all lines begin and end at the beginning of the line.
                    // TODO: Accurate line endings
                    var lineNumber = (uint)LineNumber;
                    var begTp      = new TEXT_POSITION
                    {
                        dwColumn = 0,
                        dwLine   = lineNumber - 1
                    };
                    var endTp = new TEXT_POSITION
                    {
                        dwColumn = 0,
                        dwLine   = lineNumber - 1
                    };

                    docContext = new MonoDocumentContext(_documentName, begTp, endTp, null);
                    return(S_OK);
                }
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(S_FALSE);
        }
예제 #12
0
        public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process)
        {
            waiter   = new AutoResetEvent(false);
            settings = MonoDebuggerSettings.Parse(options);

            Task.Run(() =>
            {
                var outputWindow    = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow));
                var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane;
                outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow);

                // Upload the contents of the output folder to the target directory
                if (connection == null)
                {
                    connection = ConnectionManager.Get(settings);
                    if (!connection.IsConnected)
                    {
                        Log("Connecting SSH and SFTP...");
//                        Debugger.Launch();
                        connection.Connect();
                        Log("Connected");
                    }
                }

                Log("Uploading program...");

                // Ensure target directory exists:
                var targetDirectories = directory.Split('/');
                foreach (var part in targetDirectories)
                {
                    if (!connection.Sftp.Exists(part))
                    {
                        connection.Sftp.CreateDirectory(part);
                    }
                    connection.Sftp.ChangeDirectory(part);
                }
                foreach (var _ in targetDirectories)
                {
                    connection.Sftp.ChangeDirectory("..");
                }

                var outputDirectory = new DirectoryInfo(Path.GetDirectoryName(exe));
                foreach (var file in outputDirectory.EnumerateFiles().Where(x => x.Extension == ".dll" || x.Extension == ".mdb" || x.Extension == ".exe"))
                {
                    using (var stream = file.OpenRead())
                    {
                        connection.Sftp.UploadFile(stream, $"{directory}/{file.Name}", true);
                    }
                    Log($"Uploaded {file.FullName}");
                }
                Log("Done");

                var targetExe = directory + "/" + Path.GetFileName(exe);
                connection.Ssh.RunCommand("cd ~");
                Log("Launching application");
                var commandText = $"mono --debug=mdb-optimizations --debugger-agent=transport=dt_socket,address=0.0.0.0:6438,server=y {targetExe}";
                connection.Ssh.RunCommand("kill $(ps auxww | grep '" + commandText + "' | awk '{print $2}')", this.outputWindow, null);
                runCommand = connection.Ssh.BeginCommand(commandText, this.outputWindow, out runCommandAsyncResult);

                // Trigger that the app is now running for whomever might be waiting for that signal
                waiter.Set();
            });

            Session              = new SoftDebuggerSession();
            Session.TargetReady += (sender, eventArgs) =>
            {
                var activeThread = Session.ActiveThread;
                ThreadManager.Add(activeThread, new MonoThread(this, activeThread));
//                Session.Stop();
            };
            Session.ExceptionHandler = exception => true;
            Session.TargetExited    += (sender, x) =>
            {
//                runCommand.EndExecute(runCommandAsyncResult);
                Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null);
            };
            Session.TargetUnhandledException += (sender, x) =>
            {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0))
                {
                    IsUnhandled = true
                }, MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.LogWriter            = (stderr, text) => Console.WriteLine(text);
            Session.OutputWriter         = (stderr, text) => Console.WriteLine(text);
            Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread));
            Session.TargetThreadStopped += (sender, x) =>
            {
                ThreadManager.Remove(x.Thread);
            };
            Session.TargetStopped         += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetStarted         += (sender, x) => Console.WriteLine();
            Session.TargetSignaled        += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetInterrupted     += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetExceptionThrown += (sender, x) =>
            {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.TargetHitBreakpoint += (sender, x) =>
            {
                var breakpoint        = x.BreakEvent as Breakpoint;
                var pendingBreakpoint = breakpointManager[breakpoint];
                Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]);
            };

            processId = new AD_PROCESS_ID();
            processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            processId.guidProcessId = Guid.NewGuid();

            EngineUtils.CheckOk(port.GetProcess(processId, out process));
            Callback = callback;

            return(VSConstants.S_OK);
        }
예제 #13
0
 public string GetAddressDescription(uint ip)
 {
     //    DebuggedModule module = m_debuggedProcess.ResolveAddress(ip);
     return(EngineUtils.GetAddressDescription(/*module,*/ this, ip));
 }
예제 #14
0
        public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process)
        {
            waiter   = new AutoResetEvent(false);
            settings = MonoDebuggerSettings.Load(options);

            Task.Run(() => {
                var outputWindow    = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow));
                var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane;
                outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow);

                settings.Launcher.Launch();

                // Trigger that the app is now running for whomever might be waiting for that signal
                waiter.Set();
            });

            Session              = new SoftDebuggerSession();
            Session.TargetReady += (sender, eventArgs) => {
                var activeThread = Session.ActiveThread;
                ThreadManager.Add(activeThread, new MonoThread(this, activeThread));
                //                Session.Stop();
            };
            Session.ExceptionHandler = exception => true;
            Session.TargetExited    += (sender, x) => {
                //                runCommand.EndExecute(runCommandAsyncResult);
                Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null);
            };
            Session.TargetUnhandledException += (sender, x) => {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0))
                {
                    IsUnhandled = true
                }, MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.LogWriter            = (stderr, text) => Console.WriteLine(text);
            Session.OutputWriter         = (stderr, text) => Console.WriteLine(text);
            Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread));
            Session.TargetThreadStopped += (sender, x) => {
                ThreadManager.Remove(x.Thread);
            };
            Session.TargetStopped         += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetStarted         += (sender, x) => Console.WriteLine();
            Session.TargetSignaled        += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetInterrupted     += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetExceptionThrown += (sender, x) => {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.TargetHitBreakpoint += (sender, x) => {
                var breakpoint        = x.BreakEvent as Breakpoint;
                var pendingBreakpoint = breakpointManager[breakpoint];
                Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]);
            };

            processId = new AD_PROCESS_ID();
            processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            processId.guidProcessId = Guid.NewGuid();

            EngineUtils.CheckOk(port.GetProcess(processId, out process));
            Callback = callback;

            return(VSConstants.S_OK);
        }
예제 #15
0
        public int Compare(enum_CONTEXT_COMPARE compare, IDebugMemoryContext2[] compareToItems, uint compareToLength, out uint foundIndex)
        {
            foundIndex = uint.MaxValue;

            try
            {
                enum_CONTEXT_COMPARE contextCompare = compare;

                for (uint c = 0; c < compareToLength; c++)
                {
                    MonoMemoryAddress compareTo = compareToItems[c] as MonoMemoryAddress;
                    if (compareTo == null)
                    {
                        continue;
                    }

                    if (!ReferenceEquals(this.engine, compareTo.engine))
                    {
                        continue;
                    }

                    bool result;

                    switch (contextCompare)
                    {
                    case enum_CONTEXT_COMPARE.CONTEXT_EQUAL:
                        result = address == compareTo.address;
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN:
                        result = address < compareTo.address;
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN:
                        result = address > compareTo.address;
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN_OR_EQUAL:
                        result = address <= compareTo.address;
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN_OR_EQUAL:
                        result = address >= compareTo.address;
                        break;

                    // The sample debug engine doesn't understand scopes or functions
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_SCOPE:
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_FUNCTION:
                        result = address == compareTo.address;
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_MODULE:
                        result = address == compareTo.address;
                        if (!result)
                        {
/*
 *                              DebuggedModule module = engine.DebuggedProcess.ResolveAddress(address);
 *
 *                              if (module != null)
 *                              {
 *                                  result = (compareTo.address >= module.BaseAddress) &&
 *                                      (compareTo.address < module.BaseAddress + module.Size);
 *                              }
 */
                        }
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_PROCESS:
                        result = true;
                        break;

                    default:
                        // A new comparison was invented that we don't support
                        return(VSConstants.E_NOTIMPL);
                    }

                    if (result)
                    {
                        foundIndex = c;
                        return(VSConstants.S_OK);
                    }
                }

                return(VSConstants.S_FALSE);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #16
0
 private static RegisterGroup GetGroupForRegister(List<RegisterGroup> registerGroups, string name, EngineUtils.RegisterNameMap nameMap)
 {
     string grpName = nameMap.GetGroupName(name);
     RegisterGroup grp = registerGroups.FirstOrDefault((g) => { return g.Name == grpName; });
     if (grp == null)
     {
         grp = new RegisterGroup(grpName);
         registerGroups.Add(grp);
     }
     return grp;
 }
예제 #17
0
        private static void OnInterrupt <G>(string code, InstructionExecutor <G> _, InterruptedEventArgs <G> args) where G : IGroupState <G>, new()
        {
            PrintStackPointers(args.ExecutionState);
            PrintGroupPointers(args.ExecutionState);
            PrintStackRegister(args.ExecutionState);
            PrintListRegister(args.ExecutionState);

            Instruction <G> instruction = args.ExecutionState.GroupState.Group.Instructions[args.ExecutionState.InstructionIndex];

            Debug.WriteLine($"\nInstruction: {args.ExecutionState.InstructionIndex}. {instruction.Code} {string.Join(", ", instruction.Payload?.Select(item => ToValueString(item)) ?? Enumerable.Empty<string>())} \n {(instruction.SourcePosition != null ? EngineUtils.GetLineAtPosition(code, instruction.SourcePosition.Value, 100) : null)}");
        }
예제 #18
0
        internal async Task BindAsync()
        {
            if (CanBind())
            {
                string          documentName  = null;
                string          functionName  = null;
                TEXT_POSITION[] startPosition = new TEXT_POSITION[1];
                TEXT_POSITION[] endPosition   = new TEXT_POSITION[1];
                string          condition     = null;

                lock (_boundBreakpoints)
                {
                    if (_bp != null)   // already bound
                    {
                        Debug.Fail("Breakpoint already bound");
                        return;
                    }
                    if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_BPLOCATION) != 0)
                    {
                        if (_bpRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET)
                        {
                            IDebugFunctionPosition2 functionPosition = HostMarshal.GetDebugFunctionPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2);
                            EngineUtils.CheckOk(functionPosition.GetFunctionName(out functionName));
                        }
                        else if (_bpRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE)
                        {
                            IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2);

                            // Get the name of the document that the breakpoint was put in
                            EngineUtils.CheckOk(docPosition.GetFileName(out documentName));

                            // Get the location in the document that the breakpoint is in.
                            EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition));
                        }
                    }
                    if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 &&
                        _bpRequestInfo.bpCondition.styleCondition == enum_BP_COND_STYLE.BP_COND_WHEN_TRUE)
                    {
                        condition = _bpRequestInfo.bpCondition.bstrCondition;
                    }
                }
                PendingBreakpoint.BindResult bindResult;
                // Bind all breakpoints that match this source and line number.
                if (documentName != null)
                {
                    bindResult = await PendingBreakpoint.Bind(documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn, _engine.DebuggedProcess, condition, this);
                }
                else
                {
                    bindResult = await PendingBreakpoint.Bind(functionName, _engine.DebuggedProcess, condition, this);
                }

                lock (_boundBreakpoints)
                {
                    if (bindResult.PendingBreakpoint != null)
                    {
                        _bp = bindResult.PendingBreakpoint;    // an MI breakpoint object exists: TODO: lock?
                    }
                    if (bindResult.BoundBreakpoints == null || bindResult.BoundBreakpoints.Count == 0)
                    {
                        _BPError = new AD7ErrorBreakpoint(this, bindResult.ErrorMessage);
                        _engine.Callback.OnBreakpointError(_BPError);
                    }
                    else
                    {
                        Debug.Assert(_bp != null);
                        foreach (BoundBreakpoint bp in bindResult.BoundBreakpoints)
                        {
                            AddBoundBreakpoint(bp);
                        }
                    }
                }
            }
        }
예제 #19
0
        // Compares the memory context to each context in the given array in the manner indicated by compare flags,
        // returning an index of the first context that matches.
        public int Compare(enum_CONTEXT_COMPARE Compare, IDebugMemoryContext2[] rgpMemoryContextSet, uint dwMemoryContextSetLen, out uint pdwMemoryContext)
        {
            pdwMemoryContext = UInt32.MaxValue;

            try
            {
                for (uint c = 0; c < dwMemoryContextSetLen; c++)
                {
                    if (!(rgpMemoryContextSet[c] is AD7MemoryAddress compareTo))
                    {
                        continue;
                    }

                    if (!ReferenceEquals(m_engine, compareTo.m_engine))
                    {
                        continue;
                    }

                    bool result;

                    switch (Compare)
                    {
                    case enum_CONTEXT_COMPARE.CONTEXT_EQUAL:
                        result = (m_address == compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN:
                        result = (m_address < compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN:
                        result = (m_address > compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN_OR_EQUAL:
                        result = (m_address <= compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN_OR_EQUAL:
                        result = (m_address >= compareTo.m_address);
                        break;

                    // The sample debug engine doesn't understand scopes or functions
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_SCOPE:
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_FUNCTION:
                        result = (m_address == compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_MODULE:
                        result = (m_address == compareTo.m_address);
                        if (result == false)
                        {
                            //DebuggedModule module = m_engine.DebuggedProcess.ResolveAddress(m_address);

                            //if (module != null)
                            //{
                            //    result = (compareTo.m_address >= module.BaseAddress) &&
                            //        (compareTo.m_address < module.BaseAddress + module.Size);
                            //}
                        }
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_PROCESS:
                        result = true;
                        break;

                    default:
                        // A new comparison was invented that we don't support
                        return(VSConstants.E_NOTIMPL);
                    }

                    if (result)
                    {
                        pdwMemoryContext = c;
                        return(VSConstants.S_OK);
                    }
                }

                return(VSConstants.S_FALSE);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #20
0
    void OnEntityResLoaded(string resName, string resPath, UnityEngine.Object resObject, System.Object userData)
    {
        IGameObject go     = userData as IGameObject;
        Entity      entity = userData as Entity;

        if (go == null || entity == null)
        {
            throw new Exception("World::OnResLoaded: userData cannot transfer to IGameObject or Entity");
        }
        if (KBEngineApp.app.findEntity(entity.id) == null)
        {
            Debug.LogWarningFormat("World::OnEntityResLoaded:发现entity已经不存在,则不需要加载资源了");
            return;
        }
        float y = entity.position.y;
        //if (entity.isOnGround)
        //	y = 1.3f;
        Vector3    pos       = new Vector3(entity.position.x, y, entity.position.z);
        Quaternion rotation  = Quaternion.Euler(EngineUtils.EngineDirectionToUnity(entity.direction));
        GameObject renderObj = GameObject.Instantiate(resObject, pos, rotation) as GameObject;

        renderObj.name = entity.className + "_" + entity.id;
        //该方法会由Entity的实现类去完成Unity相关组件的添加和初始化
        go.SetRenderObj(renderObj);
        var synchronizer = renderObj.GetComponent <BaseSynchronizer>();

        if (synchronizer != null)
        {
            synchronizer.SetDestPosition(entity.position);
            synchronizer.SetDestDirection(EngineUtils.EngineDirectionToUnity(entity.direction));
            synchronizer.SpaceID = KBEngineApp.app.spaceID;
            _entitySynchronizerDict.Add(entity.id, synchronizer);
        }



        EntityUnityComponent component = null;

        if (entity.isPlayer())
        {        //如果是玩家自己,需要先disable一下,等待地形完成加载
            _playerEntity = renderObj.GetComponent <EntityUnityComponent>();
        }
        component = renderObj.GetComponent <EntityUnityComponent>();

        if (component == null)
        {
            Debug.LogErrorFormat("Entity资源加载后,竟然没有EntityUnityComponent!,entityId={0}, className={1}", entity.id, entity.className);
            return;
        }
        _entityList.Add(component);
        _entityDict.Add(entity.id, component);

        if (OnEntityEnter != null)
        {
            OnEntityEnter(component);
        }

        if (entity.isPlayer())
        {
            if (_terrain != null)
            {
                FinishMyselfLoadTask();
            }
        }
    }
        // Compares the memory context to each context in the given array in the manner indicated by compare flags,
        // returning an index of the first context that matches.
        public int Compare(enum_CONTEXT_COMPARE contextCompare, IDebugMemoryContext2[] compareToItems, uint compareToLength, out uint foundIndex)
        {
            foundIndex = uint.MaxValue;

            try
            {
                for (uint c = 0; c < compareToLength; c++)
                {
                    AD7MemoryAddress compareTo = compareToItems[c] as AD7MemoryAddress;
                    if (compareTo == null)
                    {
                        continue;
                    }

                    if (!AD7Engine.ReferenceEquals(_engine, compareTo._engine))
                    {
                        continue;
                    }

                    bool result;

                    switch (contextCompare)
                    {
                    case enum_CONTEXT_COMPARE.CONTEXT_EQUAL:
                        result = (_address == compareTo._address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN:
                        result = (_address < compareTo._address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN:
                        result = (_address > compareTo._address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN_OR_EQUAL:
                        result = (_address <= compareTo._address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN_OR_EQUAL:
                        result = (_address >= compareTo._address);
                        break;

                    // The debug engine doesn't understand scopes
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_SCOPE:
                        result = (_address == compareTo._address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_PROCESS:
                        result = true;
                        break;

                    default:
                        // A new comparison was invented that we don't support
                        return(VSConstants.E_NOTIMPL);
                    }

                    if (result)
                    {
                        foundIndex = c;
                        return(VSConstants.S_OK);
                    }
                }

                return(VSConstants.S_FALSE);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #22
0
        // Binds this pending breakpoint to one or more code locations.
        int IDebugPendingBreakpoint2.Bind()
        {
            if (CanBind())
            {
                IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(_bpRequestInfo.bpLocation.unionmember2));

                // Get the name of the document that the breakpoint was put in
                EngineUtils.CheckOk(docPosition.GetFileName(out global::System.String documentName));


                // Get the location in the document that the breakpoint is in.
                TEXT_POSITION[] startPosition = new TEXT_POSITION[1];
                TEXT_POSITION[] endPosition   = new TEXT_POSITION[1];
                EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition));

                lock (_boundBreakpoints)
                {
                    if (_bpRequestInfo.guidLanguage == DebuggerConstants.guidLanguagePython)
                    {
                        PythonBreakpoint bp = _engine.Process.AddBreakpoint(
                            documentName,
                            (int)(startPosition[0].dwLine + 1),
                            _bpRequestInfo.bpCondition.styleCondition.ToPython(),
                            _bpRequestInfo.bpCondition.bstrCondition,
                            _bpRequestInfo.bpPassCount.stylePassCount.ToPython(),
                            (int)_bpRequestInfo.bpPassCount.dwPassCount);

                        AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(_engine, bp, GetDocumentContext(bp));
                        AD7BoundBreakpoint      boundBreakpoint      = new AD7BoundBreakpoint(_engine, bp, this, breakpointResolution, _enabled);
                        _boundBreakpoints.Add(boundBreakpoint);
                        _bpManager.AddBoundBreakpoint(bp, boundBreakpoint);

                        if (_enabled)
                        {
                            TaskHelpers.RunSynchronouslyOnUIThread(ct => bp.AddAsync(ct));
                        }

                        return(VSConstants.S_OK);
                    }
                    else if (_bpRequestInfo.guidLanguage == DebuggerConstants.guidLanguageDjangoTemplate)
                    {
                        // bind a Django template
                        PythonBreakpoint bp = _engine.Process.AddDjangoBreakpoint(
                            documentName,
                            (int)(startPosition[0].dwLine + 1)
                            );

                        AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(_engine, bp, GetDocumentContext(bp));
                        AD7BoundBreakpoint      boundBreakpoint      = new AD7BoundBreakpoint(_engine, bp, this, breakpointResolution, _enabled);
                        _boundBreakpoints.Add(boundBreakpoint);
                        _bpManager.AddBoundBreakpoint(bp, boundBreakpoint);

                        if (_enabled)
                        {
                            TaskHelpers.RunSynchronouslyOnUIThread(ct => bp.AddAsync(ct));
                        }

                        return(VSConstants.S_OK);
                    }
                }
            }

            // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc...
            // The Python engine does not support this.
            // TODO: send an instance of IDebugBreakpointErrorEvent2 to the UI and return a valid instance of IDebugErrorBreakpoint2 from
            // IDebugPendingBreakpoint2::EnumErrorBreakpoints. The debugger will then display information about why the breakpoint did not
            // bind to the user.
            return(VSConstants.S_FALSE);
        }
예제 #23
0
        // Binds this pending breakpoint to one or more code locations.
        int IDebugPendingBreakpoint2.Bind()
        {
            try
            {
                if (CanBind())
                {
                    var xDocPos = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(mBpRequestInfo.bpLocation.unionmember2));

                    // Get the name of the document that the breakpoint was put in
                    string xDocName;
                    EngineUtils.CheckOk(xDocPos.GetFileName(out xDocName));
                    xDocName = xDocName.ToLower(); //Bug: Some filenames were returned with the drive letter as lower case but in DocumentGUIDs it was captialised so file-not-found!

                    // Get the location in the document that the breakpoint is in.
                    var xStartPos = new TEXT_POSITION[1];
                    var xEndPos   = new TEXT_POSITION[1];
                    EngineUtils.CheckOk(xDocPos.GetRange(xStartPos, xEndPos));

                    uint xAddress   = 0;
                    var  xDebugInfo = mEngine.mProcess.mDebugInfoDb;

                    // We must check for DocID. This is important because in a solution that contains many projects,
                    // VS will send us BPs from other Cosmos projects (and possibly non Cosmos ones, didnt look that deep)
                    // but we wont have them in our doc list because it contains only ones from the currently project
                    // to run.
                    long xDocID;
                    if (xDebugInfo.DocumentGUIDs.TryGetValue(xDocName, out xDocID))
                    {
                        // Find which Method the Doc, Line, Col are in.
                        // Must add +1 for both Line and Col. They are 0 based, while SP ones are 1 based.
                        // () around << are VERY important.. + has precedence over <<
                        long xPos = (((long)xStartPos[0].dwLine + 1) << 32) + xStartPos[0].dwColumn + 1;

                        try
                        {
                            var xMethod = xDebugInfo.GetMethodByDocumentIDAndLinePosition(xDocID, xPos, xPos);
                            var asm     = xDebugInfo.GetAssemblyFileById(xMethod.AssemblyFileID);

                            // We have the method. Now find out what Sequence Point it belongs to.
                            var xSPs = xDebugInfo.GetSequencePoints(asm.Pathname, xMethod.MethodToken);
                            var xSP  = xSPs.Single(q => q.LineColStart <= xPos && q.LineColEnd >= xPos);

                            // We have the Sequence Point, find the MethodILOp
                            var xOp = xDebugInfo.GetFirstMethodIlOpByMethodIdAndILOffset(xMethod.ID, xSP.Offset);

                            // Get the address of the Label
                            xAddress = xDebugInfo.GetAddressOfLabel(xOp.LabelName);


                            if (xAddress > 0)
                            {
                                var xBPR = new AD7BreakpointResolution(mEngine, xAddress, GetDocumentContext(xAddress));
                                var xBBP = new AD7BoundBreakpoint(mEngine, xAddress, this, xBPR);
                                mBoundBPs.Add(xBBP);
                            }

                            // Ask the symbol engine to find all addresses in all modules with symbols that match this source and line number.
                            //uint[] addresses = mEngine.DebuggedProcess.GetAddressesForSourceLocation(null, documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn);
                            lock (mBoundBPs)
                            {
                                //foreach (uint addr in addresses) {
                                //    AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(mEngine, addr, GetDocumentContext(addr));
                                //    AD7BoundBreakpoint boundBreakpoint = new AD7BoundBreakpoint(mEngine, addr, this, breakpointResolution);
                                //    m_boundBreakpoints.Add(boundBreakpoint);
                                //    mEngine.DebuggedProcess.SetBreakpoint(addr, boundBreakpoint);
                                //}
                            }
                        }
                        catch (InvalidOperationException)
                        {
                            //No elements in potXMethods sequence!
                            return(VSConstants.S_FALSE);
                        }
                    }
                    return(VSConstants.S_OK);
                }
                else
                {
                    // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc...
                    // The sample engine does not support this, but a real world engine will want to send an instance of IDebugBreakpointErrorEvent2 to the
                    // UI and return a valid instance of IDebugErrorBreakpoint2 from IDebugPendingBreakpoint2::EnumErrorBreakpoints. The debugger will then
                    // display information about why the breakpoint did not bind to the user.
                    return(VSConstants.S_FALSE);
                }
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #24
0
        // Gets the MODULE_INFO that describes this module.
        // This is how the debugger obtains most of the information about the module.
        int IDebugModule2.GetInfo(enum_MODULE_INFO_FIELDS dwFields, MODULE_INFO[] infoArray)
        {
            try
            {
                MODULE_INFO info = new MODULE_INFO();

                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_NAME))
                {
                    //info.m_bstrName = System.IO.Path.GetFileName(this.DebuggedModule.Name);
                    info.m_bstrName     = "DEADBEEF";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_NAME;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_URL))
                {
                    //info.m_bstrUrl = this.DebuggedModule.Name;
                    info.m_bstrUrl      = "DEADBEEF";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_URL;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_LOADADDRESS))
                {
                    //info.m_addrLoadAddress = (ulong)this.DebuggedModule.BaseAddress;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_LOADADDRESS;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_PREFFEREDADDRESS))
                {
                    // A debugger that actually supports showing the preferred base should crack the PE header and get
                    // that field. This debugger does not do that, so assume the module loaded where it was suppose to.
                    //info.m_addrPreferredLoadAddress = (ulong)this.DebuggedModule.BaseAddress;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_PREFFEREDADDRESS;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_SIZE))
                {
                    //info.m_dwSize = this.DebuggedModule.Size;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_SIZE;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_LOADORDER))
                {
                    //info.m_dwLoadOrder = this.DebuggedModule.GetLoadOrder();
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_LOADORDER;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_URLSYMBOLLOCATION))
                {
                    //if (this.DebuggedModule.SymbolsLoaded)
                    {
                        //info.m_bstrUrlSymbolLocation = this.DebuggedModule.SymbolPath;
                        info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_URLSYMBOLLOCATION;
                    }
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_FLAGS))
                {
                    info.m_dwModuleFlags = 0;
                    //if (this.DebuggedModule.SymbolsLoaded)
                    {
                        info.m_dwModuleFlags |= (enum_MODULE_FLAGS.MODULE_FLAG_SYMBOLS);
                    }
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_FLAGS;
                }


                infoArray[0] = info;

                return(VSConstants.S_OK);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #25
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("Node debugging only supports one program in a process");
                throw new ArgumentException();
            }

            IDebugProgram2 program   = rgpPrograms[0];
            int            processId = EngineUtils.GetProcessId(program);

            if (processId == 0)
            {
                // engine only supports system processes
                Debug.WriteLine("NodeEngine failed to get process id during attach");
                return(VSConstants.E_NOTIMPL);
            }

            EngineUtils.RequireOk(program.GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null)
            {
                // TODO: Where do we get the language version from?
                _events = ad7Callback;

                // Check if we're attaching remotely using the node remote debugging transport
                if (!NodeProcess.TryAttach(processId, out _process))
                {
                    MessageBox.Show("Failed to attach debugger:\n", null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(VSConstants.E_FAIL);
                }

                AttachProcessEvents(_process);
                _attached = true;
            }
            else
            {
                if (processId != _process.Id)
                {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return(VSConstants.E_FAIL);
                }
            }

            AD7EngineCreateEvent.Send(this);

            lock (_syncLock)
            {
                _programCreated = true;

                if (_processLoadedThread != null)
                {
                    SendLoadComplete(_processLoadedThread);
                }
            }

            Debug.WriteLine("NodeEngine Attach returning S_OK");
            return(VSConstants.S_OK);
        }