Question about function call stack on x64

Hi all,
I’m not very sure if it’s OK to discuss this question rather than driver
dev.
I want to use kv command in windbg to get the parameter from dump file.
However, it’s OK on debug version , but it’s failed on release version.
Here is my code snippet:
void Foo(int a, int b)
{
printf(“%x %x\n”, a, b);
printf(“%p\n”,Foo);

Foo(a,b);
}
int main()
{
DebugBreak();
Foo(0x11223344,0x12345678);
return 0;
}

0:000> kv
Child-SP RetAddr : Args to Child
: Call Site
000000000031fb80 000000013fee1059 : 0000000000000001 0000000000000000
0000000000000000 0000000000000000 : MyTest!Foo+0x10
[c:\users\zhangm21\documents\visual studio
2010\projects\mytest\mytest\mytest.cpp @ 8]
000000000031fbb0 000000013fee1212 : 0000000000000001 0000000c8e19c1b7
0000000000000000 0000000000000000 : MyTest!main+0x19
[c:\users\zhangm21\documents\visual studio
2010\projects\mytest\mytest\mytest.cpp @ 16]
000000000031fbe0 0000000076cd652d : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : MyTest!__tmainCRTStartup+0x11a
[f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 555]
000000000031fc10 000000007710c521 : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : kernel32!BaseThreadInitThunk+0xd
000000000031fc40 0000000000000000 : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : ntdll!RtlUserThreadStart+0x1d

Obvisouly, the Foo parameter is 0x11223344 and 0x12345678, but the result
from windbg is wrong.
Marvin

You may want to check

http://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention

Anton Bassov

In the release version calls might be optimized out, and the parameters passed in registers are not required to be stored on stack. If a parameter is not used anymore in the function, it might get lost.

This is why debugging a release build is a pain.

“Args to Child” is a really poor name for these columns. I discuss them on
both the x86 and x64 here:

http://analyze-v.com/?p=7

-scott
OSR

“Marvin Zhang” wrote in message news:xxxxx@ntdev…
Hi all,
I’m not very sure if it’s OK to discuss this question rather than driver
dev.
I want to use kv command in windbg to get the parameter from dump file.
However, it’s OK on debug version , but it’s failed on release version.
Here is my code snippet:
void Foo(int a, int b)
{
printf(“%x %x\n”, a, b);
printf(“%p\n”,Foo);

Foo(a,b);
}
int main()
{
DebugBreak();
Foo(0x11223344,0x12345678);
return 0;
}

0:000> kv
Child-SP RetAddr : Args to Child
: Call Site
000000000031fb80 000000013fee1059 : 0000000000000001 0000000000000000
0000000000000000 0000000000000000 : MyTest!Foo+0x10
[c:\users\zhangm21\documents\visual studio
2010\projects\mytest\mytest\mytest.cpp @ 8]
000000000031fbb0 000000013fee1212 : 0000000000000001 0000000c8e19c1b7
0000000000000000 0000000000000000 : MyTest!main+0x19
[c:\users\zhangm21\documents\visual studio
2010\projects\mytest\mytest\mytest.cpp @ 16]
000000000031fbe0 0000000076cd652d : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : MyTest!__tmainCRTStartup+0x11a
[f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 555]
000000000031fc10 000000007710c521 : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : kernel32!BaseThreadInitThunk+0xd
000000000031fc40 0000000000000000 : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : ntdll!RtlUserThreadStart+0x1d

Obvisouly, the Foo parameter is 0x11223344 and 0x12345678, but the result
from windbg is wrong.
Marvin

Thanks all your reply. I found there is parameter of compiling /homeparams(even
though X64 call convention use register to pass parameters, this compiling
parameter will force to store register back to stack ), which is enable in
checked build and is not enable in release build by default. I add this in
my release build, it works. But I’m not sure if it will result any
performance issue.

On Mon, Jul 1, 2013 at 10:48 PM, Scott Noone wrote:

> ?Args to Child? is a really poor name for these columns. I discuss them on
> both the x86 and x64 here:
>
> http://analyze-v.com/?p=7
>
> -scott
> OSR
>
> “Marvin Zhang” wrote in message news:xxxxx@ntdev…
>
> Hi all,
> I’m not very sure if it’s OK to discuss this question rather than driver
> dev.
> I want to use kv command in windbg to get the parameter from dump file.
> However, it’s OK on debug version , but it’s failed on release version.
> Here is my code snippet:
> void Foo(int a, int b)
> {
> printf(“%x %x\n”, a, b);
> printf(“%p\n”,Foo);
>
> Foo(a,b);
> }
> int main()
> {
> DebugBreak();
> Foo(0x11223344,0x12345678);
> return 0;
> }
>
> 0:000> kv
> Child-SP RetAddr : Args to Child : Call Site
> 000000000031fb80 000000013fee1059 : 0000000000000001 0000000000000000
> 0000000000000000 0000000000000000 : MyTest!Foo+0x10
> [c:\users\zhangm21\documents**visual studio 2010\projects\mytest\mytest*
> *mytest.cpp @ 8]
> 000000000031fbb0 000000013fee1212 : 0000000000000001 0000000c8e19c1b7
> 0000000000000000 0000000000000000 : MyTest!main+0x19
> [c:\users\zhangm21\documents**visual studio 2010\projects\mytest\mytest*
> *mytest.cpp @ 16]
> 000000000031fbe0 0000000076cd652d : 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000 : MyTest!_tmainCRTStartup+0x11a
> [f:\dd\vctools\crt_bld\self
**64_amd64\crt\src\crtexe.c @ 555]
> 000000000031fc10 000000007710c521 : 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000 : kernel32!BaseThreadInitThunk+**0xd
> 000000000031fc40 0000000000000000 : 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000 : ntdll!RtlUserThreadStart+0x1d
>
> Obvisouly, the Foo parameter is 0x11223344 and 0x12345678, but the result
> from windbg is wrong.
> Marvin
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/ showlists.cfm?list=ntdevhttp:
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.
cfm?name=ListServerhttp:
></http:></http:>

>>But I’m not sure if it will result any performance issue.

In short there is a reason it is disabled in release. :slight_smile:

What you are doing here is to ask computer to override the optimization (pass first 4 parameters by register), so for each function header it is going to mov these 4 registers to the stack location.

Now multiply this overhead with the number of function being called (repeatedly) and that will be your performance impact.

Another question: is there similar pain in RISC(such as ARM) compiler ?

On Tue, Jul 2, 2013 at 11:09 AM, wrote:

> >>But I’m not sure if it will result any performance issue.
>
> In short there is a reason it is disabled in release. :slight_smile:
>
> What you are doing here is to ask computer to override the optimization
> (pass first 4 parameters by register), so for each function header it is
> going to mov these 4 registers to the stack location.
>
> Now multiply this overhead with the number of function being called
> (repeatedly) and that will be your performance impact.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

I am not sure of that yet, a look on ARM manuals will surly help you. I googled ARM calling convention and end up at http://en.wikipedia.org/wiki/Calling_convention#ARM. Take a look

Marvin Zhang wrote:

Another question: is there similar pain in RISC(such as ARM) compiler ?

Remember that this is not an attribute of a particular processor or even
a particular compiler. It is merely a software convention. This
happens to be how Microsoft decided to implement function calls in the
x64 world. Linux uses a different convention.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.