www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12163] New: pdb debugging (win64): stepping loops points to incorrect lines

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163

           Summary: pdb debugging (win64): stepping loops points to
                    incorrect lines
           Product: D
           Version: D2
          Platform: x86_64
        OS/Version: Windows
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: turkeyman gmail.com


--- Comment #0 from Manu <turkeyman gmail.com> 2014-02-14 16:50:31 PST ---
This is extremely annoying, and really hinders the DMD debugging experience.

Example program:

0   void main()
1   {
2     int[] things = [1,2,3,4];
3
4     foreach(i; things)
5     {
6       if(i == 2)
7         continue;
8
9       if(i != 3)
10      {
11        int x = 0;
12      }
13    }
14
15    int last = 0;
16  }

Compile this for Win64, in VisualD, place a breakpoint on line 2, and begin
debugging.
Single-step through the program and watch the cursor carefully as it moves; the
cursor movement is very confusing.

While stepping (using only F10), the program execution is as follows:
 2     int[] things = [1,2,3,4];
 4     foreach(i; things)
 6       if(i == 2)        ; false
 9       if(i != 3)        ; false
 11        int x = 0;      ; WRONG! within if(false), should be 13
 4     foreach(i; things)
 6       if(i == 2)        ; true
                           ; MISSING: should step to 7 (continue;)
 11        int x = 0;      ; WRONG! within if(false), should be 13
 4     foreach(i; things)
 6       if(i == 2)        ; false
 9       if(i != 3)        ; true
 11        int x = 0;
                           ; MISSING: should step to 13
 4     foreach(i; things)
 6       if(i == 2)        ; false
 9       if(i != 3)        ; false
 11        int x = 0;      ; WRONG! within if(false), should be 13
 4     foreach(i; things)
 15    int last = 0;


The flow should be:
 2     int[] things = [1,2,3,4];
 4     foreach(i; things)
 6       if(i == 2)
 9       if(i != 3)
 13    }
 4     foreach(i; things)
 6       if(i == 2)
 7         continue;
 13    }
 4     foreach(i; things)
 6       if(i == 2)
 9       if(i != 3)
 11        int x = 0;
 13    }
 4     foreach(i; things)
 6       if(i == 2)
 9       if(i != 3)
 13    }
 4     foreach(i; things)
 15    int last = 0;

It seems the debug info is writing the last meaningful line  of the loop
regardless of it's nested depth, instead of the line of the closing '}' at the
end of each loop iteration.
This is very confusing when stepping complex constructs with deep nested
content.
It is also important to be able to place a breakpoint on the closing '}' to
catch a final opportunity to inspect the values within the loop iteration
before the next iteration begins.

Currently, the 'continue' line seems to just be skipped. The execution should
move there before jumping to the closing '}' so you can place breakpoints
allowing to inspect the loop iteration values that caused the case.

Without proper cursor movement, it's impossible to place breakpoints to inspect
the state that leads to many situations; one of the most important tasks for a
debugger.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 14 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163


Rainer Schuetze <r.sagitario gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |r.sagitario gmx.de
           Platform|x86_64                      |All


--- Comment #1 from Rainer Schuetze <r.sagitario gmx.de> 2014-02-15 00:26:47
PST ---
It's the same for win32, I suspect it is similar with DWARF output. The reason
probably is that there is no line number info for the closing braces.

The patch to create lexical scope might help here:
https://github.com/D-Programming-Language/dmd/pull/2867

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163


yazan.dabain gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yazan.dabain gmail.com
         OS/Version|Windows                     |All


--- Comment #2 from yazan.dabain gmail.com 2014-02-15 01:39:57 PST ---
The same behavior can be observed on Linux with DWARF symbols.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163


Manu <turkeyman gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|major                       |critical


--- Comment #3 from Manu <turkeyman gmail.com> 2014-02-15 01:57:08 PST ---
Right, so it seems it's a line numbering thing rather than a win64/pdb thing.
I think that calls for a bump in priority if debugging experience on all
platforms is crooked.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163



--- Comment #4 from yazan.dabain gmail.com 2014-02-15 01:59:01 PST ---
Ohh, your expected output is incorrect.
The test is (i != 3) not (i == 3).

And so, the expected output is:

2    int[] things = [1,2,3,4];
4    foreach(i; things)
6      if(i == 2)
9      if(i != 3)
11       int x = 0;
13   }                          <-- missing/questionable
4    foreach(i; things)
6      if(i == 2)
7        continue;              <-- missing
13   }                          <-- missing/questionable
4    foreach(i; things)
6      if(i == 2)
9      if(i != 3)
13   }                          <-- missing/questionable
4    foreach(i; things)
6      if(i == 2)
9      if(i != 3)
11       int x = 0;
13   }                          <-- missing/questionable
4    foreach(i; things)
15   int last = 0;
16 }

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163



--- Comment #5 from Manu <turkeyman gmail.com> 2014-02-15 04:15:03 PST ---
(In reply to comment #4)
 Ohh, your expected output is incorrect.
 The test is (i != 3) not (i == 3).

Haha, true. Yeah sorry about that. Perfect example of how the existing debugging experience is broken and doesn't do it right :P I had to type my expectation by hand, and couldn't test it... -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 15 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163



--- Comment #6 from Manu <turkeyman gmail.com> 2014-02-15 04:19:53 PST ---
(In reply to comment #4)
 13   }                          <-- missing/questionable

I should add, I don't think this is questionable at all. All C compiler's I've ever used (many!) do this, and without it, it would be impossible to place a breakpoint on the last line of the loop, which is a very important tool. The reason you want to place a breakpoint on the closing '}' is so you have a final opportunity to inspect the state of all variables within that cycle of the loop. If the last operation in the loop skipped right into the next cycle of the loop, you would have nowhere you are able to break to inspect the result of that operation. It's obvious that DMD already does have a moment where it intends to step to the 'end of the loop cycle', except rather than pointing to the '}', it incorrectly points to the last significant line in the code, no matter how deeply nested it happens to be. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 15 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12163


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies gmail.com


--- Comment #7 from yebblies <yebblies gmail.com> 2014-02-16 03:04:14 EST ---
(In reply to comment #6)
 It's obvious that DMD already does have a moment where it intends to step to
 the 'end of the loop cycle', except rather than pointing to the '}', it
 incorrectly points to the last significant line in the code, no matter how
 deeply nested it happens to be.

Yeah, it simply doesn't know where the end of the loop is. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 15 2014