Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

poi command error?

633 views
Skip to first unread message

George

unread,
Oct 5, 2008, 8:08:02 AM10/5/08
to
Hello everyone,


I have made some experiment about poi command. But

always met with syntax error, here is my source code, and

related commands in WinDbg. My purpose is to deference

the memory which is holds by variable b, so that the value

of variable is displayed. Any ideas?

[Code]
0:000> dv
b = 0x00000000`0012feb4
a = 200
0:000> poi (b)
^ pass count must be preceeded by whitespace error

in 'poi (b)'
0:000> poi (0x00000000`0012feb4)
^ pass count must be preceeded by whitespace error

in 'poi (0x00000000`0012feb4)'


#include <iostream>

using namespace std;

int main()
{
int a = 200;

int* b = &a;

return 0;
}
[/Code]


thanks in advance,
George

Kalle Olavi Niemitalo

unread,
Oct 5, 2008, 10:45:47 AM10/5/08
to
George <Geo...@discussions.microsoft.com> writes:

> 0:000> dv
> b = 0x00000000`0012feb4
> a = 200
> 0:000> poi (b)
> ^ pass count must be preceeded by whitespace error

poi is not itself a debugger command. It is an operator
recognized by the MASM expression evaluator of the debugger.
Try instead:

0:000> ? poi(b)
should display 0x00000000`0012feb4, which is the value of the
pointer. In MASM expressions, the name of a variable (b) means
the address of the variable. poi(b) then means the pointer value
at that address, i.e. the value of the variable.

0:000> ? dwo(poi(b))
should display 0n200, which is the DWORD i.e. 32-bit value to
which b points.

0:000> dd poi(b) l1
should also display the 0n200 value, and its address.

0:000> ?? *b
should also display the 0n200 value, now using a C++ expression
rather than a MASM expression.

George

unread,
Oct 6, 2008, 2:50:00 AM10/6/08
to
Thanks Kalle,


1.

I have tried but seems it does not work. I set a break point to line foo in
main and execute to this line, here is the output and the source codes. Any
ideas?

--------------------


0:000> dv
b = 0x00000000`0012feb4
a = 200

0:000> dd poi(b)
Memory access error at ')'


#include <iostream>

using namespace std;

int foo()
{
int b = 300;

return b;
}

int goo()
{
int a = 400;

return a;
}

int main()
{
int a = 200;

int* b = &a;

foo();

a = 400;

goo();

return 0;
}
--------------------

2.

I want to learn more about how to use MASM expression and C++ expression in
WinDbg, current help documentin WinDbg seems not quite readable with enough
samples, do you have any other documents/tutorials to make a reference? :-)


regards,
George

Marc Sherman

unread,
Oct 7, 2008, 10:03:35 AM10/7/08
to
What does `dd poi(0x00000000`0012feb4)` show?

"George" <Geo...@discussions.microsoft.com> wrote in message
news:AB357D37-0B97-4F77...@microsoft.com...

George

unread,
Oct 8, 2008, 2:32:01 AM10/8/08
to
Thanks Marc,

1.

> What does `dd poi(0x00000000`0012feb4)` show?

It will show correct result, 0xc8.

2.

I did experiment and then read WinDbg help carefully, then I find the
answer. But not 100% sure, could you review here please? :-)

A. For C++ expression, the value of the variable is its actual value, but
for MASM expression, the value is its address;
B. For expression dd @@C++(b), b is a pointer variable to variable a and
this command will display the address from value of b;
C. For expression dd poi (@@C++(b)), the process will be, dereference
pointer variable b and get the deference result, the result is 0xc8, the
using dd to display address from 0xc8, so wrong results with ? signs.

Is my understanding correct?

3.

My further confusion is, why dd poi(@@C++(b)) results in cccccccc`000000c8
other than 00000000`000000c8?


regards,
George

Marc Sherman

unread,
Oct 8, 2008, 9:29:32 AM10/8/08
to
> 2.
>
> I did experiment and then read WinDbg help carefully, then I find the
> answer. But not 100% sure, could you review here please? :-)
>
> A. For C++ expression, the value of the variable is its actual value, but
> for MASM expression, the value is its address;
> B. For expression dd @@C++(b), b is a pointer variable to variable a and
> this command will display the address from value of b;
> C. For expression dd poi (@@C++(b)), the process will be, dereference
> pointer variable b and get the deference result, the result is 0xc8, the
> using dd to display address from 0xc8, so wrong results with ? signs.
>
> Is my understanding correct?

I don't know. I know very little about C++ expressions in WinDbg, sorry.

>
> 3.
>
> My further confusion is, why dd poi(@@C++(b)) results in cccccccc`000000c8
> other than 00000000`000000c8?

Probably because `dd` shows 4 bytes only.
What does `dp poi(@@C++(b))` show?
How about `dq poi(@@C++(b))` ?

Marc


Kalle Olavi Niemitalo

unread,
Oct 8, 2008, 7:30:56 PM10/8/08
to
George <Geo...@discussions.microsoft.com> writes:

> 3.
>
> My further confusion is, why dd poi(@@C++(b)) results in cccccccc`000000c8
> other than 00000000`000000c8?

You defined:

int a = 200;
int* b = &a;

So the value of @@C++(b) is the address of a. Then,
poi(@@C++(b)) means read a pointer-sized value from the address
of a; in C++, you'd get the same effect with *((void**)&a).
In your system, pointers are 64-bit, but a itself is only 32-bit,
so when poi(@@C++(b)) reads 64 bits, it gets a as the low 32 bits
and some garbage from the stack as the high 32 bits. This
garbage is 0xcccccccc, resulting in the 0xcccccccc`000000c8
value. The compiler you use perhaps generates code that fills
all unused bytes in the stack with 0xcc. If you don't want the
garbage to be read, you could instead use dwo(@@C++(b)), which
reads only 32 bits and so need not go past the end of a.

George

unread,
Oct 9, 2008, 12:34:00 AM10/9/08
to
Hi Marc,


I have found the answer. Here is my analysis, could you review it please?

For command 0:000> dd poi(0x00000000`0012feb4)

Step1: deference address 0x00000000`0012feb4 to get its value, since I am
debugging in a x64 environment, the return value should be 8-byte, and not
4-byte.

Here is what I get from experiment.

0:000> dd (0x00000000`0012fea4)
00000000`0012fea4 000000c8 cccccccc cccccccc cccccccc
00000000`0012feb4 cccccccc 0012fea4 00000000 cccccccc
00000000`0012fec4 cccccccc cccccccc cccccccc 00000000
00000000`0012fed4 00000000 40001652 00000001 00000001
00000000`0012fee4 00000001 40006220 00000001 00000000
00000000`0012fef4 00000000 40002375 00000001 00000000
00000000`0012ff04 00000000 8ac27600 00000000 00000000
00000000`0012ff14 00000000 00130000 00000000 00000000

Step2:

To deferenence the address, for 4-byte, we should get value 000000c8, but
for 8-byte, we should get cccccccc`000000c8, which is 000000c8 plus its
consecutive 4 bytes. Since I am debugging in a x64 environment, the result
should be the 8 byte one for the 8-byte address space.

Step 3:

display address at cccccccc`000000c8 using dd command, and get,

cccccccc`000000c8 ???????? ???????? ???????? ????????
cccccccc`000000d8 ???????? ???????? ???????? ????????
cccccccc`000000e8 ???????? ???????? ???????? ????????
cccccccc`000000f8 ???????? ???????? ???????? ????????
cccccccc`00000108 ???????? ???????? ???????? ????????
cccccccc`00000118 ???????? ???????? ???????? ????????
cccccccc`00000128 ???????? ???????? ???????? ????????
cccccccc`00000138 ???????? ???????? ???????? ????????


regards,
George

George

unread,
Oct 9, 2008, 12:42:01 AM10/9/08
to
Thanks Kalle,


1.

> So the value of @@C++(b) is the address of a. Then,
> poi(@@C++(b)) means read a pointer-sized value from the address
> of a; in C++, you'd get the same effect with *((void**)&a).

Your reply is really excellent! Cool!

But I do not quite agree with your above statements for equivalent C++
expression.

My analysis is,

- b is the address of a, and we can say dereference a;
- poi means deference again;
- so the related C++ expression should be dereference a twice, not once, I
think the equivalent C++ expression should be, &(&a).

Any comments?

2.

Why you add void** in your expression?


regards,
George

Marc Sherman

unread,
Oct 9, 2008, 9:27:48 AM10/9/08
to
> For command 0:000> dd poi(0x00000000`0012feb4)
>
> Step1: deference address 0x00000000`0012feb4 to get its value, since I am
> debugging in a x64 environment, the return value should be 8-byte, and not
> 4-byte.

From the docs, it looks like `dd` will always display 4 bytes, regardless of
cpu bitness.

>
> Here is what I get from experiment.
>
> 0:000> dd (0x00000000`0012fea4)
> 00000000`0012fea4 000000c8 cccccccc cccccccc cccccccc
> 00000000`0012feb4 cccccccc 0012fea4 00000000 cccccccc
> 00000000`0012fec4 cccccccc cccccccc cccccccc 00000000
> 00000000`0012fed4 00000000 40001652 00000001 00000001
> 00000000`0012fee4 00000001 40006220 00000001 00000000
> 00000000`0012fef4 00000000 40002375 00000001 00000000
> 00000000`0012ff04 00000000 8ac27600 00000000 00000000
> 00000000`0012ff14 00000000 00130000 00000000 00000000

This is odd since the docs say if you don't specify a range (which you did
not), then it will default to 32 DWORDs but here I see 64.

What do you see with `dd (0x00000000`0012fea4) L1` ?

>
> Step2:
>
> To deferenence the address, for 4-byte, we should get value 000000c8, but
> for 8-byte, we should get cccccccc`000000c8, which is 000000c8 plus its
> consecutive 4 bytes. Since I am debugging in a x64 environment, the result
> should be the 8 byte one for the 8-byte address space.

Show some actual debugger output here.

>
> Step 3:
>
> display address at cccccccc`000000c8 using dd command, and get,
>
> cccccccc`000000c8 ???????? ???????? ???????? ????????
> cccccccc`000000d8 ???????? ???????? ???????? ????????
> cccccccc`000000e8 ???????? ???????? ???????? ????????
> cccccccc`000000f8 ???????? ???????? ???????? ????????
> cccccccc`00000108 ???????? ???????? ???????? ????????
> cccccccc`00000118 ???????? ???????? ???????? ????????
> cccccccc`00000128 ???????? ???????? ???????? ????????
> cccccccc`00000138 ???????? ???????? ???????? ????????

cccccccc`000000c8 is an invalid address, nothing's there, that's why you see
the question marks.

On a 32 bit system, any address below 64K is invalid. Not sure if it's
exactly the same for 64 bit systems.

Marc


George

unread,
Oct 10, 2008, 6:07:04 AM10/10/08
to
Thanks Marc,


1.

> From the docs, it looks like `dd` will always display 4 bytes, regardless of
> cpu bitness.

> This is odd since the docs say if you don't specify a range (which you did
> not), then it will default to 32 DWORDs but here I see 64.
>
> What do you see with `dd (0x00000000`0012fea4) L1` ?

I agree the document is not clear. But I think the content of memory is
correct. The most important should be the content, not format. :-)

Here are the output without and with L1. Any comments?

0:000> dd 0x00000000`0012fea4


00000000`0012fea4 000000c8 cccccccc cccccccc cccccccc
00000000`0012feb4 cccccccc 0012fea4 00000000 cccccccc
00000000`0012fec4 cccccccc cccccccc cccccccc 00000000
00000000`0012fed4 00000000 40001652 00000001 00000001
00000000`0012fee4 00000001 40006220 00000001 00000000
00000000`0012fef4 00000000 40002375 00000001 00000000
00000000`0012ff04 00000000 8ac27600 00000000 00000000
00000000`0012ff14 00000000 00130000 00000000 00000000

0:000> dd 0x00000000`0012fea4 L1
00000000`0012fea4 000000c8

2.

>
> Show some actual debugger output here.

2.

>> Show some actual debugger output here.

From command, we know the content of address 0x00000000`0012fea4, for 32-bit
is 0x000000c8, for 64-bit is 0xcccccccc 000000c8. Because int* is 64-bit on
x64, so its value becomes 0xcccccccc 000000c8. Is that clear now? And you
agree with my analysis?

0:000> dd 0x00000000`0012fea4


00000000`0012fea4 000000c8 cccccccc cccccccc cccccccc
00000000`0012feb4 cccccccc 0012fea4 00000000 cccccccc
00000000`0012fec4 cccccccc cccccccc cccccccc 00000000
00000000`0012fed4 00000000 40001652 00000001 00000001
00000000`0012fee4 00000001 40006220 00000001 00000000
00000000`0012fef4 00000000 40002375 00000001 00000000
00000000`0012ff04 00000000 8ac27600 00000000 00000000
00000000`0012ff14 00000000 00130000 00000000 00000000

3.

> cccccccc`000000c8 is an invalid address, nothing's there, that's why you see
> the question marks.
>
> On a 32 bit system, any address below 64K is invalid. Not sure if it's
> exactly the same for 64 bit systems.

cccccccc`000000c8 is not below 64K?


regards,
George

Marc Sherman

unread,
Oct 10, 2008, 10:08:32 AM10/10/08
to
"George" <Geo...@discussions.microsoft.com> wrote in message
news:E47651DB-6023-4FF1...@microsoft.com...

> Thanks Marc,
>
>
> 1.
>
>> From the docs, it looks like `dd` will always display 4 bytes, regardless
>> of
>> cpu bitness.
>> This is odd since the docs say if you don't specify a range (which you
>> did
>> not), then it will default to 32 DWORDs but here I see 64.
>>
>> What do you see with `dd (0x00000000`0012fea4) L1` ?
>
> I agree the document is not clear. But I think the content of memory is
> correct. The most important should be the content, not format. :-)
>
> Here are the output without and with L1. Any comments?
>
> 0:000> dd 0x00000000`0012fea4
> 00000000`0012fea4 000000c8 cccccccc cccccccc cccccccc
> 00000000`0012feb4 cccccccc 0012fea4 00000000 cccccccc
> 00000000`0012fec4 cccccccc cccccccc cccccccc 00000000
> 00000000`0012fed4 00000000 40001652 00000001 00000001
> 00000000`0012fee4 00000001 40006220 00000001 00000000
> 00000000`0012fef4 00000000 40002375 00000001 00000000
> 00000000`0012ff04 00000000 8ac27600 00000000 00000000
> 00000000`0012ff14 00000000 00130000 00000000 00000000

I need more caffeine. This is 32 DWORDs, just like the docs say.

> 0:000> dd 0x00000000`0012fea4 L1
> 00000000`0012fea4 000000c8

And this shows that `dd` always displays 4 bytes, no matter cpu bitness.

>
> 2.
>
>>
>> Show some actual debugger output here.
>
> 2.
>
>>> Show some actual debugger output here.
>
> From command, we know the content of address 0x00000000`0012fea4, for
> 32-bit
> is 0x000000c8, for 64-bit is 0xcccccccc 000000c8. Because int* is 64-bit
> on
> x64, so its value becomes 0xcccccccc 000000c8. Is that clear now? And you
> agree with my analysis?

I don't think `dd` cares if there's a 64 bit pointer at 00000000`0012fea4,
because it will only show 4 bytes if you specify L1 (which means show me one
object).

Since you know that there's a 64 bit pointer at 00000000`0012fea4, you
should use `dp` or `dq`, not `dd`.

>> cccccccc`000000c8 is an invalid address, nothing's there, that's why you
>> see
>> the question marks.
>>
>> On a 32 bit system, any address below 64K is invalid. Not sure if it's
>> exactly the same for 64 bit systems.
>
> cccccccc`000000c8 is not below 64K?

Again, I need more caffeine. I got fixated on 0xc8. Anyway, windbg shows
question marks for invalid addresses. I'm not sure if cccccccc`000000c8 is a
kernel mode address. If it is, then that's why you see the question marks.
If it's a "possible" user mode address, then there's nothing allocated
there.

Marc


0 new messages