digitalmars.D - Bug in exception chaining results in exceptions escaping
- Yuxuan Shui (79/79) Dec 13 2016 Test case originally by Ali Çehreli, modified by me to expose a
- Walter Bright (4/5) Dec 13 2016 My favorite kind of bug report is one that comes with a fix! Thanks!
Test case originally by Ali Çehreli, modified by me to expose a more serious bug: import core.stdc.stdio; class TestException : Exception { this(string msg) { super(typeof(this).stringof~": "~msg); } } class UnrelatedException: Exception { this() { super("You should've caught me!!"); } } class TestError : Error { this(string msg) { super(typeof(this).stringof~": "~msg); } } // Causes an exception chain where the node at index errorIndex is an // Error (others are all Exceptions). void causeExceptionChain(size_t chainLength, size_t errorIndex) { void throws(size_t n) { scope (exit) { string msg = [ cast(char)('a'+n) ].idup; if (n == errorIndex) { throw new TestError(msg); } else { throw new TestException(msg); } } if (n != 0) { // Redundant 'return' keyword due to // https://issues.dlang.org/show_bug.cgi?id=16960 return throws(n - 1); } } throws(chainLength - 1); } void main() { // Step 1: Setup a corrupted thread exception chain version(bug) { try { size_t errorIndex = 1; causeExceptionChain(2, errorIndex); } catch (Error original) { printf("Caught\n"); string prefix = ""; for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i) { printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); prefix = prefix~" "; } printf("Bypassed chain was:\n"); prefix = ""; // This loop should print something, but nope. for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i) { printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); prefix = prefix~" "; } } } // Now there's leftover exceptions unhandled try { // Step 2 throw new UnrelatedException(); } catch (UnrelatedException x) { // Should be caught here } // But it escaped!! // It even has some ghost exceptions chained to it. } Bug is fixed in https://github.com/dlang/druntime/pull/1712, please review.
Dec 13 2016
On 12/13/2016 4:14 PM, Yuxuan Shui wrote:Bug is fixed in https://github.com/dlang/druntime/pull/1712, please review.My favorite kind of bug report is one that comes with a fix! Thanks! But please also file the bug report in bugzilla, that makes it much easier for us to track and document the changelog.
Dec 13 2016