Ejemplo n.º 1
0
        public int GetThreadProperties(enum_THREADPROPERTY_FIELDS fields, THREADPROPERTIES[] ptp)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugThread2.GetThreadProperties {0}", fields);
            var info = new THREADPROPERTIES();

            if (fields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_ID))
            {
                info.dwThreadId = (uint)tid;
                info.dwFields  |= enum_THREADPROPERTY_FIELDS.TPF_ID;
            }
            if (fields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_NAME))
            {
                info.bstrName  = GetNameAsync().Await(DalvikProcess.VmTimeout);
                info.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
            }
            if (fields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_STATE))
            {
                info.dwThreadState = (uint)State;
                info.dwFields     |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
            }
            if (fields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT))
            {
                info.dwSuspendCount = (uint)GetSuspendCountAsync().Await(DalvikProcess.VmTimeout);
                info.dwFields      |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
            }
            if (fields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_PRIORITY))
            {
                info.bstrPriority = "Normal";
                info.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
            }
            ptp[0] = info;
            return(VSConstants.S_OK);
        }
Ejemplo n.º 2
0
            /// <summary>
            /// Debugger has connected.
            /// </summary>
            private void OnDebuggerDalvikEvent(object sender, JdwpEvent e)
            {
                DLog.Debug(DContext.VSDebuggerEvent, "DalvikEvent {0}", e);
                var debugger = (XDebugger)sender;

                if (!debugger.Connected || token.IsCancellationRequested)
                {
                    return;
                }

                if ((debugger.AppName == packageName) && !debuggerLaunched)
                {
                    // Inform status
                    debuggerLaunched = true;
                    outputPane.LogLine("Found process to debug");

                    // We've found the process to debug.
                    var currentMonitor = jdwpMonitor;
                    jdwpMonitor = null;
                    debugger.Attach(currentMonitor);
                    DisposeOtherDebuggers(debugger);

                    // Prepare the debugger
                    stateUpdate(LauncherStates.Attaching, string.Empty);
                    outputPane.LogLine("Preparing debugger launch");
                    try
                    {
                        LaunchVsDebugEngine(ide, apkPath, debugger, launchFlags, stateUpdate);
                    }
                    catch (Exception ex)
                    {
                        stateUpdate(LauncherStates.Error, ex.Message);
                    }
                }
            }
Ejemplo n.º 3
0
        /// <summary>
        /// Removes the specified exception so it is no longer handled by the debug engine.
        /// </summary>
        public int RemoveSetException(EXCEPTION_INFO[] pException)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.RemoveSetException");
            var copyToProgram = false;

            foreach (var info in pException)
            {
                if (info.guidType == GuidList.Guids.guidDot42DebuggerId)
                {
                    if (info.bstrExceptionName == ExceptionConstants.TopLevelName)
                    {
                        exceptionBehaviorMap.ResetDefaults();
                        copyToProgram = true;
                    }
                    else
                    {
                        exceptionBehaviorMap[info.bstrExceptionName] = null;
                        copyToProgram = true;
                    }
                }
            }
            if (copyToProgram)
            {
                CopyExceptionMapToProgram();
            }
            return(VSConstants.S_OK);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Specifies how the debug engine (DE) should handle a given exception.
        /// </summary>
        public int SetException(EXCEPTION_INFO[] pException)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.SetException");
            var copyToProgram = false;

            foreach (var info in pException)
            {
                if (info.guidType == GuidList.Guids.guidDot42DebuggerId)
                {
                    if (info.bstrExceptionName == ExceptionConstants.TopLevelName)
                    {
                        exceptionBehaviorMap.DefaultStopOnThrow  = info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE);
                        exceptionBehaviorMap.DefaultStopUncaught = info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT);
                        copyToProgram = true;
                    }
                    else
                    {
                        var behavior = new ExceptionBehavior(
                            info.bstrExceptionName,
                            info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE),
                            info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT));
                        exceptionBehaviorMap[info.bstrExceptionName] = behavior;
                        copyToProgram = true;
                    }
                }
            }
            if (copyToProgram)
            {
                CopyExceptionMapToProgram();
            }
            return(VSConstants.S_OK);
        }
Ejemplo n.º 5
0
            /// <summary>
            // Sets the value of one or more local variables. Each variable must be visible at the current frame code index.
            // For primitive values, the value's type must match the variable's type exactly. For object values, there must
            // be a widening reference conversion from the value's type to the variable's type and the variable's type must
            // be loaded.
            // Even if local variable information is not available, values can be set, if the front-end is able to determine
            // the correct local variable index. (Typically, this index can be determined for method arguments from the
            // method signature without access to the local variable table information.)
            /// </summary>
            public Task SetValuesAsync(ThreadId threadId, FrameId frameId, params SlotValue[] slotValues)
            {
                var conn = ConnectionOrError;

                DLog.Debug(DContext.DebuggerLibCommands, () => string.Format("StackFrame.SetValues {0}", string.Join(", ", slotValues.Select(x => x.ToString()))));
                var t = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 2, 4000 /* we don't know how long the packet is going to be... */,
                                                                x =>
                {
                    var data = x.Data;
                    threadId.WriteTo(data);
                    frameId.WriteTo(data);
                    data.SetInt(slotValues.Length);
                    foreach (var value in slotValues)
                    {
                        value.Write(data);
                    }
                    x.Length = data.Offset;
                }));

                return(t.ContinueWith(x =>
                {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                }));
            }
Ejemplo n.º 6
0
        /// <summary>
        /// Informs a debug engine (DE) that the program specified has been atypically terminated and that the DE should clean up all references
        /// to the program and send a program destroy event.
        /// </summary>
        public int DestroyProgram(IDebugProgram2 pProgram)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.DestroyProgram");

            // Avoid recursion
            if (destroying)
            {
                return(VSConstants.S_OK);
            }
            destroying = true;

            var program = pProgram as DebugProgram;

            if (program == null)
            {
                return(VSConstants.E_INVALIDARG);
            }
            var port = (IDebugPortNotify2)program.Process.Port;

            port.RemoveProgramNode(program);

            if (this.program == program)
            {
                // Detach
                this.program = null;
            }

            //eventCallback.Send(program, new ProgramDestroyEvent(0));
            return(VSConstants.S_OK);
        }
Ejemplo n.º 7
0
 public int GetPhysicalStackRange(out ulong paddrMin, out ulong paddrMax)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugStackFrame.GetPhysicalStackRange");
     paddrMin = 0;
     paddrMax = 0;
     return(VSConstants.E_NOTIMPL);
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Step out of the current method
        /// </summary>
        public void StepOut(DebugThread thread)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "Dot42Debugger.StepOut");
            var stepDepth = Jdwp.StepDepth.Out;

            StepAsync(new StepRequest(thread, stepDepth));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Handle Thread Status messages
        /// </summary>
        internal static void HandleTHST(Chunk chunk, Action <DalvikEvent> onEvent)
        {
            var data      = chunk.Data;
            var hdrLength = data.GetByte();
            var entryLen  = data.GetByte();
            var count     = data.GetInt16();

            data.Skip(hdrLength - 4);

            var list = new List <ThreadStatusInfo>();

            for (var i = 0; i < count; i++)
            {
                var id       = new ThreadId(data, 4);
                var state    = data.GetByte();
                var tid      = data.GetInt();
                var utime    = data.GetInt();
                var stime    = data.GetInt();
                var isDaemon = data.GetByte();
                data.Skip(entryLen - 18);

                DLog.Debug(DContext.DebuggerLibEvent, "THST id={0}, state={1}, tid={2}, utime={3}, stime={4}", id, state, tid, utime, stime);

                list.Add(new ThreadStatusInfo(id, (ThreadStates)state));
            }
            onEvent(new ThreadStatus(list));
        }
Ejemplo n.º 10
0
        public int EnumBreakpoints(out IEnumDebugBoundBreakpoints2 ppEnum)
        {
            DLog.Debug(DContext.VSDebuggerEvent, "BreakpointEvent.EnumBreakpoints");

            ppEnum = new BoundBreakpointsEnum(new[] { breakpoint });
            return(VSConstants.S_OK);
        }
Ejemplo n.º 11
0
        public int EnumProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, uint nRadix, ref Guid guidFilter, uint dwTimeout, out uint pcelt, out IEnumDebugPropertyInfo2 ppEnum)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "DebugStackFrame.EnumProperties");
            var list = new List <DebugProperty>();

            if (guidFilter == AD7Guids.guidFilterLocalsPlusArgs ||
                guidFilter == AD7Guids.guidFilterAllLocalsPlusArgs ||
                guidFilter == AD7Guids.guidFilterAllLocals)
            {
                AddLocalProperties(list);
                AddParameterProperties(list);
            }
            else if (guidFilter == AD7Guids.guidFilterLocals)
            {
                AddLocalProperties(list);
            }
            else if (guidFilter == AD7Guids.guidFilterArgs)
            {
                AddParameterProperties(list);
            }
            else
            {
                pcelt  = 0;
                ppEnum = null;
                return(VSConstants.E_NOTIMPL);
            }

            pcelt  = (uint)list.Count;
            ppEnum = new PropertyEnum(list.Select(x => x.ConstructDebugPropertyInfo(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_STANDARD)));
            return(VSConstants.S_OK);
        }
Ejemplo n.º 12
0
 public int EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugProgram2.EnumCodePaths");
     ppEnum   = null;
     ppSafety = null;
     return(VSConstants.E_NOTIMPL);
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Send handshake packet.
        /// </summary>
        private void SendHandshake()
        {
            DLog.Debug(DContext.DebuggerLibJdwpConnection, "SendHandshake for pid {0}", pid);

            // Send handshape
            Write(Handshake);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Performs a step.
        /// </summary>
        public int Step(IDebugThread2 pThread, enum_STEPKIND stepKind, enum_STEPUNIT stepUnit)
        {
            // This method is deprecated. Use the IDebugProcess3::Step method instead.
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugProgram2.Step kind={0}, step={1}", stepKind, stepUnit);
            Jdwp.StepDepth stepDepth;
            switch (stepKind)
            {
            case enum_STEPKIND.STEP_INTO:
                stepDepth = Jdwp.StepDepth.Into;
                break;

            case enum_STEPKIND.STEP_BACKWARDS:
                return(VSConstants.E_NOTIMPL);

            case enum_STEPKIND.STEP_OVER:
                stepDepth = Jdwp.StepDepth.Over;
                break;

            case enum_STEPKIND.STEP_OUT:
                stepDepth = Jdwp.StepDepth.Out;
                break;

            default:
                return(VSConstants.E_INVALIDARG);
            }

            var stepMode = stepUnit == enum_STEPUNIT.STEP_INSTRUCTION ? StepMode.SingleInstruction : StepMode.Line;

            StepAsync(new StepRequest((DalvikThread)pThread, stepDepth, stepMode));
            return(VSConstants.S_OK);
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Gets the name and identifier of the debug engine (DE) running a program.
 /// </summary>
 public int GetEngineInfo(out string pbstrEngine, out Guid pguidEngine)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugProgram2.GetEngineInfo");
     pbstrEngine = DebugEngine.Name;
     pguidEngine = new Guid(GuidList.Strings.guidDot42DebuggerId);
     return(VSConstants.S_OK);
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Notify visual studio of a trigger in this breakpoint.
        /// </summary>
        internal void OnTrigger(DebuggerLib.Events.Jdwp.Breakpoint @event)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "DebugBoundBreakpoint.OnTrigger");

            // Prepare
            var program = breakpointManager.Program;

            // Increment hitcount
            hitCount++;

            // Find thread
            DalvikThread thread;

            if (!program.ThreadManager.TryGet(@event.ThreadId, out thread))
            {
                thread = program.ThreadManager.MainThread();
            }

            // Set resolution info
            resolution.Thread = (DebugThread)thread;

            // Send event
            DLog.Debug(DContext.VSDebuggerComCall, "DebugBoundBreakpoint.OnTrigger.Send");
            breakpointManager.Send((DebugThread)thread, new BreakpointEvent(this));
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Continues running this program from a stopped state. Any previous execution state (such as a step) is preserved, and the program starts executing again.
 /// </summary>
 public int Continue(IDebugThread2 pThread)
 {
     // This method is deprecated. Use the IDebugProcess3::Continue method instead.
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugProgram2.Continue");
     Debugger.VirtualMachine.ResumeAsync();
     return(VSConstants.S_OK);
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Handle non-reply chunks
        /// </summary>
        private void ChunkHandler(Chunk chunk)
        {
            DLog.Debug(DContext.DebuggerLibDebugger, "Handle Chunk {0}", chunk);
            var type = chunk.Type;

            if (type == DdmsCommandSet.HeloType)
            {
                var data = chunk.Data;
                var clientProtocolVersion = data.GetInt();
                var pid        = data.GetInt();
                var vmIdentLen = data.GetInt();
                var appNameLen = data.GetInt();
                var vmIdent    = data.GetString(vmIdentLen);
                var appName    = data.GetString(appNameLen);
                SetAppName(appName);
            }
            else if (type == DdmsCommandSet.ApnmType)
            {
                var data       = chunk.Data;
                var appNameLen = data.GetInt();
                var appName    = data.GetString(appNameLen);
                SetAppName(appName);
            }
            else if (type == DdmsCommandSet.WaitType)
            {
                var data   = chunk.Data;
                var reason = data.GetByte();
                OnEventAsync(new WaitForDebugger(reason));
            }
            else if (type == DdmsCommandSet.ThstType)
            {
                ThreadStatus.HandleTHST(chunk, OnEventAsync);
            }
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Executes the program. The thread is returned to give the debugger information on which thread the user is viewing when executing.
 /// </summary>
 public int ExecuteOnThread(IDebugThread2 pThread)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugProgram2.ExecuteOnThread");
     // Resume VM
     ResumeAsync();
     return(VSConstants.S_OK);
 }
Ejemplo n.º 20
0
            /// <summary>
            /// Returns the value of one or more local variables in a given frame. Each variable must be visible at the frame's code index.
            /// Even if local variable information is not available, values can be retrieved if the front-end is able to determine the correct
            /// local variable index. (Typically, this index can be determined for method arguments from the method signature without access to
            /// the local variable table information.)
            /// </summary>
            public Task <List <Value> > GetValuesAsync(ThreadId threadId, FrameId frameId, SlotRequest[] slots)
            {
                var conn = ConnectionOrError;

                DLog.Debug(DContext.DebuggerLibCommands, () => string.Format("StackFrame.GetValues {0}", string.Join(", ", slots.Select(x => x.ToString()))));
                var t = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, threadId.Size + frameId.Size + 4 + (slots.Length * 5),
                                                                x => {
                    var data = x.Data;
                    threadId.WriteTo(data);
                    frameId.WriteTo(data);
                    data.SetInt(slots.Length);
                    foreach (var slot in slots)
                    {
                        data.SetInt(slot.Slot);
                        data.SetByte((byte)slot.Tag);
                    }
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <Value>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var value = new Value(data);
                        list.Add(value);
                    }
                    return list;
                }));
            }
Ejemplo n.º 21
0
 /// <summary>
 /// Gets the name of the session that is debugging this process. An IDE can display this information to a user who is debugging a particular process on a particular machine.
 /// </summary>
 public int GetAttachedSessionName(out string pbstrSessionName)
 {
     // This method is deprecated, and its implementation should always return E_NOTIMPL.
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugProcess2.GetAttachedSessionName");
     pbstrSessionName = null;
     return(VSConstants.E_NOTIMPL);
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Gets the title, friendly name, or file name of the process.
        /// </summary>
        public int GetName(enum_GETNAME_TYPE gnType, out string pbstrName)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugProcess2.GetName");
            switch (gnType)
            {
            case enum_GETNAME_TYPE.GN_FILENAME:
            case enum_GETNAME_TYPE.GN_MONIKERNAME:
                pbstrName = apkPath;
                break;

            case enum_GETNAME_TYPE.GN_NAME:
            case enum_GETNAME_TYPE.GN_BASENAME:
            case enum_GETNAME_TYPE.GN_TITLE:
                pbstrName = Path.GetFileName(apkPath);
                break;

            case enum_GETNAME_TYPE.GN_URL:
                pbstrName = "<url>";
                break;

            case enum_GETNAME_TYPE.GN_STARTPAGEURL:
                pbstrName = "<startpageurl>";
                break;

            default:
                pbstrName = null;
                return(VSConstants.S_FALSE);
            }
            return(VSConstants.S_OK);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected internal virtual void OnExceptionEvent(Events.Jdwp.Exception @event, DalvikThread thread)
        {
            // Log
            DLog.Debug(DContext.VSDebuggerEvent, "OnExceptionEvent location: {0}", @event.Location);

            // Save exception in thread
            thread.CurrentException = @event.ExceptionObject;
        }
Ejemplo n.º 24
0
 public int SetPassCount(BP_PASSCOUNT bpPassCount)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugBoundBreakpoint.SetPassCount");
     if (IsDeleted)
     {
         return(HResults.E_BP_DELETED);
     }
     return(pendingBreakpoint.SetPassCount(bpPassCount));
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Sets or changes the condition associated with this pending breakpoint.
 /// </summary>
 public int SetCondition(BP_CONDITION bpCondition)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugPendingBreakpoint.SetCondition");
     if (IsDeleted)
     {
         return(HResults.E_BP_DELETED);
     }
     throw new NotImplementedException();
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Toggles the virtualized state of this pending breakpoint.
 /// </summary>
 public int Virtualize(int fVirtualize)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugPendingBreakpoint.Virtualize");
     if (IsDeleted)
     {
         return(HResults.E_BP_DELETED);
     }
     return(VSConstants.S_OK);
 }
Ejemplo n.º 27
0
        /// <summary>
        /// Gets the name of the stack frame, typically the method name.
        /// </summary>
        public int GetName(out string pbstrName)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "DebugStackFrame.GetName");
            FRAMEINFO info;

            SetFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME, out info);
            pbstrName = info.m_bstrFuncName;
            return(VSConstants.S_OK);
        }
Ejemplo n.º 28
0
 public int SetCondition(BP_CONDITION bpCondition)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugBoundBreakpoint.SetCondition");
     if (IsDeleted)
     {
         return(HResults.E_BP_DELETED);
     }
     return(pendingBreakpoint.SetCondition(bpCondition));
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Gets the system process identifier.
 /// </summary>
 public int GetPhysicalProcessId(AD_PROCESS_ID[] pProcessId)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugProcess2.GetPhysicalProcessId");
     pProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
     //pProcessId[0].dwProcessId = (uint) processId;
     pProcessId[0].dwProcessId   = 0;
     pProcessId[0].guidProcessId = guid;
     return(VSConstants.S_OK);
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Gets a port by it's guid.
        /// </summary>
        public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.GetPort");
            var guid = guidPort;
            var port = ports.Values.FirstOrDefault(x => x.Guid == guid);

            ppPort = port;
            return((port != null) ? VSConstants.S_OK : VSConstants.S_FALSE);
        }