You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.2 KiB
210 lines
7.2 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
#region License |
|
// |
|
// Copyright (c) 2007, ic#code |
|
// |
|
// All rights reserved. |
|
// |
|
// Redistribution and use in source and binary forms, with or without |
|
// modification, are permitted provided that the following conditions are met: |
|
// |
|
// 1. Redistributions of source code must retain the above copyright notice, |
|
// this list of conditions and the following disclaimer. |
|
// |
|
// 2. Redistributions in binary form must reproduce the above copyright |
|
// notice, this list of conditions and the following disclaimer in the |
|
// documentation and/or other materials provided with the distribution. |
|
// |
|
// 3. Neither the name of the ic#code nor the names of its contributors may be |
|
// used to endorse or promote products derived from this software without |
|
// specific prior written permission. |
|
// |
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
// POSSIBILITY OF SUCH DAMAGE. |
|
// |
|
#endregion |
|
|
|
using System; |
|
using System.Windows.Forms; |
|
using Debugger; |
|
using ICSharpCode.Core; |
|
|
|
namespace ICSharpCode.SharpDevelop.Gui.Pads |
|
{ |
|
public partial class RunningThreadsPad : DebuggerPad |
|
{ |
|
ListView runningThreadsList; |
|
Debugger.Process debuggedProcess; |
|
|
|
ColumnHeader id = new ColumnHeader(); |
|
ColumnHeader name = new ColumnHeader(); |
|
ColumnHeader location = new ColumnHeader(); |
|
ColumnHeader priority = new ColumnHeader(); |
|
ColumnHeader breaked = new ColumnHeader(); |
|
|
|
public override Control Control { |
|
get { |
|
return runningThreadsList; |
|
} |
|
} |
|
|
|
protected override void InitializeComponents() |
|
{ |
|
runningThreadsList = new ListView(); |
|
runningThreadsList.FullRowSelect = true; |
|
runningThreadsList.AutoArrange = true; |
|
runningThreadsList.Alignment = ListViewAlignment.Left; |
|
runningThreadsList.View = View.Details; |
|
runningThreadsList.Dock = DockStyle.Fill; |
|
runningThreadsList.GridLines = false; |
|
runningThreadsList.Activation = ItemActivation.OneClick; |
|
runningThreadsList.Columns.AddRange(new ColumnHeader[] {id, name, location, priority, breaked} ); |
|
runningThreadsList.ContextMenuStrip = CreateContextMenuStrip(); |
|
runningThreadsList.ItemActivate += new EventHandler(RunningThreadsListItemActivate); |
|
id.Width = 100; |
|
name.Width = 300; |
|
location.Width = 250; |
|
priority.Width = 120; |
|
breaked.Width = 80; |
|
|
|
RedrawContent(); |
|
} |
|
|
|
public override void RedrawContent() |
|
{ |
|
id.Text = ResourceService.GetString("Global.ID"); |
|
name.Text = ResourceService.GetString("Global.Name"); |
|
location.Text = ResourceService.GetString("AddIns.HtmlHelp2.Location"); |
|
priority.Text = ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority"); |
|
breaked.Text = ResourceService.GetString("MainWindow.Windows.Debug.Threads.Frozen"); |
|
} |
|
|
|
|
|
protected override void SelectProcess(Debugger.Process process) |
|
{ |
|
if (debuggedProcess != null) { |
|
debuggedProcess.DebuggeeStateChanged -= debuggedProcess_DebuggeeStateChanged; |
|
debuggedProcess.ThreadStarted -= debuggedProcess_ThreadStarted; |
|
} |
|
debuggedProcess = process; |
|
if (debuggedProcess != null) { |
|
debuggedProcess.DebuggeeStateChanged += debuggedProcess_DebuggeeStateChanged; |
|
debuggedProcess.ThreadStarted += debuggedProcess_ThreadStarted; |
|
} |
|
runningThreadsList.Items.Clear(); |
|
RefreshPad(); |
|
} |
|
|
|
void debuggedProcess_DebuggeeStateChanged(object sender, ProcessEventArgs e) |
|
{ |
|
RefreshPad(); |
|
} |
|
|
|
void debuggedProcess_ThreadStarted(object sender, ThreadEventArgs e) |
|
{ |
|
AddThread(e.Thread); |
|
} |
|
|
|
public override void RefreshPad() |
|
{ |
|
if (debuggedProcess != null) { |
|
foreach (Thread t in debuggedProcess.Threads) { |
|
RefreshThread(t); |
|
} |
|
} |
|
} |
|
|
|
void RunningThreadsListItemActivate(object sender, EventArgs e) |
|
{ |
|
if (debuggedProcess.IsPaused) { |
|
if (debuggedProcess != null) { |
|
debuggedProcess.SelectedThread = (Thread)(runningThreadsList.SelectedItems[0].Tag); |
|
debuggedProcess.OnDebuggeeStateChanged(); // Force refresh of pads |
|
} |
|
} else { |
|
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}"); |
|
} |
|
} |
|
|
|
void AddThread(Thread thread) |
|
{ |
|
runningThreadsList.Items.Add(new ListViewItem(thread.ID.ToString())); |
|
RefreshThread(thread); |
|
thread.StateChanged += delegate { |
|
RefreshThread(thread); |
|
}; |
|
thread.Expired += delegate { |
|
RemoveThread(thread); |
|
}; |
|
} |
|
|
|
void RefreshThread(Thread thread) |
|
{ |
|
foreach (ListViewItem item in runningThreadsList.Items) { |
|
if (thread.ID.ToString() == item.Text) { |
|
item.SubItems.Clear(); |
|
item.Text = thread.ID.ToString(); |
|
item.Tag = thread; |
|
item.SubItems.Add(thread.Name); |
|
StackFrame location = null; |
|
if (thread.Process.IsPaused) { |
|
location = thread.LastStackFrameWithLoadedSymbols; |
|
if (location == null) { |
|
location = thread.LastStackFrame; |
|
} |
|
} |
|
if (location != null) { |
|
item.SubItems.Add(location.MethodInfo.Name); |
|
} else { |
|
item.SubItems.Add(ResourceService.GetString("Global.NA")); |
|
} |
|
switch (thread.Priority) { |
|
case System.Threading.ThreadPriority.Highest: |
|
item.SubItems.Add(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Highest")); |
|
break; |
|
case System.Threading.ThreadPriority.AboveNormal: |
|
item.SubItems.Add(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.AboveNormal")); |
|
break; |
|
case System.Threading.ThreadPriority.Normal: |
|
item.SubItems.Add(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Normal")); |
|
break; |
|
case System.Threading.ThreadPriority.BelowNormal: |
|
item.SubItems.Add(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.BelowNormal")); |
|
break; |
|
case System.Threading.ThreadPriority.Lowest: |
|
item.SubItems.Add(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Lowest")); |
|
break; |
|
default: |
|
item.SubItems.Add(thread.Priority.ToString()); |
|
break; |
|
} |
|
item.SubItems.Add(ResourceService.GetString(thread.Suspended ? "Global.Yes" : "Global.No")); |
|
return; |
|
} |
|
} |
|
AddThread(thread); |
|
} |
|
|
|
void RemoveThread(Thread thread) |
|
{ |
|
foreach (ListViewItem item in runningThreadsList.Items) { |
|
if (thread.ID.ToString() == item.Text) { |
|
item.Remove(); |
|
} |
|
} |
|
} |
|
} |
|
}
|
|
|