www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ide - Visual D return BP

reply Bert <Bert gmail.com> writes:
if (x)
     return

do()

putting a BP on return will cause the BP to hit jump to do on 
execution no matter the value of x. This is very annoying ;/

I know this has been brought up before and supposedly it is an 
issue with D itself.

Can anything be done about it? It is not sane. No programming 
language I have ever used works this way.

00007FF6BEC8FC6C  cmp         rcx,rax
00007FF6BEC8FC6F  je          foo+48h (07FF6BEC8FC78h)
00007FF6BEC8FC71  pop         rsi
00007FF6BEC8FC72  pop         rbx
00007FF6BEC8FC73  mov         rsp,rbp
00007FF6BEC8FC76  pop         rbp
00007FF6BEC8FC77  ret
				return;
		
			Do();
00007FF6BEC8FC78  mov         rcx,qword ptr [this]
00007FF6BEC8FC7C  sub         rsp,20h
00007FF6BEC8FC80  mov         rax,qword ptr [rcx]
00007FF6BEC8FC83  call        qword ptr [rax+78h]
00007FF6BEC8FC87  add         rsp,20h


There is definitely assembly code that should be able to have a 
BP put at it to make it all work. The way it works, one is forced 
to add junk code simply to get a BP to work correctly in to a 
very common programming semantic.

It seems more like a bug to me, like somehow the BP gets added 
after the return rather than before it.

I'm not sure how it couldn't work, you mentioned something about 
the D language, optimizations, and Walter refusing to allow it to 
work. Surely there is some way to get this to function correctly?

Thanks
Aug 11 2019
parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
On 11/08/2019 11:47, Bert wrote:
 if (x)
     return
 
 do()
 
 putting a BP on return will cause the BP to hit jump to do on execution
 no matter the value of x. This is very annoying ;/
 
 I know this has been brought up before and supposedly it is an issue
 with D itself.
 
 Can anything be done about it? It is not sane. No programming language I
 have ever used works this way.
 
 00007FF6BEC8FC6C  cmp         rcx,rax
 00007FF6BEC8FC6F  je          foo+48h (07FF6BEC8FC78h)
 00007FF6BEC8FC71  pop         rsi
 00007FF6BEC8FC72  pop         rbx
 00007FF6BEC8FC73  mov         rsp,rbp
 00007FF6BEC8FC76  pop         rbp
 00007FF6BEC8FC77  ret
                 return;
        
             Do();
 00007FF6BEC8FC78  mov         rcx,qword ptr [this]
 00007FF6BEC8FC7C  sub         rsp,20h
 00007FF6BEC8FC80  mov         rax,qword ptr [rcx]
 00007FF6BEC8FC83  call        qword ptr [rax+78h]
 00007FF6BEC8FC87  add         rsp,20h
 
 
 There is definitely assembly code that should be able to have a BP put
 at it to make it all work. The way it works, one is forced to add junk
 code simply to get a BP to work correctly in to a very common
 programming semantic.
In this example it could work, but the code after the jump is not associated with the return statement, but it is a duplication of the epilog of the function that is considered to have the location of the closing brace. In debug builds the compiler should avoid these kind of optimizations and insert/keep a jump to the end of the function.
 
 It seems more like a bug to me, like somehow the BP gets added after the
 return rather than before it.
 
 I'm not sure how it couldn't work, you mentioned something about the D
 language, optimizations, and Walter refusing to allow it to work. Surely
 there is some way to get this to function correctly?
 
 Thanks
 
It's not a problem of the language, but the compiler implementation. I recently filed a bug for this issue when Walter asked for reports: https://issues.dlang.org/show_bug.cgi?id=19985. Somewhat related: https://issues.dlang.org/show_bug.cgi?id=19989 https://issues.dlang.org/show_bug.cgi?id=19991
Aug 15 2019
parent reply Bert <Bert gmail.com> writes:
On Thursday, 15 August 2019 at 18:23:25 UTC, Rainer Schuetze 
wrote:
 On 11/08/2019 11:47, Bert wrote:
 if (x)
     return
 
 do()
 
 putting a BP on return will cause the BP to hit jump to do on 
 execution no matter the value of x. This is very annoying ;/
 
 I know this has been brought up before and supposedly it is an 
 issue with D itself.
 
 Can anything be done about it? It is not sane. No programming 
 language I have ever used works this way.
 
 00007FF6BEC8FC6C  cmp         rcx,rax
 00007FF6BEC8FC6F  je          foo+48h (07FF6BEC8FC78h)
 00007FF6BEC8FC71  pop         rsi
 00007FF6BEC8FC72  pop         rbx
 00007FF6BEC8FC73  mov         rsp,rbp
 00007FF6BEC8FC76  pop         rbp
 00007FF6BEC8FC77  ret
                 return;
 
             Do();
 00007FF6BEC8FC78  mov         rcx,qword ptr [this]
 00007FF6BEC8FC7C  sub         rsp,20h
 00007FF6BEC8FC80  mov         rax,qword ptr [rcx]
 00007FF6BEC8FC83  call        qword ptr [rax+78h]
 00007FF6BEC8FC87  add         rsp,20h
 
 
 There is definitely assembly code that should be able to have 
 a BP put at it to make it all work. The way it works, one is 
 forced to add junk code simply to get a BP to work correctly 
 in to a very common programming semantic.
In this example it could work, but the code after the jump is not associated with the return statement, but it is a duplication of the epilog of the function that is considered to have the location of the closing brace. In debug builds the compiler should avoid these kind of optimizations and insert/keep a jump to the end of the function.
 
 It seems more like a bug to me, like somehow the BP gets added 
 after the return rather than before it.
 
 I'm not sure how it couldn't work, you mentioned something 
 about the D language, optimizations, and Walter refusing to 
 allow it to work. Surely there is some way to get this to 
 function correctly?
 
 Thanks
 
It's not a problem of the language, but the compiler implementation. I recently filed a bug for this issue when Walter asked for reports: https://issues.dlang.org/show_bug.cgi?id=19985. Somewhat related: https://issues.dlang.org/show_bug.cgi?id=19989 https://issues.dlang.org/show_bug.cgi?id=19991
Thanks, I appreciate it. It's one annoying issue[maybe the biggest now, everything else seems to be working well so far, although I did experience a crash of VS earlier]. I'm not sure if this can be fixed, but frequently when I step in to a function call(F11) any intermediate calls are always stepped in to foo(bar()) F11 to get in to foo will get in to bar also. This can be quite annoying and I never remember having this issue in other languages. I realize there is no solution since it is impossible for the compiler to know if you want to step in to bar too or not... But it seems in some cases other debuggers(such as .NET) somehow eliminate common cases that are not necessary but I can't recall them off hand. I wonder if we could not mark a function with some attribute that will prevent the debugger from stepping in to it?(would have to manually add a BP) Mago_StepInto_Ignore void bar() { } [attr could be aliased by user to something shorter] and if the attribute exists the the debugger will not step in to bar and treat it all as atomic and get directly in to foo. Or one could create a text file of functions (using fully qualified name) that will be ignored. The debugger reads it and ignores them like above(this is so the source code doesn't get littered with irrelevant code. This might actually be an interesting way to interface with the debugger by providing it with contextual info on things to do. e.g., one could ignore stepping in to whole modules, the phobos, etc. The reason here is that many functions that act as properties using as arguments get stepped in to and one can waste quite a bit of time in some instances getting directly to the code they want. Some of these functions don't require debugging because they are simple so being able to get them ignored. Ideally it would be supported somehow in the ide itself but I don't see that happening(e.g., one could mark the symbols to ignore by clicking on them).
Aug 16 2019
parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
On 16/08/2019 23:22, Bert wrote:
 
 I'm not sure if this can be fixed, but frequently when I step in to a
 function call(F11) any intermediate calls are always stepped in to
 
 foo(bar())
 
 F11 to get in to foo will get in to bar also. This can be quite annoying
 and I never remember having this issue in other languages. I realize
 there is no solution since it is impossible for the compiler to know if
 you want to step in to bar too or not...
For single cases there is "Step into specific" in the context menu that allows you to select the function to step into, ignoring all others. It doesn't work too well with virtual function dispatch, though.
 
 But it seems in some cases other debuggers(such as .NET) somehow
 eliminate common cases that are not necessary but I can't recall them
 off hand.
 
 
 I wonder if we could not mark a function with some attribute that will
 prevent the debugger from stepping in to it?(would have to manually add
 a BP)
 
  Mago_StepInto_Ignore void bar() { }
 
 [attr could be aliased by user to something shorter]
 
 and if the attribute exists the the debugger will not step in to bar and
 treat it all as atomic and get directly in to foo.
UDAs are currently not part of the debug info, so it would not be so easy to get that info to the debugger.
 
 Or one could create a text file of functions (using fully qualified
 name) that will be ignored. The debugger reads it and ignores them like
 above(this is so the source code doesn't get littered with irrelevant
 code. This might actually be an interesting way to interface with the
 debugger by providing it with contextual info on things to do. e.g., one
 could ignore stepping in to whole modules, the phobos, etc.
Adding fully qualified functions to "c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Packages\Debugger\Visualizers\default.natstepfilter" seems to work. You can also create a similar file in the same folder or in "c:\Users\user-name\Documents\Visual Studio 2019\Visualizers". Maybe there is also a way to have a similar project local file.
 
 The reason here is that many functions that act as properties using as
 arguments get stepped in to and one can waste quite a bit of time in
 some instances getting directly to the code they want. Some of these
 functions don't require debugging because they are simple so being able
 to get them ignored.
 
 Ideally it would be supported somehow in the ide itself but I don't see
 that happening(e.g., one could mark the symbols to ignore by clicking on
 them).
 
Aug 16 2019
parent Bert <Bert gmail.com> writes:
On Saturday, 17 August 2019 at 06:08:43 UTC, Rainer Schuetze 
wrote:
 On 16/08/2019 23:22, Bert wrote:
 
 I'm not sure if this can be fixed, but frequently when I step 
 in to a function call(F11) any intermediate calls are always 
 stepped in to
 
 foo(bar())
 
 F11 to get in to foo will get in to bar also. This can be 
 quite annoying and I never remember having this issue in other 
 languages. I realize there is no solution since it is 
 impossible for the compiler to know if you want to step in to 
 bar too or not...
For single cases there is "Step into specific" in the context menu that allows you to select the function to step into, ignoring all others. It doesn't work too well with virtual function dispatch, though.
 
 But it seems in some cases other debuggers(such as .NET) 
 somehow eliminate common cases that are not necessary but I 
 can't recall them off hand.
 
 
 I wonder if we could not mark a function with some attribute 
 that will prevent the debugger from stepping in to it?(would 
 have to manually add a BP)
 
  Mago_StepInto_Ignore void bar() { }
 
 [attr could be aliased by user to something shorter]
 
 and if the attribute exists the the debugger will not step in 
 to bar and treat it all as atomic and get directly in to foo.
UDAs are currently not part of the debug info, so it would not be so easy to get that info to the debugger.
Probably a good idea. It will mix in things that probably shouldn't be mixed together.
 
 Or one could create a text file of functions (using fully 
 qualified name) that will be ignored. The debugger reads it 
 and ignores them like above(this is so the source code doesn't 
 get littered with irrelevant code. This might actually be an 
 interesting way to interface with the debugger by providing it 
 with contextual info on things to do. e.g., one could ignore 
 stepping in to whole modules, the phobos, etc.
Adding fully qualified functions to "c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Packages\Debugger\Visualizers\default.natstepfilter" seems to work. You can also create a similar file in the same folder or in "c:\Users\user-name\Documents\Visual Studio 2019\Visualizers". Maybe there is also a way to have a similar project local file.
That would be nice, I don't have that dir and it probably changes. If we could get a project file that can do it then it might work really well. What would be really cool is to have some way to specify BP conditions(e.g., if cnt > 3 then break; or if (x) then break). One can then have different files for different debugging cases(save) them if they want.
Aug 17 2019