Beispiel #1
0
        public AD7StackFrame(AD7Engine engine, AD7Thread thread, ThreadContext threadContext)
        {
            Debug.Assert(threadContext != null, "ThreadContext is null");

            Engine = engine;
            Thread = thread;
            ThreadContext = threadContext;

            _textPosition = threadContext.TextPosition;
            _functionName = threadContext.Function;

            if (threadContext.pc.HasValue)
            {
                _codeCxt = new AD7MemoryAddress(this.Engine, threadContext.pc.Value, _functionName);
            }

            if (_textPosition != null)
            {
                _documentCxt = new AD7DocumentContext(_textPosition, _codeCxt);

                if (_codeCxt != null)
                {
                    _codeCxt.SetDocumentContext(_documentCxt);
                }
            }
        }
Beispiel #2
0
        private VariableInformation(ThreadContext ctx, AD7Engine engine, AD7Thread thread)
        {
            _engine          = engine;
            _debuggedProcess = _engine.DebuggedProcess;
            _ctx             = ctx;
            Client           = thread;

            IsParameter     = false;
            IsChild         = false;
            _attribsFetched = false;
            Access          = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE;
            _fullname       = null;

            lock (this._debuggedProcess.ActiveVariables)
            {
                this._debuggedProcess.ActiveVariables.Add(this);
            }
        }
Beispiel #3
0
        public AD7StackFrame(AD7Engine engine, AD7Thread thread, ThreadContext threadContext)
        {
            Debug.Assert(threadContext != null, "ThreadContext is null");

            Engine        = engine;
            Thread        = thread;
            ThreadContext = threadContext;

            _textPosition = threadContext.TextPosition;
            _functionName = threadContext.Function;

            if (threadContext.pc.HasValue)
            {
                _codeCxt = new AD7MemoryAddress(this.Engine, threadContext.pc.Value, _functionName);
            }
            if (_textPosition != null)
            {
                var docContext = new AD7DocumentContext(_textPosition, _codeCxt);
                _codeCxt.SetDocumentContext(docContext);
            }
        }
Beispiel #4
0
        private void FilterUnknownFrames(System.Collections.Generic.List <ThreadContext> stackFrames)
        {
            bool lastWasQuestion = false;

            for (int i = 0; i < stackFrames.Count;)
            {
                // replace sequences of "??" with one UnknownCode frame
                if (stackFrames[i].Function == null || stackFrames[i].Function.Equals("??", StringComparison.Ordinal))
                {
                    if (lastWasQuestion)
                    {
                        stackFrames.RemoveAt(i);
                        continue;
                    }
                    lastWasQuestion = true;
                    stackFrames[i]  = new ThreadContext(stackFrames[i].pc, stackFrames[i].TextPosition, ResourceStrings.UnknownCode, stackFrames[i].Level, null);
                }
                else
                {
                    lastWasQuestion = false;
                }
                i++;
            }
        }
Beispiel #5
0
 private void FilterUnknownFrames(System.Collections.Generic.List<ThreadContext> stackFrames)
 {
     bool lastWasQuestion = false;
     for (int i = 0; i < stackFrames.Count;)
     {
         // replace sequences of "??" with one UnknownCode frame
         if (stackFrames[i].Function == null || stackFrames[i].Function.Equals("??", StringComparison.Ordinal))
         {
             if (lastWasQuestion)
             {
                 stackFrames.RemoveAt(i);
                 continue;
             }
             lastWasQuestion = true;
             stackFrames[i] = new ThreadContext(stackFrames[i].pc, stackFrames[i].TextPosition, ResourceStrings.UnknownCode, stackFrames[i].Level, null);
         }
         else
         {
             lastWasQuestion = false;
         }
         i++;
     }
 }
Beispiel #6
0
        private async Task <ThreadContext> CollectThreadsInfo(int cxtThreadId)
        {
            ThreadContext ret = null;
            // set of threads has changed or thread locations have been asked for
            Results threadsinfo = await _debugger.MICommandFactory.ThreadInfo();

            if (threadsinfo.ResultClass != ResultClass.done)
            {
                Debug.Fail("Failed to get thread info");
            }
            else
            {
                var tlist = threadsinfo.Find <ValueListValue>("threads");

                // update our thread list
                lock (_threadList)
                {
                    foreach (var thread in _threadList)
                    {
                        thread.Alive = false;
                    }

                    foreach (var t in tlist.Content)
                    {
                        bool bNew     = false;
                        var  thread   = SetThreadInfoFromResultValue(t, out bNew);
                        int  threadId = thread.Id;

                        if (bNew)
                        {
                            NewThreads.Add(thread);
                        }

                        TupleValue[] frames = ((TupleValue)t).FindAll <TupleValue>("frame");

                        if (frames.Any())
                        {
                            List <ThreadContext> stack = new List <ThreadContext>();
                            stack.AddRange(frames.Select(frame => CreateContext(frame)));

                            _topContext[threadId] = stack[0];
                            if (threadId == cxtThreadId)
                            {
                                ret = _topContext[threadId];
                            }

                            if (stack.Count > 1)
                            {
                                _stackFrames[threadId] = stack;
                            }
                        }
                    }

                    foreach (var thread in _threadList.ToList())
                    {
                        if (!thread.Alive)
                        {
                            DeadThreads.Add(thread);
                            _threadList.Remove(thread);
                        }
                    }

                    _stateChange = false;
                    _full        = true;
                }
            }
            return(ret);
        }
Beispiel #7
0
        //This method gets the value/type info for the method parameters without creating an MI debugger variable for them. For use in the callstack window
        //NOTE: eval is not called
        public async Task<List<SimpleVariableInformation>> GetParameterInfoOnly(AD7Thread thread, ThreadContext ctx)
        {
            List<SimpleVariableInformation> parameters = new List<SimpleVariableInformation>();

            ValueListValue localAndParameters = await MICommandFactory.StackListVariables(PrintValues.SimpleValues, thread.Id, ctx.Level);

            foreach (var results in localAndParameters.Content.Where(r => r.TryFindString("arg") == "1"))
            {
                parameters.Add(new SimpleVariableInformation(results.FindString("name"), /*isParam*/ true, results.FindString("value"), results.FindString("type")));
            }

            return parameters;
        }
Beispiel #8
0
        //This method gets the locals and parameters and creates an MI debugger variable for each one so that we can manipulate them (and expand children, etc.)
        //NOTE: Eval is called
        internal async Task<List<VariableInformation>> GetLocalsAndParameters(AD7Thread thread, ThreadContext ctx)
        {
            List<VariableInformation> variables = new List<VariableInformation>();

            ValueListValue localsAndParameters = await MICommandFactory.StackListVariables(PrintValues.NoValues, thread.Id, ctx.Level);

            foreach (var localOrParamResult in localsAndParameters.Content)
            {
                string name = localOrParamResult.FindString("name");
                bool isParam = localOrParamResult.TryFindString("arg") == "1";
                SimpleVariableInformation simpleInfo = new SimpleVariableInformation(name, isParam);
                VariableInformation vi = await simpleInfo.CreateMIDebuggerVariable(ctx, Engine, thread);
                variables.Add(vi);
            }

            return variables;
        }
Beispiel #9
0
        //This method gets the value/type info for the method parameters without creating an MI debugger varialbe for them. For use in the callstack window
        //NOTE: eval is not called
        public async Task <List <SimpleVariableInformation> > GetParameterInfoOnly(AD7Thread thread, ThreadContext ctx)
        {
            List <SimpleVariableInformation> parameters = new List <SimpleVariableInformation>();

            ValueListValue localAndParameters = await MICommandFactory.StackListVariables(PrintValues.SimpleValues, thread.Id, ctx.Level);

            foreach (var results in localAndParameters.Content.Where(r => r.TryFindString("arg") == "1"))
            {
                parameters.Add(new SimpleVariableInformation(results.FindString("name"), /*isParam*/ true, results.FindString("value"), results.FindString("type")));
            }

            return(parameters);
        }
Beispiel #10
0
        //This method gets the locals and parameters and creates an MI debugger variable for each one so that we can manipulate them (and expand children, etc.)
        //NOTE: Eval is called
        internal async Task <List <VariableInformation> > GetLocalsAndParameters(AD7Thread thread, ThreadContext ctx)
        {
            List <VariableInformation> variables = new List <VariableInformation>();

            ValueListValue localsAndParameters = await MICommandFactory.StackListVariables(PrintValues.NoValues, thread.Id, ctx.Level);

            foreach (var localOrParamResult in localsAndParameters.Content)
            {
                string name    = localOrParamResult.FindString("name");
                bool   isParam = localOrParamResult.TryFindString("arg") == "1";
                SimpleVariableInformation simpleInfo = new SimpleVariableInformation(name, isParam);
                VariableInformation       vi         = await simpleInfo.CreateMIDebuggerVariable(ctx, Engine, thread);

                variables.Add(vi);
            }

            return(variables);
        }
Beispiel #11
0
        private async Task HandleBreakModeEvent(ResultEventArgs results)
        {
            string reason = results.Results.TryFindString("reason");
            int    tid;

            if (!results.Results.Contains("thread-id"))
            {
                Results res = await MICommandFactory.ThreadInfo();

                tid = res.FindInt("id");
            }
            else
            {
                tid = results.Results.FindInt("thread-id");
            }

            ThreadCache.MarkDirty();
            MICommandFactory.DefineCurrentThread(tid);

            DebuggedThread thread = await ThreadCache.GetThread(tid);

            await ThreadCache.StackFrames(thread);  // prepopulate the break thread in the thread cache

            ThreadContext cxt = await ThreadCache.GetThreadContext(thread);

            ThreadCache.SendThreadEvents(this, null);   // make sure that new threads have been pushed to the UI

            //always delete breakpoints pending deletion on break mode
            //the flag tells us if we hit an existing breakpoint pending deletion that we need to continue

            await _breakpointManager.DeleteBreakpointsPendingDeletion();

            //delete varialbes that have been GC'd
            List <string> variablesToDelete = new List <string>();

            lock (VariablesToDelete)
            {
                foreach (var variable in VariablesToDelete)
                {
                    variablesToDelete.Add(variable);
                }
                VariablesToDelete.Clear();
            }

            foreach (var variable in variablesToDelete)
            {
                try
                {
                    await MICommandFactory.VarDelete(variable);
                }
                catch (MIException)
                {
                    //not much to do really, we're leaking MI debugger variables.
                    Debug.Fail("Failed to delete variable: " + variable + ". This is leaking memory in the MI Debugger.");
                }
            }

            if (String.IsNullOrWhiteSpace(reason) && !_bEntrypointHit)
            {
                // CLRDBG TODO: Try to verify this code path
                _bEntrypointHit = true;
                CmdContinueAsync();
                FireDeviceAppLauncherResume();
            }
            else if (reason == "breakpoint-hit")
            {
                string             bkptno = results.Results.FindString("bkptno");
                ulong              addr   = cxt.pc ?? 0;
                AD7BoundBreakpoint bkpt   = null;
                bool       fContinue;
                TupleValue frame = results.Results.TryFind <TupleValue>("frame");
                bkpt = _breakpointManager.FindHitBreakpoint(bkptno, addr, frame, out fContinue); // use breakpoint number to resolve breakpoint
                if (bkpt != null)
                {
                    List <object> bplist = new List <object>();
                    bplist.Add(bkpt);
                    _callback.OnBreakpoint(thread, bplist.AsReadOnly());
                }
                else if (!_bEntrypointHit)
                {
                    _bEntrypointHit = true;
                    _callback.OnEntryPoint(thread);
                }
                else
                {
                    if (fContinue)
                    {
                        //we hit a bp pending deletion
                        //post the CmdContinueAsync operation so it does not happen until we have deleted all the pending deletes
                        CmdContinueAsync();
                    }
                    else
                    {
                        // not one of our breakpoints, so stop with a message
                        _callback.OnException(thread, "Unknown breakpoint", "", 0);
                    }
                }
            }
            else if (reason == "end-stepping-range" || reason == "function-finished")
            {
                _callback.OnStepComplete(thread);
            }
            else if (reason == "signal-received")
            {
                string name = results.Results.TryFindString("signal-name");
                if ((name == "SIG32") || (name == "SIG33"))
                {
                    // we are going to ignore these (Sigma) signals for now
                    CmdContinueAsync();
                }
                else if (MICommandFactory.IsAsyncBreakSignal(results.Results))
                {
                    _callback.OnAsyncBreakComplete(thread);
                }
                else
                {
                    uint   code    = 0;
                    string sigName = results.Results.TryFindString("signal-name");
                    code = results.Results.Contains("signal") ? results.Results.FindUint("signal") : 0;
                    if (String.IsNullOrEmpty(sigName) && code != 0 && EngineUtils.SignalMap.Instance.ContainsValue(code))
                    {
                        sigName = EngineUtils.SignalMap.Instance.First((p) => p.Value == code).Key;
                    }
                    else if (!String.IsNullOrEmpty(sigName) && code == 0 && EngineUtils.SignalMap.Instance.ContainsKey(sigName))
                    {
                        code = EngineUtils.SignalMap.Instance[sigName];
                    }
                    _callback.OnException(thread, sigName, results.Results.TryFindString("signal-meaning"), code);
                }
            }
            else if (reason == "exception-received")
            {
                string exception = results.Results.FindString("exception");
                _callback.OnException(thread, "Exception", exception, 0);
            }
            else
            {
                Debug.Fail("Unknown stopping reason");
                _callback.OnException(thread, "Unknown", "Unknown stopping event", 0);
            }
        }
Beispiel #12
0
        private async Task <ThreadContext> CollectThreadsInfo(int cxtThreadId)
        {
            ThreadContext ret = null;
            // set of threads has changed or thread locations have been asked for
            Results threadsinfo = await _debugger.MICommandFactory.ThreadInfo();

            if (threadsinfo.ResultClass != ResultClass.done)
            {
                Debug.Fail("Failed to get thread info");
            }
            else
            {
                var tlist = threadsinfo.Find <ValueListValue>("threads");

                // update our thread list
                lock (_threadList)
                {
                    foreach (var thread in _threadList)
                    {
                        thread.Alive = false;
                    }
                    foreach (var t in tlist.Content)
                    {
                        int          threadId = t.FindInt("id");
                        string       targetId = t.TryFindString("target-id");
                        string       state    = t.FindString("state");
                        TupleValue[] frames   = ((TupleValue)t).FindAll <TupleValue>("frame");

                        bool           bNew;
                        DebuggedThread thread = FindThread(threadId, out bNew);
                        thread.Alive = true;
                        if (!String.IsNullOrEmpty(targetId))
                        {
                            uint tid = 0;
                            if (System.UInt32.TryParse(targetId, out tid) && tid != 0)
                            {
                                thread.TargetId = tid;
                            }
                            else if (targetId.StartsWith("Thread") &&
                                     System.UInt32.TryParse(targetId.Substring("Thread ".Length), out tid) &&
                                     tid != 0
                                     )
                            {
                                thread.TargetId = tid;
                            }
                        }
                        if (t.Contains("name"))
                        {
                            thread.Name = t.FindString("name");
                        }
                        if (bNew)
                        {
                            if (_newThreads == null)
                            {
                                _newThreads = new List <DebuggedThread>();
                            }
                            _newThreads.Add(thread);
                        }
                        var stack = new List <ThreadContext>();
                        foreach (var frame in frames)
                        {
                            stack.Add(CreateContext(frame));
                        }
                        if (stack.Count > 0)
                        {
                            _topContext[threadId] = stack[0];
                            if (threadId == cxtThreadId)
                            {
                                ret = _topContext[threadId];
                            }
                            if (stack.Count > 1)
                            {
                                _stackFrames[threadId] = stack;
                            }
                        }
                    }
                    foreach (var thread in _threadList)
                    {
                        if (!thread.Alive)
                        {
                            if (_deadThreads == null)
                            {
                                _deadThreads = new List <DebuggedThread>();
                            }
                            _deadThreads.Add(thread);
                        }
                    }
                    if (_deadThreads != null)
                    {
                        foreach (var dead in _deadThreads)
                        {
                            _threadList.Remove(dead);
                        }
                    }
                    _stateChange = false;
                    _full        = true;
                }
            }
            return(ret);
        }
Beispiel #13
0
        private async Task <ThreadContext> CollectThreadsInfo(int cxtThreadId)
        {
            ThreadContext ret = null;
            // set of threads has changed or thread locations have been asked for
            Results threadsinfo = await _debugger.MICommandFactory.ThreadInfo();

            if (threadsinfo.ResultClass != ResultClass.done)
            {
                Debug.Fail("Failed to get thread info");
            }
            else
            {
                var tlist = threadsinfo.Find <ValueListValue>("threads");

                // update our thread list
                lock (_threadList)
                {
                    foreach (var thread in _threadList)
                    {
                        thread.Alive = false;
                    }
                    foreach (var t in tlist.Content)
                    {
                        int          threadId = t.FindInt("id");
                        string       targetId = t.TryFindString("target-id");
                        string       state    = t.FindString("state");
                        TupleValue[] frames   = ((TupleValue)t).FindAll <TupleValue>("frame");

                        bool           bNew;
                        DebuggedThread thread = FindThread(threadId, out bNew);
                        thread.Alive = true;
                        if (!String.IsNullOrEmpty(targetId))
                        {
                            uint tid = 0;
                            if (System.UInt32.TryParse(targetId, out tid) && tid != 0)
                            {
                                thread.TargetId = tid;
                            }
                            else if (targetId.StartsWith("Thread ", StringComparison.OrdinalIgnoreCase) &&
                                     System.UInt32.TryParse(targetId.Substring("Thread ".Length), out tid) &&
                                     tid != 0
                                     )
                            {
                                thread.TargetId = tid;
                            }
                            else if (targetId.StartsWith("Process ", StringComparison.OrdinalIgnoreCase) &&
                                     System.UInt32.TryParse(targetId.Substring("Process ".Length), out tid) &&
                                     tid != 0
                                     )
                            {   // First thread in a linux process has tid == pid
                                thread.TargetId = tid;
                            }
                            else if (targetId.StartsWith("Thread ", StringComparison.OrdinalIgnoreCase))
                            {
                                // In processes with pthreads the thread name is in form: "Thread <0x123456789abc> (LWP <thread-id>)"
                                int lwp_pos   = targetId.IndexOf("(LWP ");
                                int paren_pos = targetId.LastIndexOf(')');
                                int len       = paren_pos - (lwp_pos + 5);
                                if (len > 0 && System.UInt32.TryParse(targetId.Substring(lwp_pos + 5, len), out tid) && tid != 0)
                                {
                                    thread.TargetId = tid;
                                }
                            }
                            else
                            {
                                thread.TargetId = --s_targetId;
                            }
                        }
                        if (t.Contains("name"))
                        {
                            thread.Name = t.FindString("name");
                        }
                        if (bNew)
                        {
                            if (_newThreads == null)
                            {
                                _newThreads = new List <DebuggedThread>();
                            }
                            _newThreads.Add(thread);
                        }
                        var stack = new List <ThreadContext>();
                        foreach (var frame in frames)
                        {
                            stack.Add(CreateContext(frame));
                        }
                        if (stack.Count > 0)
                        {
                            _topContext[threadId] = stack[0];
                            if (threadId == cxtThreadId)
                            {
                                ret = _topContext[threadId];
                            }
                            if (stack.Count > 1)
                            {
                                _stackFrames[threadId] = stack;
                            }
                        }
                    }
                    foreach (var thread in _threadList)
                    {
                        if (!thread.Alive)
                        {
                            if (_deadThreads == null)
                            {
                                _deadThreads = new List <DebuggedThread>();
                            }
                            _deadThreads.Add(thread);
                        }
                    }
                    if (_deadThreads != null)
                    {
                        foreach (var dead in _deadThreads)
                        {
                            _threadList.Remove(dead);
                        }
                    }
                    _stateChange = false;
                    _full        = true;
                }
            }
            return(ret);
        }