[Issue 5944] New: Five ideas for the stacktrace

`http://d.puremagic.com/issues/show_bug.cgi?id=5944`
```
Summary: Five ideas for the stacktrace
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Keywords: diagnostic
Severity: enhancement
Priority: P2
Component: druntime
AssignedTo: nob...@puremagic.com
ReportedBy: bearophile_h...@eml.cc

--- Comment #0 from bearophile_h...@eml.cc 2011-05-07 06:06:11 PDT ---
This little program:

int foo(int x, int y) {
return x / y;
}
void main() {
foo(1, 0);
}

Produces the stack trace (dmd 2.053beta):

object.Error: Integer Divide by Zero
----------------
...\test.d(5): _Dmain
----------------

While this similar Python2 program:

def foo(x, y):
return x / y
def main():
foo(1, 0)
main()

Gives the stacktrace (feel fee to ignore the first global call to main()):

Traceback (most recent call last):
File "...\temp.py", line 5, in <module>
main()
File "...\temp.py", line 4, in main
foo(1, 0)
File "...\temp.py", line 2, in foo
return x / y
ZeroDivisionError: integer division or modulo by zero

[Idea1] On Python the stacktrace is reversed compared to the D one, maybe this
is better.

[Idea2] And as first line it prints this, that's useful for D too:
Traceback (most recent call last):

[Idea3] And the Python stacktrace shows the line/function where the division by
zero happens too, instead of just all the frames of the functions up to the one
that has called the function that has generated the division by zero. I'd like
to see foo() too in the D stacktrace.

------------------------------------

This program:

int foo(int x) {
if (x > 0)
return bar(x - 1);
else
return 10 / x;
}
int bar(int x) {
if (x > 0)
return foo(x - 1);
else
return 10 / x;
}
void main() {
foo(10);
}

dmd 2.053beta (witout -g switch) gives:

object.Error: Integer Divide by Zero
----------------
40CCF4
40CB6B
402041
402021
402041
402021
402041
402021
402041
402021
402041
402021
40205A
4025FB
4021F7
411FDD
----------------

[Idea4] When the -g switch is not used I suggest to add a note about missing
debug info, useful for not expert programmers/newbies:

object.Error: Integer Divide by Zero
----------------
Traceback, no symbolic debug info (most recent call last):
40CCF4
40CB6B
402041
402021
402041
402021
402041
402021
402041
402021
402041
402021
40205A
4025FB
4021F7
411FDD
----------------

object.Error: Integer Divide by Zero
----------------
Traceback (most recent call last):
40CCF4
40CB6B
402041
402021
402041
402021
402041
402021
402041
402021
402041
402021
40205A
4025FB
4021F7
411FDD
----------------

------------------------------------

This little program:

int foo(int x) {
if (x > 0)
return foo(x - 1);
else
return 10 / x;
}
void main() {
foo(10);
}

dmd 2.053beta gives just (here DMD has performed tail-call optimization, so
there are no stack frames to show for the recursive calls to foo()):

object.Error: Integer Divide by Zero
----------------
...
----------------

A bigger similar example:

import core.stdc.stdio: printf;
nothrow pure int str2int(const char *str, in int n=0) {
if (str == null || *str == '\0') {
int x = 10 / cast(size_t)*str; // A bug
return n;
} else
return str2int(str+1, n*10 + *str-'0');
}
void main() {
printf("%d\n", str2int("12345678".ptr));
}

The asm shows that DMD performs the tail-call optimization on str2int():

_D5test37str2intFNaNbxPaxiZi    comdat
push    EBX
mov EBX,8[ESP]
test    EBX,EBX
push    ESI
mov ESI,EAX
push    EDI
je  L12
cmp byte ptr [EBX],0
jne L1A
L12:        pop EDI
mov EAX,ESI
pop ESI
pop EBX
ret 4
L1A:        lea EDX,1[EBX]
movzx   ECX,byte ptr [EBX]
lea EDI,[ESI*4][ESI]
lea EDI,-030h[EDI*2][ECX]
mov ESI,EDI
mov EBX,EDX
test    EDX,EDX
je  L12
cmp byte ptr [EDX],0
je  L12
jmp short   L1A

object.Error: Integer Divide by Zero
----------------
...
----------------

[Idea5] In this case the stacktrace may add a note:

object.Error: Integer Divide by Zero
----------------
...\test.d(4): int test.str2int(const char*, const int) [Tail-Call Optimized]
----------------

--------------------------------------

This little program just crashes at runtime (dmd 2.053beta):

int foo() {
return foo();
}
void main() {
foo();
}

With DMD 2.052 it gives:
object.Error: Stack Overflow

------------------------------------

--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
```
• [Issue 5944] New: Five ideas for the stacktrace d-bugmail