Registers values throughout the stack

Hello all,
I have a question that seems to be basic, because it is one of the first issues the WinDbg user run into, but I haven’t found a solution since I first met WinDbg. Let’s say I’m processing a crash dump. Function in my driver calls another function in my driver and so on until the last function calls kernel routine, which invokes KeBugCheck and the kernel crashes. I have only the crash dump and at a first glance I can’t understand where is the problem in the kernel routine, so I have to check whether my functions and the parameters with they are invoked are ok. If the driver is built and ran in x86 configuration I can look at the output of !analyze -v or kb, see the first column with the ChildEBP and search for the parameters passed to my functions in the stack, knowing the fact that the parameters are pushed in the stack. But when the driver is build and ran in x64 configurations, the parameters are passed in the processor registers and I only can see the registers at the time of the function on the top of the stack (KeBugCheck). Is there a way to view the registers values throughout the stack, at he time each function through the stack is called? I suppose that I can disassemble each function, see where the old registers values are pushed in the stack and trace them, but it is a real pain, and I’m wondering if there is a normal way to do that. Thank you.

xxxxx@gmail.com wrote:

I have a question that seems to be basic, because it is one of the first issues the WinDbg user run into,

Well, only if you’re on x64…

Is there a way to view the registers values throughout the stack, at he time each function through the stack is called? I suppose that I can disassemble each function, see where the old registers values are pushed in the stack and trace them, but it is a real pain, and I’m wondering if there is a normal way to do that.

In the Windows x64 calling convention, the calling function must make
room on the stack for all of the parameters, as if they were going to be
pushed. Even though the first four are always passed in registers (rcx,
rdx, r8, r9), the caller has to allocate stack space for them, and he
must make room for at least 4, even if there are no parameters. Then,
when the called function needs to use those registers, he automatically
has a place to store the original values.

The net result is that, in many cases, the parameters ARE visible on the
stack, because the called function put them there. That often won’t be
true for the final function, but farther down the stack you can often
get lucky.


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

Use “.frame /r” command to display register context from specified stack frame.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, August 04, 2011 09:15 AM
To: Kernel Debugging Interest List
Subject: Re: [windbg] Registers values throughout the stack

xxxxx@gmail.com wrote:

I have a question that seems to be basic, because it is one of the
first issues the WinDbg user run into,

Well, only if you’re on x64…

Is there a way to view the registers values throughout the stack, at he time each function through the stack is called? I suppose that I can disassemble each function, see where the old registers values are pushed in the stack and trace them, but it is a real pain, and I’m wondering if there is a normal way to do that.

In the Windows x64 calling convention, the calling function must make room on the stack for all of the parameters, as if they were going to be pushed. Even though the first four are always passed in registers (rcx, rdx, r8, r9), the caller has to allocate stack space for them, and he must make room for at least 4, even if there are no parameters. Then, when the called function needs to use those registers, he automatically has a place to store the original values.

The net result is that, in many cases, the parameters ARE visible on the stack, because the called function put them there. That often won’t be true for the final function, but farther down the stack you can often get lucky.


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


WINDBG is sponsored by OSR

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

Be very careful with this as in the majority of cases, the original arguments are not going to be there. One must be prepared to discern whether a value in the home region is really a plausible parameter value.

In most cases (non-debug builds), parameters are *not* homed (only for vararg functions is this required).

Debug builds are typically performed with a compiler flag that requests that the first four parameters homed to their respective stack slots unconditionally. In these cases, the home region is a much more reliable indicator.

  • S (Msft)

-----Original Message-----
From: Tim Roberts
Sent: Thursday, August 04, 2011 9:14
To: Kernel Debugging Interest List
Subject: Re: [windbg] Registers values throughout the stack

xxxxx@gmail.com wrote:
> I have a question that seems to be basic, because it is one of the first issues the WinDbg user run into,

Well, only if you’re on x64…

> Is there a way to view the registers values throughout the stack, at he time each function through the stack is called? I suppose that I can disassemble each function, see where the old registers values are pushed in the stack and trace them, but it is a real pain, and I’m wondering if there is a normal way to do that.

In the Windows x64 calling convention, the calling function must make
room on the stack for all of the parameters, as if they were going to be
pushed. Even though the first four are always passed in registers (rcx,
rdx, r8, r9), the caller has to allocate stack space for them, and he
must make room for at least 4, even if there are no parameters. Then,
when the called function needs to use those registers, he automatically
has a place to store the original values.

The net result is that, in many cases, the parameters ARE visible on the
stack, because the called function put them there. That often won’t be
true for the final function, but farther down the stack you can often
get lucky.


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


WINDBG is sponsored by OSR

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

Note that for .frame /r, only the nonvolatile registers have correct values (though the nonvolatile values should always be correct on non-x86 platforms when using this command). Volatile registers aren’t preserved and thus can’t be unwound back.

  • S

-----Original Message-----
From: Jen-Lung Chiu
Sent: Thursday, August 04, 2011 9:27
To: Kernel Debugging Interest List
Subject: RE: [windbg] Registers values throughout the stack

Use “.frame /r” command to display register context from specified stack frame.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, August 04, 2011 09:15 AM
To: Kernel Debugging Interest List
Subject: Re: [windbg] Registers values throughout the stack

xxxxx@gmail.com wrote:
> I have a question that seems to be basic, because it is one of the
> first issues the WinDbg user run into,

Well, only if you’re on x64…

> Is there a way to view the registers values throughout the stack, at he time each function through the stack is called? I suppose that I can disassemble each function, see where the old registers values are pushed in the stack and trace them, but it is a real pain, and I’m wondering if there is a normal way to do that.

In the Windows x64 calling convention, the calling function must make room on the stack for all of the parameters, as if they were going to be pushed. Even though the first four are always passed in registers (rcx, rdx, r8, r9), the caller has to allocate stack space for them, and he must make room for at least 4, even if there are no parameters. Then, when the called function needs to use those registers, he automatically has a place to store the original values.

The net result is that, in many cases, the parameters ARE visible on the stack, because the called function put them there. That often won’t be true for the final function, but farther down the stack you can often get lucky.


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


WINDBG is sponsored by OSR

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


WINDBG is sponsored by OSR

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 almost never get lucky and have to do serious trolling to reconstruct
values when on the x64 (x86 is so much more pleasant in that regard). Very
easy to lose track and end up with the wrong value, which can lead to
confusing results.

I’ll also add that the “Args to Child” in the kv output represent the home
space of the functions, which can be a quick way to grab a value if you’re
lucky.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Skywing” wrote in message news:xxxxx@windbg…

Be very careful with this as in the majority of cases, the original
arguments are not going to be there. One must be prepared to discern
whether a value in the home region is really a plausible parameter value.

In most cases (non-debug builds), parameters are *not* homed (only for
vararg functions is this required).

Debug builds are typically performed with a compiler flag that requests that
the first four parameters homed to their respective stack slots
unconditionally. In these cases, the home region is a much more reliable
indicator.

  • S (Msft)

-----Original Message-----
From: Tim Roberts
Sent: Thursday, August 04, 2011 9:14
To: Kernel Debugging Interest List
Subject: Re: [windbg] Registers values throughout the stack

xxxxx@gmail.com wrote:
> I have a question that seems to be basic, because it is one of the first
> issues the WinDbg user run into,

Well, only if you’re on x64…

> Is there a way to view the registers values throughout the stack, at he
> time each function through the stack is called? I suppose that I can
> disassemble each function, see where the old registers values are pushed
> in the stack and trace them, but it is a real pain, and I’m wondering if
> there is a normal way to do that.

In the Windows x64 calling convention, the calling function must make
room on the stack for all of the parameters, as if they were going to be
pushed. Even though the first four are always passed in registers (rcx,
rdx, r8, r9), the caller has to allocate stack space for them, and he
must make room for at least 4, even if there are no parameters. Then,
when the called function needs to use those registers, he automatically
has a place to store the original values.

The net result is that, in many cases, the parameters ARE visible on the
stack, because the called function put them there. That often won’t be
true for the final function, but farther down the stack you can often
get lucky.


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


WINDBG is sponsored by OSR

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

Yes, it’s not common or typical for the compiler to conclude that homing all of the parameters is beneficial from a cost standpoint.

That being said, with the ability to retrieve nonvolatile register values, there are a number of cases where one can get more information about what’s going on in a call stack (versus x86), though some disassembly may be required.

  • S

-----Original Message-----
From: Scott Noone
Sent: Thursday, August 04, 2011 11:19
To: Kernel Debugging Interest List
Subject: Re:[windbg] Registers values throughout the stack

I almost never get lucky and have to do serious trolling to reconstruct
values when on the x64 (x86 is so much more pleasant in that regard). Very
easy to lose track and end up with the wrong value, which can lead to
confusing results.

I’ll also add that the “Args to Child” in the kv output represent the home
space of the functions, which can be a quick way to grab a value if you’re
lucky.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Skywing” wrote in message news:xxxxx@windbg…

Be very careful with this as in the majority of cases, the original
arguments are not going to be there. One must be prepared to discern
whether a value in the home region is really a plausible parameter value.

In most cases (non-debug builds), parameters are not homed (only for
vararg functions is this required).

Debug builds are typically performed with a compiler flag that requests that
the first four parameters homed to their respective stack slots
unconditionally. In these cases, the home region is a much more reliable
indicator.

- S (Msft)

-----Original Message-----
From: Tim Roberts
Sent: Thursday, August 04, 2011 9:14
To: Kernel Debugging Interest List
Subject: Re: [windbg] Registers values throughout the stack

xxxxx@gmail.com wrote:
> I have a question that seems to be basic, because it is one of the first
> issues the WinDbg user run into,

Well, only if you’re on x64…

> Is there a way to view the registers values throughout the stack, at he
> time each function through the stack is called? I suppose that I can
> disassemble each function, see where the old registers values are pushed
> in the stack and trace them, but it is a real pain, and I’m wondering if
> there is a normal way to do that.

In the Windows x64 calling convention, the calling function must make
room on the stack for all of the parameters, as if they were going to be
pushed. Even though the first four are always passed in registers (rcx,
rdx, r8, r9), the caller has to allocate stack space for them, and he
must make room for at least 4, even if there are no parameters. Then,
when the called function needs to use those registers, he automatically
has a place to store the original values.

The net result is that, in many cases, the parameters ARE visible on the
stack, because the called function put them there. That often won’t be
true for the final function, but farther down the stack you can often
get lucky.


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


WINDBG is sponsored by OSR

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


WINDBG is sponsored by OSR

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

+1

It seems like considerable luck is required.

Mm
On Aug 4, 2011 2:20 PM, “Scott Noone” wrote:
> I almost never get lucky and have to do serious trolling to reconstruct
> values when on the x64 (x86 is so much more pleasant in that regard). Very

> easy to lose track and end up with the wrong value, which can lead to
> confusing results.
>
> I’ll also add that the “Args to Child” in the kv output represent the home

> space of the functions, which can be a quick way to grab a value if you’re

> lucky.
>
> -scott
>
> –
> Scott Noone
> Consulting Associate and Chief System Problem Analyst
> OSR Open Systems Resources, Inc.
> http://www.osronline.com
>
>
> “Skywing” wrote in message news:xxxxx@windbg…
>
> Be very careful with this as in the majority of cases, the original
> arguments are not going to be there. One must be prepared to discern
> whether a value in the home region is really a plausible parameter value.
>
> In most cases (non-debug builds), parameters are not homed (only for
> vararg functions is this required).
>
> Debug builds are typically performed with a compiler flag that requests
that
> the first four parameters homed to their respective stack slots
> unconditionally. In these cases, the home region is a much more reliable
> indicator.
>
> - S (Msft)
>
> -----Original Message-----
> From: Tim Roberts
> Sent: Thursday, August 04, 2011 9:14
> To: Kernel Debugging Interest List
> Subject: Re: [windbg] Registers values throughout the stack
>
>
> xxxxx@gmail.com wrote:
>> I have a question that seems to be basic, because it is one of the first
>> issues the WinDbg user run into,
>
> Well, only if you’re on x64…
>
>> Is there a way to view the registers values throughout the stack, at he
>> time each function through the stack is called? I suppose that I can
>> disassemble each function, see where the old registers values are pushed
>> in the stack and trace them, but it is a real pain, and I’m wondering if
>> there is a normal way to do that.
>
> In the Windows x64 calling convention, the calling function must make
> room on the stack for all of the parameters, as if they were going to be
> pushed. Even though the first four are always passed in registers (rcx,
> rdx, r8, r9), the caller has to allocate stack space for them, and he
> must make room for at least 4, even if there are no parameters. Then,
> when the called function needs to use those registers, he automatically
> has a place to store the original values.
>
> The net result is that, in many cases, the parameters ARE visible on the
> stack, because the called function put them there. That often won’t be
> true for the final function, but farther down the stack you can often
> get lucky.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> WINDBG is sponsored by OSR
>
> 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
>
>
> —
> WINDBG is sponsored by OSR
>
> 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