Thread overview
Re: Win32: How to get the stack trace when compiling with a windows subsystem?
Aug 18, 2013
Andrej Mitrovic
Aug 18, 2013
Adam D. Ruppe
Aug 18, 2013
Andrej Mitrovic
Aug 19, 2013
Benjamin Thaut
Aug 19, 2013
Andrej Mitrovic
Aug 19, 2013
Andrej Mitrovic
Aug 19, 2013
Benjamin Thaut
Aug 19, 2013
Andrej Mitrovic
August 18, 2013
On 8/18/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>     if (!GetConsoleWindow())

Actually it would be even better if I could create a console window when building with subsystem:windows, for debugging purposes. I'll have a look at MSDN on ways to do this, unless someone already knows this and posts it here.

Normally I'd just compile in console mode to begin with, but I'm
trying to avoid some GUI-related bugs when an app isn't built with
subsystem windows
(http://forum.dlang.org/thread/CAJ85NXBnx+8Uo5BeO1k9Q-j0QpOVo74Ft4LaEEksaQJtMULeKg@mail.gmail.com#post-mpzehfgvzuzspvfoxsxw:40forum.dlang.org).
August 18, 2013
On Sunday, 18 August 2013 at 14:10:07 UTC, Andrej Mitrovic wrote:
> Actually it would be even better if I could create a console window when building with subsystem:windows, for debugging purposes.


extern(Windows) void AllocConsole(); // not sure if that's the perfect signature but it works

void main() {
   debug AllocConsole();
   throw new Exception("test");
}


The problem is the console will close before you can actually read it! But it is there and the exception text did appear in it so that's something.

August 18, 2013
On 8/18/13, Adam D. Ruppe <destructionator@gmail.com> wrote:
> extern(Windows) void AllocConsole(); // not sure if that's the
> perfect signature but it works
>
> void main() {
>     debug AllocConsole();
>     throw new Exception("test");
> }
>
>
> The problem is the console will close before you can actually read it! But it is there and the exception text did appear in it so that's something.

Thanks. However I've found a solution but also a new problem. The 'info' field of a Throwable can be converted to a string, so I can output this into a log file.

But, the info field is always null in a module constructor:

-----
import std.stdio;

import core.sys.windows.windows;
extern(Windows) HWND GetConsoleWindow();

shared static this()
{
    stderr.open(r".\stderr.log", "w");

    try
    {
        assert(0);
    }
    catch (Throwable thr)
    {
        stderr.writefln("thr.info: %s", thr.info);
    }
}

void main() { }
-----

$ dmd -g -L/SUBSYSTEM:WINDOWS:5.01 -run test.d && type stderr.log $ thr.info: null

If I copy-paste the code from the module ctor into main then thr.info has the proper stack trace information.

Should I be calling some runtime initialization functions in the module ctor so the stack traces work there?
August 19, 2013
Am 18/08/2013 16:35, schrieb Andrej Mitrovic:
>
> $ dmd -g -L/SUBSYSTEM:WINDOWS:5.01 -run test.d && type stderr.log
> $ thr.info: null
>
> If I copy-paste the code from the module ctor into main then thr.info
> has the proper stack trace information.
>
> Should I be calling some runtime initialization functions in the
> module ctor so the stack traces work there?
>

D should be calling the module constructors in the correct order so that the windows stack trace module (core.sys.windows.stacktrace) is initialized first. If this is not the case you might need to import the module into your main file to make sure that it gets initialized first.

You might also create a bug ticket for this, because exceptions should really have traces if they are thrown inside a module constructor.

Kind Regards
Benjamin Thaut
August 19, 2013
On 8/19/13, Benjamin Thaut <code@benjamin-thaut.de> wrote:
> D should be calling the module constructors in the correct order so that the windows stack trace module (core.sys.windows.stacktrace) is initialized first. If this is not the case you might need to import the module into your main file to make sure that it gets initialized first.

Thinking about it some more I think the .info field is empty because there's nothing really to trace, if I write the whole exception via writeln(thr) rather than writeln(thr.info), I'll get back the file+line of the failed assert, which should be enough for a module constructor (the Druntime function which ends up calling the actual module ctors isn't really important here).
August 19, 2013
On 8/19/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> Thinking about it some more I think the .info field is empty because there's nothing really to trace, if I write the whole exception via writeln(thr) rather than writeln(thr.info), I'll get back the file+line of the failed assert, which should be enough for a module constructor (the Druntime function which ends up calling the actual module ctors isn't really important here).

Nevermind, I was printing out the wrong file, there really is some kind of bug here. Anyway I'll file a small test-case to bugzilla.
August 19, 2013
On 8/19/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> Nevermind, I was printing out the wrong file, there really is some kind of bug here. Anyway I'll file a small test-case to bugzilla.

So it turns out it has nothing to do with the win32 subsystem: http://d.puremagic.com/issues/show_bug.cgi?id=10851
August 19, 2013
Am 19/08/2013 12:02, schrieb Andrej Mitrovic:
> On 8/19/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>> Thinking about it some more I think the .info field is empty because
>> there's nothing really to trace, if I write the whole exception via
>> writeln(thr) rather than writeln(thr.info), I'll get back the
>> file+line of the failed assert, which should be enough for a module
>> constructor (the Druntime function which ends up calling the actual
>> module ctors isn't really important here).
>
> Nevermind, I was printing out the wrong file, there really is some
> kind of bug here. Anyway I'll file a small test-case to bugzilla.
>

Well if you didn't build druntime with debug information then it is possible that the stack trace code is not able to resolve the stackframe the exceptionw as thrown in.

Kind Regards
Benjamin Thaut