Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit e97402b

Browse files
fix #549: Breaking on all but one exception type does not work as expected
1 parent 19c98ee commit e97402b

5 files changed

Lines changed: 68 additions & 29 deletions

File tree

data/resources/StringResources.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8211,9 +8211,12 @@ a line break</value>
82118211
<value>Break on</value>
82128212
</data>
82138213
<data name="Dialog.Options.IDEOptions.Debugging.ExceptionFilter.ColumnExpression" xml:space="preserve">
8214-
<value>Exception name expression (wildcards are allowed)</value>
8214+
<value>Full exception name</value>
82158215
</data>
82168216
<data name="Dialog.Options.IDEOptions.Debugging.ChooseExceptions" xml:space="preserve">
82178217
<value>Choose exceptions</value>
82188218
</data>
8219+
<data name="MainWindow.Windows.Debug.ExceptionForm.BreakOnHandled" xml:space="preserve">
8220+
<value>Break on handled ${ExceptionName}</value>
8221+
</data>
82198222
</root>

src/AddIns/Debugger/Debugger.AddIn/Service/DebuggeeExceptionForm.Designer.cs

Lines changed: 25 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AddIns/Debugger/Debugger.AddIn/Service/DebuggeeExceptionForm.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
using System;
2020
using System.Drawing;
21+
using System.Linq;
2122
using System.Windows.Forms;
2223
using Debugger;
2324
using ICSharpCode.Core;
@@ -30,16 +31,18 @@ namespace ICSharpCode.SharpDevelop.Services
3031
internal sealed partial class DebuggeeExceptionForm
3132
{
3233
Process process;
34+
string exceptionType;
3335

3436
public bool Break { get; set; }
3537

36-
DebuggeeExceptionForm(Process process)
38+
DebuggeeExceptionForm(Process process, string exceptionType)
3739
{
3840
InitializeComponent();
3941

4042
this.Break = true;
4143

4244
this.process = process;
45+
this.exceptionType = exceptionType;
4346

4447
this.process.Exited += ProcessHandler;
4548
this.process.Resumed += ProcessHandler;
@@ -75,14 +78,20 @@ void FormClosedHandler(object sender, EventArgs e)
7578
this.process.Resumed -= ProcessHandler;
7679
}
7780

78-
public static bool Show(Process process, string title, string type, string stacktrace, Bitmap icon, bool isUnhandled)
81+
public static bool Show(Process process, string exceptionType, string stacktrace, bool isUnhandled)
7982
{
80-
DebuggeeExceptionForm form = new DebuggeeExceptionForm(process);
81-
form.Text = title;
83+
DebuggeeExceptionForm form = new DebuggeeExceptionForm(process, exceptionType);
84+
string type = string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Message}"), exceptionType);
85+
Bitmap icon = WinFormsResourceService.GetBitmap(isUnhandled ? "Icons.32x32.Error" : "Icons.32x32.Warning");
86+
87+
form.Text = isUnhandled ? StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Unhandled}") : StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Handled}");
8288
form.pictureBox.Image = icon;
8389
form.lblExceptionText.Text = type;
8490
form.exceptionView.Text = stacktrace;
8591
form.btnContinue.Enabled = !isUnhandled;
92+
form.chkBreakOnHandled.Visible = !isUnhandled;
93+
form.chkBreakOnHandled.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.BreakOnHandled}", new StringTagPair("ExceptionName", exceptionType));
94+
form.chkBreakOnHandled.Checked = true;
8695

8796
// Showing the form as dialg seems like a resonable thing in the presence of potentially multiple
8897
// concurent debugger evetns
@@ -91,6 +100,21 @@ public static bool Show(Process process, string title, string type, string stack
91100
return form.Break;
92101
}
93102

103+
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
104+
{
105+
if (chkBreakOnHandled.Visible && !chkBreakOnHandled.Checked) {
106+
var list = process.Debugger.Options.ExceptionFilterList.ToList();
107+
var entry = list.FirstOrDefault(item => item.Expression.Equals(exceptionType, StringComparison.OrdinalIgnoreCase));
108+
if (entry == null) {
109+
list.Add(new ExceptionFilterEntry(exceptionType) { IsActive = false });
110+
} else {
111+
entry.IsActive = false;
112+
}
113+
process.Debugger.Options.ExceptionFilterList = list;
114+
}
115+
base.OnClosing(e);
116+
}
117+
94118
void ExceptionViewDoubleClick(object sender, EventArgs e)
95119
{
96120
string fullText = exceptionView.Text;

src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -533,12 +533,8 @@ void debuggedProcess_DebuggingPaused(object sender, DebuggerPausedEventArgs e)
533533
// Do not intercept handled expetions
534534
stacktrace += exceptionThread.GetStackTrace(formatSymbols, formatNoSymbols);
535535
}
536-
537-
string title = isUnhandled ? StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Unhandled}") : StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Handled}");
538-
string type = string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Message}"), exception.Type);
539-
Bitmap icon = WinFormsResourceService.GetBitmap(isUnhandled ? "Icons.32x32.Error" : "Icons.32x32.Warning");
540-
541-
if (DebuggeeExceptionForm.Show(e.Process, title, type, stacktrace, icon, isUnhandled)) {
536+
537+
if (DebuggeeExceptionForm.Show(e.Process, exception.Type.FullName, stacktrace, isUnhandled)) {
542538
breakProcess = true;
543539
// The dialog box is allowed to kill the process
544540
if (e.Process.HasExited) {

src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, I
557557
ExitCallback();
558558
}
559559

560-
Regex filterRegex;
560+
Dictionary<string, bool> exceptionFilter;
561561

562562
static string ConvertWildcardsToRegex(string searchPattern)
563563
{
@@ -587,17 +587,18 @@ bool BreakOnException(Thread thread)
587587
{
588588
IType exceptionType = thread.CurrentException.Type;
589589

590-
if (filterRegex == null) {
591-
var exceptionFilterList = thread.Process.Options.ExceptionFilterList.Where(i => i.IsActive).Select(s => "(" + ConvertWildcardsToRegex(s.Expression) + ")");
592-
filterRegex = new Regex(string.Join("|", exceptionFilterList), RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
590+
if (exceptionFilter == null) {
591+
exceptionFilter = thread.Process.Options.ExceptionFilterList
592+
.ToDictionary(e => e.Expression, e => e.IsActive, StringComparer.OrdinalIgnoreCase);
593593
}
594594

595-
foreach (var baseType in exceptionType.GetNonInterfaceBaseTypes()) {
596-
if (filterRegex.IsMatch(baseType.ReflectionName))
597-
return true;
595+
foreach (var baseType in exceptionType.GetNonInterfaceBaseTypes().Reverse()) {
596+
bool isActive;
597+
if (exceptionFilter.TryGetValue(baseType.ReflectionName, out isActive))
598+
return isActive;
598599
}
599600

600-
return false;
601+
return true;
601602
}
602603

603604
public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags)

0 commit comments

Comments
 (0)