Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Ticket #13 (assigned defect)

Opened 9 years ago

Last modified 6 years ago

call stack not displayed when exception is thrown

Reported by: rndgen Assigned to: sagitario (accepted)
Priority: major Component: Debugger
Version: 0.3.15 Keywords:
Cc:

Description

As the title says an incorrect call stack is shown when a user defined exception is thrown. This error does not appear on hardware exceptions(like dereferencing null pointers).

Test case:

import std.stdio;

void func1() {

func2();

}

void func2() {

//int *p=null; //*p=32; throw new Exception("msg");

}

void main() {

func1();

}

To get the call stack the "Thrown" checkbox for win32 exceptions must be set in the Debug->Exceptions... menu, because the D runtime catches all unhandled exceptions.

I'm using VS2008 shell with Visuald 0.3.15 on WinXp? and dmd 1.062.

Change History

08/24/10 18:22:59 changed by sagitario

I haven't used D1 much, but for D2, you don't get good call stacks with the release version of phobos, because there are no stack frames that the debugger can follow. Often what you see is _dthrow and then the function that called the function that has thrown the function.

It's way better if you use a debug build of phobos.

09/04/10 10:26:53 changed by rndgen

I did as you suggested, and recompiled phobos with debug information, however this did not solve the problem. The test results for both D1 and D2:

The '->' indicates where the program stopped according to the debugger. Although you only mentioned compiling phobos in debug mode, I tried compiling druntime too, but that only made things worse, and wheter phobos is with or without debug info made no difference.

D2 call stack with release druntime+debug phobos (same as release druntime+release phobos):

kernel32.dll!7c812a5b() [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] kernel32.dll!7c812a5b() debuggertest.exe!object@traceContext() + 0x14 bytes C++ debuggertest.exe__d_throw@4() + 0x14 bytes C++

-> debuggertest.exe!main@func1() Line 5 C++

debuggertest.exe!_Dmain() Line 14 + 0x5 bytes C++ debuggertest.exe!rt@dmain2@main@runMain() + 0xc bytes C++ debuggertest.exe!rt@dmain2@main@runAll() + 0x2e bytes C++ debuggertest.exe!_main() + 0x13c bytes C++ debuggertest.exe!_mainCRTStartup() + 0xa9 bytes C++ kernel32.dll!7c816fd7()

D2 call stack with debug druntime+debug phobos:

kernel32.dll!7c812a5b() [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] kernel32.dll!7c812a5b() debuggertest.exe!object@traceContext() Line 1219 C++ debuggertest.exe!object@Throwable@ctor() Line 1137 + 0x7 bytes C++ debuggertest.exe!object@Exception@ctor() Line 1226 + 0x11 bytes C++ 0012fdc4() debuggertest.exe!rt@dmain2@main@tryExec() Line 348 + 0xb bytes C++ debuggertest.exe!rt@dmain2@main@runAll() Line 414 + 0x11 bytes C++ debuggertest.exe!rt@dmain2@main@tryExec() Line 348 + 0xb bytes C++

-> debuggertest.exe!main(int argc=1, char * * argv=0x00a303c4) Line 430 C++

debuggertest.exe!_mainCRTStartup() + 0xa9 bytes C++ kernel32.dll!7c816fd7()

D1 call stack (both debug and release):

-> kernel32.dll!7c812a5b()

[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] kernel32.dll!7c812a5b() debuggertest.exe__setargv() + 0x3c6 bytes C++

I'm reposting the sample code to make sure the line numbers are consistent with those that are in the above call stacks: (The statements of func2() should be on separate lines, but I can't get it to display correctly)

import std.stdio;

void func1() {

func2();

}

void func2() {

//int *p=null; //*p=32; throw new Exception("msg");

}

void main() {

func1();

}

I beleive that a proper call stack on exceptions is very important, so any advice on how to get this work would be appreciated.

09/04/10 12:13:41 changed by sagitario

  • status changed from new to assigned.

What you see is what I meant with "the function that called the function that has thrown the function". This is caused by _d_throw@4 not having a proper stack frame that the debugger can follow. You can create it by adding option "-S" to the rule to make deh.c in win32.mak of druntime. It should look like this:

 deh.obj : src\rt\deh.c
	$(CC) -c $(CFLAGS) -S src\rt\deh.c

It even works for the release library. I haven't tested D1, though.

Thanks for insisting on a fix, I have always been annoyed by this, too. :-) I'll try to get this into the official druntime makefile.

09/13/10 02:36:06 changed by rndgen

Hehe, no problem on the insisting :). Anyway while this -S option fixes the above test case, I found another case which does not show a proper call stack:

void func3() {

int[] arr=[0, 1]; arr[15]=4;

}

The problem is probably similar to the previous one, but I could not get it to work. I am completely unfamiliar with debug information and related stuff though.

09/13/10 06:36:49 changed by sagitario

Looks good to me. Do you see the onRangeError function on the stack? In a release build, it might not come with a correct stack frame. I tried the dmd 2.048 release, and it worked. Are you using some optimizations?

Can you show the displayed call stack?

09/13/10 15:16:27 changed by rndgen

  • version changed from 0.3.14 to 0.3.15.

I'm using 2.047 because 2.048 has some critical regression. These are the compiler options I use for druntime:

DFLAGS=-g -nofloat -w -d -Isrc -Iimport

CFLAGS=-g

+the additional -S flag for deh.c

The compiler options for phobos:

DFLAGS=-g -nofloat -w -d

CFLAGS=-g -mn -6 -r

I'm using dmc 8.52.

With these settings this is the call stack I get for func3():

-> kernel32.dll!7c812a5b()

[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] kernel32.dll!7c812a5b() debuggertest.exe___SI?%_heap32_multpool_cpp4106907224_() + 0xb bytes C++ ffffffff()

Interestingly the func1() call stack which worked in a release build with -S now shows an incorrerct call stack too:

-> kernel32.dll!7c812a5b()

[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] kernel32.dll!7c812a5b() debuggertest.exe!object@traceContext() Line 1219 C++ debuggertest.exe!object@Throwable@ctor() Line 1137 + 0x7 bytes C++ debuggertest.exe!object@Exception@ctor() Line 1226 + 0x11 bytes C++ 0012fdc4() debuggertest.exe!rt@dmain2@main@tryExec() Line 348 + 0xb bytes C++ debuggertest.exe!rt@dmain2@main@runAll() Line 414 + 0x11 bytes C++ debuggertest.exe!rt@dmain2@main@tryExec() Line 348 + 0xb bytes C++ debuggertest.exe!main(int argc=1, char * * argv=0x00a403c4) Line 430 C++ debuggertest.exe!_mainCRTStartup() + 0xa9 bytes C++ kernel32.dll!7c816fd7()

With the release build I get this call stack for func3():

-> kernel32.dll!7c812a5b()

[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] kernel32.dll!7c812a5b() debuggertest.exe__d_newclass() + 0x95 bytes C++ debuggertest.exe!_mainCRTStartup() + 0xa9 bytes C++ kernel32.dll!7c816fd7()

I checked the dmc options and those are not optimiziations.

09/14/10 07:22:45 changed by sagitario

I just noticed that it works for me because I have debug symbols for the windows DLLs (kernel32.dll) from the Microsoft Symbol Server. Without these, I get unusable resluts similar to yours. To enable them, add http://msdl.microsoft.com/download/symbols to the tools->Options->Debugging->Symbols settings.

09/14/10 07:51:30 changed by rndgen

I will try that, however I'm interested why this can't be done normally. (I'm probably used to everything working out of the box for C++). Is it a fundamental limitation of D? In D the stack is not properly unwound on irrecoverable exceptions so I'm guessing it might be caused by this.

09/15/10 13:39:32 changed by rndgen

With these external dll's now debugging works perfectly for me too, however it would be worthwhile to find out why they are necessary.

09/15/10 17:36:11 changed by sagitario

As we are using the C++ debugger we might need to mimick what the C++ runtime does (if the debugger does not have a special way to detect the VC runtime library). The problem will probably disappear with the mago debugger.

09/13/13 21:12:22 changed by sagitario