Esempio n. 1
0
        // Invoked when ContextMenu item is selected to toggle Frozen/Thawed status.
        // This is invoked on the currently selected thread, and that can't change while the ContextMenu is up.
        // Called on UI thread.
        void OnThreadFrozenToggled(Object sender, EventArgs args)
        {
            MDbgThread t = this.SelectedItem;

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
                {
                    Debug.Assert(proc != null);
                    Debug.Assert(!proc.IsRunning);

                    CorDebugThreadState state = t.CorThread.DebugState;
                    bool fFrozen = (state & CorDebugThreadState.THREAD_SUSPEND) == CorDebugThreadState.THREAD_SUSPEND;
                    if (fFrozen)
                    {
                        // Thaw the thread
                        state &= ~CorDebugThreadState.THREAD_SUSPEND;
                    }
                    else
                    {
                        // Freeze the thread
                        state |= CorDebugThreadState.THREAD_SUSPEND;
                    }
                    t.CorThread.DebugState = state;
                });

            // Need to redraw the window.
            this.RefreshToolWindow();
        }
Esempio n. 2
0
        // Called when user selects a different thread in the list.
        // Called on UI thread.
        void OnSelectionChanged(Object sender, EventArgs args)
        {
            MDbgThread t = this.SelectedItem;
            if (t == null)
            {
                return;
            }
            // If we have an threads in the list, then we must have an active process and 
            // valid thread collection.
            if (!this.MainForm.IsProcessStopped)
            {
                return;
            }

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);

                proc.Threads.Active = t;
            });

            this.RefreshMainWindow();
            
        }
Esempio n. 3
0
        // Called when ContextMenu is about to popup
        // Called on UI thread.
        void Popup(object sender, EventArgs args)
        {
            // Don't process UI events if process is running.
            if (!this.MainForm.IsProcessStopped)
            {
                return;
            }

            string st = null;

            MDbgThread t = this.SelectedItem;
            if (t == null)
            {
                return;
            }

            // Get selection.
            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
                {           
                st = IsFrozen(t) ? "Thaw" : "Freeze";
                st += " thread=" + t.Number;
                });
            if (st == null)
            {
                return;
            }

            m_menu.MenuItems.Clear();
            m_menu.MenuItems.Add(st, new EventHandler(this.OnThreadFrozenToggled));

        }
Esempio n. 4
0
        // Called On UI thread.
        protected override void RefreshToolWindowInternal()
        {
            MDbgFrame frame = null;

            MDbgValue[] locals = null;
            MDbgValue[] args   = null;

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                frame = GetCurrentFrame(proc);
                if (frame == null)
                {
                    return;
                }

                // Add Vars to window.
                MDbgFunction f = frame.Function;

                locals = f.GetActiveLocalVars(frame);
                args   = f.GetArguments(frame);

                if (proc.IsEvalSafe())
                {
                    EvalWatch(proc);
                }
            });

            if (frame == null)
            {
                return;
            }

            // Reset
            TreeView t = this.treeView1;

            t.BeginUpdate();
            t.Nodes.Clear();

            // Add Vars to window.
            if (locals != null)
            {
                foreach (MDbgValue v in locals)
                {
                    Util.PrintInternal(MainForm, v, t.Nodes);
                }
            }

            if (args != null)
            {
                foreach (MDbgValue v in args)
                {
                    Util.PrintInternal(MainForm, v, t.Nodes);
                }
            }

            t.EndUpdate();
        } // refresh
Esempio n. 5
0
        // Resolve the expression to a value.
        // Returns "Null" if we can't resolve the arg.
        // called on UI thread.
        MDbgValue Resolve(string arg)
        {
            MDbgValue var = null;

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                MDbgFrame frame = GetCurrentFrame(proc);
                if (frame == null)
                {
                    return;
                }

                var = proc.ResolveVariable(arg, frame);
            });
            return(var);
        }
Esempio n. 6
0
        // Refresh the Threads window.
        public override void RefreshWhenStopped()
        {
            ListBox.ObjectCollection items = this.Items;
            items.Clear();

            
            string[] values = null;
            MDbgThread[] threads = null;

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);

                MDbgThread tActive = proc.Threads.HaveActive ? (proc.Threads.Active) : null;

                values = new string[proc.Threads.Count];
                threads = new MDbgThread[values.Length];
                int idx = 0;

                foreach (MDbgThread t in proc.Threads)
                {
                    string stFrame = "<unknown>";

                    if (t.BottomFrame != null)
                    {
                        stFrame = t.BottomFrame.Function.FullName;
                    }
                    string stActive = (t == tActive) ? "*" : " ";

                    string stFrozen = IsFrozen(t) ? "(FROZEN) " : "";

                    string s = stActive + "(" + t.Number + ") TID=" + t.Id + ", " + stFrozen + stFrame;
                    //this.AddItem(s, t);
                    values[idx]  = s;
                    threads[idx] = t;
                    idx++;

                }
            });

            for (int i = 0; i < values.Length; i++)
            {
                this.AddItem(values[i], threads[i]);
            }

        }
Esempio n. 7
0
        // Refresh the callstack window.
        // runs on UI thread.
        protected override void RefreshToolWindowInternal()
        {
            // Information we need filled out.
            FramePair[] list   = null;
            int         number = 0;
            int         id     = 0;


            // Make cross thread call to access ICorDebug and fill out data
            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);

                MDbgThread thread = proc.Threads.Active;
                try
                {
                    number = thread.Number;
                    id     = thread.Id;
                    list   = GetFrameList(thread);
                }
                catch (Exception)
                {
                    list = null;
                }
            });

            if (list == null || list.Length == 0)
            {
                MarkCallstackAsRunning();
            }
            else
            {
                ListBox.ObjectCollection l = this.listBoxCallstack.Items;
                l.Clear();

                // Set Title.
                this.Text = "Callstack on Thread #" + number + " (tid=" + id + ")";

                // Add items
                foreach (FramePair f in list)
                {
                    l.Add(f);
                }
            }
        }
Esempio n. 8
0
        // Tries to lazily add the immediate children for a given node.
        // called on UI thread.
        static public void TryExpandNode(MainForm parent, TreeNode node)
        {
            MDbgValue val = (MDbgValue)node.Tag;
            if (val == null)
            {
                return;
            }
            node.Tag = null; // only expand it once. Else we'll keep readding the children on each select.

            MDbgValue[] items = null;

            
            parent.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);
                Debug.Assert(val.Process == proc);

                if (val.IsArrayType)
                {
                    items = val.GetArrayItems();
                }
                else if (val.IsComplexType)
                {
                    items = val.GetFields().Concat(
                            val.GetProperties()).ToArray(); 
                }
            });
            
            // Nothing to expand.
            if (items == null)
            {
                return;
            }

            // This node had a dummy sub-node so that it's marked as expandable. When we get the
            // BeforeExpand event, then we kill the dummy node and replace with real nodes.
            // We use a dummy node instead of real nodes because it lets us avoid having to add all the real nodes
            // (which may be a lot of work).
            node.Nodes.Clear(); // delete dummy node.

            foreach (MDbgValue field in items)
            {
                PrintInternal(parent, field, node.Nodes);
            }
        }
Esempio n. 9
0
        // Invoked when we change the selection on the list box.
        // This will change the current active frame in the debugger and refresh.
        private void listBoxCallstack_DoubleClicked(object sender, EventArgs e)
        {
            object    o    = this.listBoxCallstack.SelectedItem;
            FramePair pair = (FramePair)o;

            MDbgFrame f = pair.m_frame;

            if (f == null)
            {
                return;
            }


            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);

                // Update callstack
                MDbgThread t = proc.Threads.Active;

                try
                {
                    t.CurrentFrame = f;
                }
                catch (InvalidOperationException)
                {
                    // if it throws an invalid op, then that means our frames somehow got out of sync
                    // and we weren't fully refreshed.
                    return;
                }
            }     // end delegate
                                                            );

            // Need to refresh UI to show update.
            this.MainForm.ShowCurrentLocation();
            this.MainForm.Invalidate();
        } // end listBoxCallstack_DoubleClicked
Esempio n. 10
0
        //-----------------------------------------------------------------------------
        // Recursive helper to populate tree view.
        // val - value to print
        // c - node collection to add to.
        // Called on UI thread.
        //-----------------------------------------------------------------------------
        static public void PrintInternal(MainForm parent, MDbgValue val, TreeNodeCollection c)
        {
            string name = val.Name;

            try
            {
                TreeNode node = null;
                string st = null;
                parent.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
                {
                    Debug.Assert(proc != null);
                    Debug.Assert(!proc.IsRunning);
                    Debug.Assert(proc == val.Process);

                    if (val.IsArrayType)
                    {         
                        // It would be nice to display array length here too.
                        // Add a "dummy" sub-node to signify that this node is expandable. We then trap
                        // the BeforeExpand event to add the real children.
                        node = new TreeNode(name + " (type='" + val.TypeName + "') array:",
                            new TreeNode[1] { new TreeNode("dummy") });                        
                    }
                    else if (val.IsComplexType)
                    {
                        // This will include both instance and static fields
                        // It will also include all base class fields.
                        node = new TreeNode(name + " (type='" + val.TypeName + "') fields:",
                            new TreeNode[1] { new TreeNode("dummy") });
                    }
                    else
                    {
                        // This is a catch-all for primitives.
                        string stValue = val.GetStringValue(false, "-", null);
                        st = (name + " (type='" + val.TypeName + "') value=" + stValue);

                    }

                });

                // Now add the node.
                if (node != null)
                {
                    node.Tag = val;
                    c.Add(node);
                }
                else if (st != null)
                {
                    c.Add(st);
                }
                else
                {
                    Debug.Assert(false, "No data set.");
                }
            }
            catch (System.Runtime.InteropServices.COMException)
            {
                // Inspecting the vars may fail at the ICorDebug level.
                c.Add(name + "= <unavailable>");
            }

        }
Esempio n. 11
0
        // Populate the module window with the current list.
        // Called on UI thread.
        protected override void RefreshToolWindowInternal()
        {
            ListView.ListViewItemCollection items = this.listView1.Items;
            items.Clear();

            ListViewItem[] temp = null;

            // Go to worker thread to collect information

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);


                temp    = new ListViewItem[proc.Modules.Count];
                int idx = 0;

                foreach (MDbgModule m in proc.Modules)
                {
                    StringBuilder sbFlags = new StringBuilder();

                    if (m.SymReader == null)
                    {
                        sbFlags.Append("[No symbols]");
                    }
                    else
                    {
                        sbFlags.Append("[Symbols]");
                    }

                    string fullname  = m.CorModule.Name;
                    string directory = System.IO.Path.GetDirectoryName(fullname);
                    string name      = System.IO.Path.GetFileName(fullname);

                    bool fIsDynamic = m.CorModule.IsDynamic;
                    if (fIsDynamic)
                    {
                        sbFlags.Append("[Dynamic] ");
                    }

                    CorDebugJITCompilerFlags flags = m.CorModule.JITCompilerFlags;

                    bool fNotOptimized = (flags & CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION) == CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION;
                    if (fNotOptimized)
                    {
                        sbFlags.Append("[Not-optimized] ");
                    }
                    else
                    {
                        sbFlags.Append("[Optimized] ");
                    }

                    // Columns: Id, Name, Path, Flags
                    temp[idx++] = new ListViewItem(
                        new string[] { m.Number.ToString(), name, directory, sbFlags.ToString() }
                        );
                }
            }); // end worker


            if (temp != null)
            {
                foreach (ListViewItem x in temp)
                {
                    items.Add(x);
                }
            }
        }