[D-runtime] stacktraces on windows

Rainer Schuetze r.sagitario at gmx.de
Sat May 7 05:05:21 PDT 2011


Walter Bright wrote:
> when running unittests. Usually it just hangs.
> 
> unittest
> totalCPUs = 2
> object.Error: Access Violation
> ----------------
> 62B6DC
> 62B553
> ----------------
> 
> --- errorlevel 1

Hijacking this thread from the phobos list, I'd like to comment on stack 
traces under windows:

- you'll never get a symbolic stacktrace without converting the debug 
info with cv2pdb (well, it might work for very simple executables). 
stacktrace.d uses dbghelp.dll, and this usually dislikes the debug 
information generated by dmd/optlink.

- if symbols are found, generating the stack trace message generates 
another exception inside std.demangle if the symbol cannot be demangled 
(non-D, compressed or SHA'd symbols).

- walking the stack trace can be very time consuming, especially when 
loading debug symbols while doing so. This should not be done for every 
exception thrown.

- the stack trace often misses the source file location where the 
exception is thrown as reported here: 
http://d.puremagic.com/issues/show_bug.cgi?id=4809
I'm not sure the patch is up to date, though.

- disabling the default traceHandler is possible, but it has some pitfalls:

// object.traceHandler is __gshared, but the static this()
// in runtime.d is not shared! so we have to reset it in every thread.
// also ensure that static this() in runtime is called before mine
import core.runtime;
static this()
{
	Runtime.traceHandler = null;
}

- a convenient way to inspect crashes is to fire up the debugger when 
the crash happens with the crash reporting by Windows. This 
functionality is currently blocked by dmain2.main() handling all 
Exceptions (which also lets a non-console application blow up without 
any message). Also, stopping on unhandled exceptions only inside a 
debugger is not possible.
I understand that a dialog showing up is no good when running programs 
from the console (e.g. the autotester), so I suggest making this 
configurable:

a: catch all Throwables
b: catch all Exceptions
c: catch none

There's already a variable rt_trapExceptions available that does a or c, 
but you can't configure it before executing the program. It is also 
copied to a local value before any static initializer is called, so it 
cannot be modified programmatically. (The comment says it should be 
modified by the debugger, but I don't think this is a sensible approach.)


Rainer


More information about the D-runtime mailing list