digitalmars.D - Collateral exceptions seem to be broken
- Andrej Mitrovic <andrej.mitrovich gmail.com> May 08 2011
- KennyTM~ <kennytm gmail.com> May 08 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> May 08 2011
- Jonathan M Davis <jmdavisProg gmx.com> May 08 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> May 08 2011
- Jonathan M Davis <jmdavisProg gmx.com> May 08 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> May 08 2011
- Rainer Schuetze <r.sagitario gmx.de> May 09 2011
- KennyTM~ <kennytm gmail.com> May 09 2011
- Rainer Schuetze <r.sagitario gmx.de> May 09 2011
- Stephan <spam extrawurst.org> May 10 2011
- Rainer Schuetze <r.sagitario gmx.de> May 14 2011
- Jonathan M Davis <jmdavisProg gmx.com> May 08 2011
- Sean Kelly <sean invisibleduck.org> May 09 2011
import std.stdio;
import std.conv;
import std.exception;
void main()
{
try
{
foo();
}
catch (Exception e)
{
for (Throwable t = e; t !is null; t = t.next)
{
writeln(t);
}
}
}
void foo()
{
try
{
throw new Exception("thrown from foo");
}
finally
{
bar(3);
}
}
void bar(int x)
{
try
{
throw new Exception(text("thrown from bar #", x));
}
finally
{
if (x > 1)
{
bar(x - 1);
}
}
}
DMD 2.052, XP 32bit:
object.Exception test.d(26): thrown from foo
object.Exception test.d(38): thrown from bar #3
object.Exception test.d(38): thrown from bar #2
object.Exception test.d(38): thrown from bar #1
object.Exception test.d(38): thrown from bar #3
object.Exception test.d(38): thrown from bar #2
object.Exception test.d(38): thrown from bar #1
object.Exception test.d(38): thrown from bar #2
object.Exception test.d(38): thrown from bar #1
object.Exception test.d(38): thrown from bar #1
Simply calling writeln(e) will work:
void main()
{
try
{
foo();
}
catch (Exception e)
{
writeln(e);
}
}
writes:
object.Exception test.d(27): thrown from foo
object.Exception test.d(39): thrown from bar #3
object.Exception test.d(39): thrown from bar #2
object.Exception test.d(39): thrown from bar #1
However that doesn't help if you want to iterate through the
exceptions one at a time.
May 08 2011
On May 9, 11 04:31, Andrej Mitrovic wrote:import std.stdio; import std.conv; import std.exception; void main() { try { foo(); } catch (Exception e) { for (Throwable t = e; t !is null; t = t.next) { writeln(t); } } } void foo() { try { throw new Exception("thrown from foo"); } finally { bar(3); } } void bar(int x) { try { throw new Exception(text("thrown from bar #", x)); } finally { if (x> 1) { bar(x - 1); } } } DMD 2.052, XP 32bit: object.Exception test.d(26): thrown from foo object.Exception test.d(38): thrown from bar #3 object.Exception test.d(38): thrown from bar #2 object.Exception test.d(38): thrown from bar #1 object.Exception test.d(38): thrown from bar #3 object.Exception test.d(38): thrown from bar #2 object.Exception test.d(38): thrown from bar #1 object.Exception test.d(38): thrown from bar #2 object.Exception test.d(38): thrown from bar #1 object.Exception test.d(38): thrown from bar #1 Simply calling writeln(e) will work: void main() { try { foo(); } catch (Exception e) { writeln(e); } } writes: object.Exception test.d(27): thrown from foo object.Exception test.d(39): thrown from bar #3 object.Exception test.d(39): thrown from bar #2 object.Exception test.d(39): thrown from bar #1 However that doesn't help if you want to iterate through the exceptions one at a time.
Not reproducible on OS X with druntime on git master. I get object.Exception y.d(24): thrown from foo ---------------- 5 y 0x000020b6 void y.foo() + 86 6 y 0x00002036 _Dmain + 14 <<rest of stack trace omitted>> object.Exception y.d(36): thrown from bar #3 ---------------- 5 y 0x00002141 void y.bar(int) + 105 6 y 0x000020d0 void y.foo() + 112 7 y 0x00002036 _Dmain + 14 <<rest of stack trace omitted>> object.Exception y.d(36): thrown from bar #2 ---------------- 5 y 0x00002141 void y.bar(int) + 105 6 y 0x00002160 void y.bar(int) + 136 7 y 0x000020d0 void y.foo() + 112 8 y 0x00002036 _Dmain + 14 <<rest of stack trace omitted>> object.Exception y.d(36): thrown from bar #1 ---------------- 5 y 0x00002141 void y.bar(int) + 105 6 y 0x00002160 void y.bar(int) + 136 7 y 0x00002160 void y.bar(int) + 136 8 y 0x000020d0 void y.foo() + 112 9 y 0x00002036 _Dmain + 14 <<rest of stack trace omitted>>
May 08 2011
Yeah it seems to be fixed in 2.053 beta. But why is the stack trace printed out? Is that the new norm when printing caught exceptions with write()? Regardless of that, I don't get any symbols printed out when building with dmd -g -debug: C:\dmd2\windows\bin>dmd -debug -g test.d C:\dmd2\windows\bin>test object.Exception test.d(24): thrown from foo ---------------- 42BA60 42B8D7 40203E 4059B8 4059F7 4055F3 45BEED object.Exception test.d(36): thrown from bar #3 ---------------- 42BA60 42B8D7 402115 40203E 4059B8 4059F7 4055F3 45BEED object.Exception test.d(36): thrown from bar #2 ---------------- 42BA60 42B8D7 4021D6 402115 40203E 4059B8 4059F7 4055F3 45BEED object.Exception test.d(36): thrown from bar #1 ---------------- 42BA60 42B8D7 ... Where are the symbols? :o
May 08 2011
Yeah it seems to be fixed in 2.053 beta. But why is the stack trace printed out? Is that the new norm when printing caught exceptions with write()? Regardless of that, I don't get any symbols printed out when building with dmd -g -debug: C:\dmd2\windows\bin>dmd -debug -g test.d C:\dmd2\windows\bin>test object.Exception test.d(24): thrown from foo ---------------- 42BA60 42B8D7 40203E 4059B8 4059F7 4055F3 45BEED object.Exception test.d(36): thrown from bar #3 ---------------- 42BA60 42B8D7 402115 40203E 4059B8 4059F7 4055F3 45BEED object.Exception test.d(36): thrown from bar #2 ---------------- 42BA60 42B8D7 4021D6 402115 40203E 4059B8 4059F7 4055F3 45BEED object.Exception test.d(36): thrown from bar #1 ---------------- 42BA60 42B8D7 ... Where are the symbols? :o
Recent work has been done on chained exceptions, so that could definitely change their behavior. And you should definitely get the symbols on Linux if you compile with the standard dmd.conf. If you aren't doing that for some reason, then you need to make sure that you use -L--export-dynamic. - Jonathan M Davis
May 08 2011
No, I'm on Windows. And I can't get any symbols unless I run cv2pdb (http://www.dsource.org/projects/cv2pdb) on the executable. Here's my console log: D:\dev\code\d_code>type test.d import std.exception; void main() { foo(); } void foo() { throw new Exception("foo"); } D:\dev\code\d_code>dmd -debug -g test.d D:\dev\code\d_code>test object.Exception test.d(10): foo ---------------- 414280 4140F7 402018 4025B8 4025F7 4021F3 45D5E9 45D540 ---------------- D:\dev\code\d_code>cv2pdb test.exe test.exe D:\dev\code\d_code>test object.Exception test.d(10): foo ---------------- D:\dev\code\d_code\test.d(5): D main ----------------
May 08 2011
No, I'm on Windows. And I can't get any symbols unless I run cv2pdb (http://www.dsource.org/projects/cv2pdb) on the executable.
There was a discussion on that recently. From what I understand, your build has to have debug symbols for you to get any function names (otherwise, it won't have any function names to show), and Sean may have to make additional changes to get it properly show names. I don't know if you can currently get it to show function names on Windows. - Jonathan M Davis
May 08 2011
You mean my build of DMD/Phobos? Well the debug symbols are definitely shown after I run cv2pdb on the executable (it makes a .pdb file with all the symbols which get loaded at runtime by the exe). Perhaps displaying names is just unimplemented yet in 2.053 for Windows. Using cv2pdb is not a problem for me (and it allows me to use VisualD's debugger, which is nice).
May 08 2011
Andrej Mitrovic wrote:You mean my build of DMD/Phobos? Well the debug symbols are definitely shown after I run cv2pdb on the executable (it makes a .pdb file with all the symbols which get loaded at runtime by the exe). Perhaps displaying names is just unimplemented yet in 2.053 for Windows. Using cv2pdb is not a problem for me (and it allows me to use VisualD's debugger, which is nice).
It is implemented, but there are currently a few problems: - the stacktrace uses dbghelp.dll to get symbol information for a code address. This often doesn't work with the debug information emitted by dmd/optlink. You have to convert it with cv2pdb to make it digestable to dbghelp. - creating the stack trace uses core.demangle on each symbol, but any symbol that cannot be demangled causes exceptions when trying to demangle it, resulting in recursive attempts to dump the stack. These symbols include C-style, compressed and "SHA'd" symbols. - thus, core.demangle should have a simple check to reject any symbol that does not start with _D<digit>. This does not exclude invalid, compressed and SHA'd symbols, but it works for most symbols. - a recent change in dmd causes debug symbols to be written unmangled, not with mangled names adding all symbols to the list of symbols causing trouble. This helps debuggers to display sensible names without the need to be able to demangle names. Additionally, it allows inspecting globals without knowing the mangled name. But with this change in place, it is no longer necessary to try demangling the names. The change might break some tools that rely on mangled names, though. Does this raise a red flag for someone? - cv2pdb demangles names and converts '.' to ' '. The '.' inside symbols confuses the Microsoft debuggers, e.g. you can no longer inspect the members of a class instance because of the '.' in the class name. Unfortunately, the ' ' seems to confuse dbghelp.dll, causing it to output just the part of the symbol until the first ' '. Maybe I should switch to '_', it even looks better than ' ' but it introduces ambiguities. - it also helps to use a debug build of phobos. Otherwise you won't get any symbolic information for phobos-functions on the stack. Missing symbols might even cause the stack walker to be unable to unwind the proper call stack. I suggest to even add debug symbols to the release build of phobos, as you also don't have debug info for non-template classes and structs declared inside phobos, even if your application is built with -g. Rainer
May 09 2011
On May 10, 11 02:05, Rainer Schuetze wrote:- creating the stack trace uses core.demangle on each symbol, but any symbol that cannot be demangled causes exceptions when trying to demangle it, resulting in recursive attempts to dump the stack. These symbols include C-style, compressed and "SHA'd" symbols.
I ain't using D on Windows. In the OSX version the stack trace are demangled (as I've shown in the post above) and I didn't notice any problems. The specific exceptions that core.demangle.Demangler generates are all caught in opCall, how will that matter? Is it only a Windows problem? (Or Demangler could be rewritten to not rely on exceptions, but that's troublesome :).)
May 09 2011
Rainer Schuetze wrote:Andrej Mitrovic wrote:You mean my build of DMD/Phobos? Well the debug symbols are definitely shown after I run cv2pdb on the executable (it makes a .pdb file with all the symbols which get loaded at runtime by the exe). Perhaps displaying names is just unimplemented yet in 2.053 for Windows. Using cv2pdb is not a problem for me (and it allows me to use VisualD's debugger, which is nice).
It is implemented, but there are currently a few problems: - the stacktrace uses dbghelp.dll to get symbol information for a code address. This often doesn't work with the debug information emitted by dmd/optlink. You have to convert it with cv2pdb to make it digestable to dbghelp.
I stand corrected here. What you need is a newer version of dbghelp.dll than the one found on XP. You can find one in a newer Windows SDK or the "Debugging Tools for Windows" from Microsoft.- a recent change in dmd causes debug symbols to be written unmangled, not with mangled names adding all symbols to the list of symbols causing trouble. This helps debuggers to display sensible names without the need to be able to demangle names. Additionally, it allows inspecting globals without knowing the mangled name. But with this change in place, it is no longer necessary to try demangling the names. The change might break some tools that rely on mangled names, though. Does this raise a red flag for someone?
I have to correct myself again: The debug info has both versions now in two seperate places. The call stack uses the global symbol table and its symbols are still mangled.
May 09 2011
On 09.05.2011 20:05, Rainer Schuetze wrote:I suggest to even add debug symbols to the release build of phobos, as you also don't have debug info for non-template classes and structs declared inside phobos, even if your application is built with -g. Rainer
That is a excellent idea. Can you post that on the beta mailing list so that it gets attention ? Stephan
May 10 2011
Stephan wrote:On 09.05.2011 20:05, Rainer Schuetze wrote:I suggest to even add debug symbols to the release build of phobos, as you also don't have debug info for non-template classes and structs declared inside phobos, even if your application is built with -g. Rainer
That is a excellent idea. Can you post that on the beta mailing list so that it gets attention ? Stephan
Probably not ready for prime time yet: When building the std.algorithm unittests against a runtime library with debug symbols (both release or debug builds) I'm getting crashes in optlink. I'll create a bug report...
May 14 2011
On 2011-05-08 15:57, Andrej Mitrovic wrote:You mean my build of DMD/Phobos? Well the debug symbols are definitely shown after I run cv2pdb on the executable (it makes a .pdb file with all the symbols which get loaded at runtime by the exe). Perhaps displaying names is just unimplemented yet in 2.053 for Windows. Using cv2pdb is not a problem for me (and it allows me to use VisualD's debugger, which is nice).
I don't know exactly what works and what needs to be ironed out with regards to stack traces on Windows. I know that there is some further work that needs to be done to properly deal with displaying symbols, but I don't normally use Windows, and I didn't pay a lot of attention to the discussions on the issues with stack traces on it. Regardless, they're very recently added, so it's not altogether surprising if they're somewhat buggy still. - Jonathan M Davis
May 08 2011
On May 8, 2011, at 3:57 PM, Andrej Mitrovic wrote:Perhaps displaying names is just unimplemented yet in 2.053 for Windows. Using cv2pdb is not a problem for me (and it allows me to use VisualD's debugger, which is nice).
This should be implemented in the 2.053 beta.
May 09 2011









KennyTM~ <kennytm gmail.com> 