www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5944] New: Five ideas for the stacktrace

reply d-bugmail puremagic.com writes:
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: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



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
----------------

Instead of just:


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: -------
May 07 2011
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5944




KennyTM~ reminds me that the [idea 3] is bugus, because divisions by zero are
not DMD exceptions. So please ignore it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 07 2011