diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs index c01229fdf3..93ea831b5b 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs @@ -39,6 +39,7 @@ using System; using System.Drawing; +using System.Text; using System.Windows.Forms; using Debugger; @@ -122,54 +123,17 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads public override void RefreshPad() { - bool showArgumentNames = ShowArgumentNames; - bool showArgumentValues = ShowArgumentValues; bool showExternalMethods = ShowExternalMethods; bool lastItemIsExternalMethod = false; - int callstackItems = 0; callStackList.BeginUpdate(); callStackList.Items.Clear(); if (debuggedProcess != null && debuggedProcess.SelectedThread != null && debuggedProcess.IsPaused) { - foreach (StackFrame f in debuggedProcess.SelectedThread.Callstack) { + foreach (StackFrame f in debuggedProcess.SelectedThread.GetCallstack(100)) { ListViewItem item; if (f.HasSymbols || showExternalMethods) { // Show the method in the list - string name = f.MethodInfo.Name; - if (showArgumentNames || showArgumentValues) { - name += "("; - for (int i = 0; i < f.ArgumentCount; i++) { - string parameterName = null; - string argValue = null; - if (showArgumentNames) { - try { - parameterName = f.MethodInfo.GetParameterName(i); - } catch { } - if (parameterName == "") parameterName = null; - } - if (showArgumentValues) { - try { - argValue = f.GetArgumentValue(i).AsString; - } catch { } - } - if (parameterName != null && argValue != null) { - name += parameterName + "=" + argValue; - } - if (parameterName != null && argValue == null) { - name += parameterName; - } - if (parameterName == null && argValue != null) { - name += argValue; - } - if (parameterName == null && argValue == null) { - name += ResourceService.GetString("Global.NA"); - } - if (i < f.ArgumentCount - 1) { - name += ", "; - } - } - name += ")"; - } + string name = GetFullName(f); item = new ListViewItem(new string[] { name, "" }); lastItemIsExternalMethod = false; } else { @@ -184,11 +148,55 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads item.Tag = f; item.ForeColor = f.HasSymbols ? Color.Black : Color.Gray; callStackList.Items.Add(item); - callstackItems++; - if (callstackItems >= 100) break; } } callStackList.EndUpdate(); } + + public string GetFullName(StackFrame frame) + { + bool showArgumentNames = ShowArgumentNames; + bool showArgumentValues = ShowArgumentValues; + + StringBuilder name = new StringBuilder(); + name.Append(frame.MethodInfo.Name); + if (showArgumentNames || showArgumentValues) { + name.Append("("); + for (int i = 0; i < frame.ArgumentCount; i++) { + string parameterName = null; + string argValue = null; + if (showArgumentNames) { + try { + parameterName = frame.MethodInfo.GetParameterName(i); + } catch { } + if (parameterName == "") parameterName = null; + } + if (showArgumentValues) { + try { + argValue = frame.GetArgumentValue(i).AsString; + } catch { } + } + if (parameterName != null && argValue != null) { + name.Append(parameterName); + name.Append("="); + name.Append(argValue); + } + if (parameterName != null && argValue == null) { + name.Append(parameterName); + } + if (parameterName == null && argValue != null) { + name.Append(argValue); + } + if (parameterName == null && argValue == null) { + name.Append(ResourceService.GetString("Global.NA")); + } + if (i < frame.ArgumentCount - 1) { + name.Append(", "); + } + } + name.Append(")"); + } + return name.ToString(); + } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs index 8131d6ef92..2b37f15e10 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs @@ -44,20 +44,13 @@ namespace Debugger } callstack = ""; - int callstackItems = 0; - foreach(StackFrame stackFrame in thread.Callstack) { - if (callstackItems >= 100) { - callstack += "...\n"; - break; - } - + foreach(StackFrame stackFrame in thread.GetCallstack(100)) { SourcecodeSegment loc = stackFrame.NextStatement; callstack += stackFrame.MethodInfo.Name + "()"; if (loc != null) { callstack += " - " + loc.SourceFullFilename + ":" + loc.StartLine + "," + loc.StartColumn; } callstack += "\n"; - callstackItems++; } type = runtimeValue.Type.FullName; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs index 7dbbe609a3..49c425dbb8 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs @@ -235,11 +235,23 @@ namespace Debugger } } - public IEnumerable Callstack { - get { - // This should be enum since callstacks can get big - return CallstackEnum; + /// + /// Gets the whole callstack of the Thread. + /// + public StackFrame[] GetCallstack() + { + return new List(CallstackEnum).ToArray(); + } + + /// Get given number of frames from the callstack + public StackFrame[] GetCallstack(int maxFrames) + { + List frames = new List(); + foreach(StackFrame frame in CallstackEnum) { + frames.Add(frame); + if (frames.Count == maxFrames) break; } + return frames.ToArray(); } IEnumerable CallstackEnum { @@ -309,7 +321,7 @@ namespace Debugger public StackFrame OldestStackFrame { get { StackFrame first = null; - foreach(StackFrame stackFrame in Callstack) { + foreach(StackFrame stackFrame in CallstackEnum) { first = stackFrame; } return first; diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Callstack.cs b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Callstack.cs index 9a3b71e96d..c073f99371 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Callstack.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Callstack.cs @@ -37,15 +37,15 @@ namespace Debugger.Tests { { StartTest("Callstack.cs"); WaitForPause(); - ObjectDump("Callstack", process.SelectedThread.Callstack); + ObjectDump("Callstack", process.SelectedThread.GetCallstack()); process.StepOut(); WaitForPause(); - ObjectDump("Callstack", process.SelectedThread.Callstack); + ObjectDump("Callstack", process.SelectedThread.GetCallstack()); process.StepOut(); WaitForPause(); - ObjectDump("Callstack", process.SelectedThread.Callstack); + ObjectDump("Callstack", process.SelectedThread.GetCallstack()); process.Continue(); process.WaitForExit();