Thread overview
calling a function inside visual D debugger: partially possible, want better support
Oct 19, 2012
timotheecour
Oct 21, 2012
Rainer Schuetze
Dec 14, 2014
Blackcat345
October 19, 2012
short version:
how to call a (non extern-C) function from visualD's debugger? ( I can do it with extern C)
how to call a function with arguments that are stack variables (I can do it with actual numeric values, eg actual pointer addresses)

long version:

when debugging a session inside visual D, it can be very useful to call functions directly, eg:

* to print variables that visual D doesn't display properly (such as dynamic arrays, where visualD just prints the length and pointer)

* for interactive purposes (eg trying a function with different parameters)

Currently, visualD's support for this is limited, but I was able to do certain useful things (I'm not sure if many people realized one can do this in visuald, but this can be useful):

suppose we compile a D program into Main.exe:
we can call extern(C) functions as follows, by adding a watch variable in visual studio debugger and entering in the name field:
Main.exe!main_test@test1(2)
=> will show value=25, type=int, and will print in the command prompt "res=25"

now get address of z1 by looking into "Locals":
it shows:
-		z1	{length=4 ptr=0x01f20f40 {1} }	int[]
then display the dynamic array z1:
Main.exe!main_test@writelnPtr(3,0x01f20f40)

This is nice but not very convenient. Is there a way (if not, can that be addressed in the near future) to support the following?

* Main.exe!main_test@writeln2(z1)
=>currently returns: identifier "z1" is undefined	

* Main.exe!main_test@writeln2([1,2,3])
=>currently returns: expected a type specifier

* Main.exe!main_test@writeln3()
=>currently returns: identifier "main_test@writeln3" is undefined	

I also tried with the mangled name of writeln3 but that didn't work with visuald D. However, it DOES work on OSX, after compiling with debug symbols and then running under lldb:

b _Dmain
r
(lldb) expr (int) _D5tests16test_scratch_tim8testfun5FiZi (4)
=> doesn't work
(lldb) expr (int) D5tests16test_scratch_tim8testfun5FiZi (4)
=> successfully runs the underlying function once we remove the leading underscore

----
module main_test;
void main(){
    int[]z1=[1,2,3];
//breakpoint here
    writeln(z1);
}
extern(C)auto test1(int x){
	auto y=x*x;
	writeln("res=",y);
	return y;
}
extern(C)void writelnPtr(size_t n,void*ptr){
	writeln((cast(int*)ptr)[0..n]);
}
extern(C)void writeln2(int[]z){
	writeln(z);
}
void writeln3(){
	writeln("test");
}
----



October 21, 2012

On 10/20/2012 12:53 AM, timotheecour wrote:
> short version:
> how to call a (non extern-C) function from visualD's debugger? ( I can
> do it with extern C)
> how to call a function with arguments that are stack variables (I can do
> it with actual numeric values, eg actual pointer addresses)
>
> long version:
>
> when debugging a session inside visual D, it can be very useful to call
> functions directly, eg:
>
> * to print variables that visual D doesn't display properly (such as
> dynamic arrays, where visualD just prints the length and pointer)
>
> * for interactive purposes (eg trying a function with different parameters)
>
> Currently, visualD's support for this is limited, but I was able to do
> certain useful things (I'm not sure if many people realized one can do
> this in visuald, but this can be useful):

I know it's possible and I use it in C++ from time to time, but never tried it in D.

>
> suppose we compile a D program into Main.exe:
> we can call extern(C) functions as follows, by adding a watch variable
> in visual studio debugger and entering in the name field:
> Main.exe!main_test@test1(2)
> => will show value=25, type=int, and will print in the command prompt
> "res=25"
>
> now get address of z1 by looking into "Locals":
> it shows:
> -        z1    {length=4 ptr=0x01f20f40 {1} }    int[]
> then display the dynamic array z1:
> Main.exe!main_test@writelnPtr(3,0x01f20f40)
>
> This is nice but not very convenient. Is there a way (if not, can that
> be addressed in the near future) to support the following?

VS2012 allows "main_test@writelnPtr(z1.length,z1.ptr)"

Actually, the changes to autoexp.dat that are done by the installer are supposed to display dynamic and associative arrays, but it seems they are broken in VS2012 and maybe also 2010.

>
> * Main.exe!main_test@writeln2(z1)
> =>currently returns: identifier "z1" is undefined

VS2012 says: "Passing class, struct or union types by value to a function evaluation is not supported". It works if you pass the argument by reference.

>
> * Main.exe!main_test@writeln2([1,2,3])
> =>currently returns: expected a type specifier

The VS debugger expects C/C++ syntax, so it cannot do this.


>
> * Main.exe!main_test@writeln3()
> =>currently returns: identifier "main_test@writeln3" is undefined

If you disable name demangling by cv2pdb, the symbol _D9main_test8writeln3FZv resolves to the function writeln3, but unfortunately its type is reported as "void*". I guess the VS debugger does not allow the calling convention used by D in function evaluation.

If you use mago as the debug engine, you will get better D expression support and output, but it is not capable of running functions through watch expressions. Unfortunately development of mago seems to have stopped/paused. Nevertheless, I think a dedicated debug engine is the way to go for the best user experience.

December 14, 2014
I've been messing around with this for a couple of hours, and I'm
having difficulty pdf[/url] determining whether gdb on OS X can be used
with DMD at all (it seems to work ok with gdc). I've tried
compiling with both -g and -gc switches.





-------------------------
watson