Input parameters and local variables use same address??

Hi all,
When I use windbg window Locals to see the parameters and the local variables of the function I see these:

Name Value Type Location
pStruct1 0x00000000 struct _STRUCT1 * struct _STRUCT1 b9df0c64
Number1 0x15 unsigned long b9df0c68
Number2 0 int b9df0c6c
pDeviceObject 0x00000000 struct _DEVICE_OBJECT * struct _DEVICE_OBJECT * b9df0c70
ppStruct2 0x89982150 struct _STRUCT2 ** b9df0c74

Return 0 int b9df0c64
Number3 0x1000 unsigned long b9df0c58
pStruct1,Number1,Number2,pDeviceObject and ppStruct2 is the Input Output parameters of the function, Return,Number3 is the local variable in the function. But Return and pStruct1 are useing same memory location so when I modified the return value the Input parameter is changed too, so when I exit this function and use pStruct1 again, the system crashed.
Why it performs like this and why this happens?

Thanks & regards!

Post the code as well. Is this a chk or fre build? Is it no_opt? if optimizations are on, the compiler can reuse stack locations at its own whim, but it should never cause this type of error that you describe. The code should make things a little more clear.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@huaweisymantec.com
Sent: Wednesday, June 03, 2009 11:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Input parameters and local variables use same address??

Hi all,
When I use windbg window Locals to see the parameters and the local variables of the function I see these:

Name Value Type Location
pStruct1 0x00000000 struct _STRUCT1 * struct _STRUCT1 b9df0c64
Number1 0x15 unsigned long b9df0c68
Number2 0 int b9df0c6c
pDeviceObject 0x00000000 struct _DEVICE_OBJECT * struct _DEVICE_OBJECT * b9df0c70
ppStruct2 0x89982150 struct _STRUCT2 ** b9df0c74

Return 0 int b9df0c64
Number3 0x1000 unsigned long b9df0c58
pStruct1,Number1,Number2,pDeviceObject and ppStruct2 is the Input Output parameters of the function, Return,Number3 is the local variable in the function. But Return and pStruct1 are useing same memory location so when I modified the return value the Input parameter is changed too, so when I exit this function and use pStruct1 again, the system crashed.
Why it performs like this and why this happens?

Thanks & regards!


NTDEV 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

It’s a fre build. And I didn’t add no_opt in my code, so may it be the default option? How can I checkout it? Here is part of my code, is it enough to diagnose?

ISSP_INT32 BITMAP_TestBits(IN BITMAP_BITMAPINFO_STRU *pstrBitMap,
IN ISSP_ULONG ulStartingIndex,
IN ISSP_ULONG ulNumberToTest,
IN OUT ISSP_BOOLEAN *pblModle,
IN ISSP_BOOL bIsBitMapDisk,
IN DEVICE_OBJECT *pstrDeviceObject)
{
ISSP_ULONG ulOffset;
ISSP_ULONG ulLcNumber;
struct lc_element *pstrLcElement;
BITMAP_BMLC_ELEMENT *pstrBMLcElement;
ISSP_ULONG ulBMPageSize = BITMAP_GetBMPageSize (pstrBitMap);
RTL_BITMAP strBitMapHeader;
ISSP_INT32 lRet;

DG_ASSERT(pstrBitMap);
DG_ASSERT(pblModle);

(ISSP_VOID)BITMAP_GetPageOffset(ulStartingIndex, ulBMPageSize, &ulOffset);

ulLcNumber = ulStartingIndex / BYTES_TO_BITS(ulBMPageSize);

if (pstrBitMap->pstrHotAreaMd->bIsBitMapDisk)
{
KIRQL OldIrql;

DG_KeAcquireSpinLock(&DG_gstrList.strLock, &OldIrql);

if (FLUSHING == DG_gstrList.ulFlag)
{
lRet = INTF_BITMAP_InsertPageInfo(ulLcNumber, &DG_gstrList);

if (lRet != DG_BITMAP_STATUS_SUCCESS)
{
INTF_UTIL_DbgPrint(DG_DBG_MAJOR,
“BMP:%s Line%d ERRNO%d! \r\n”,
FUNCTION,
LINE,
lRet);

INTF_UTIL_WriteLogsToFilesEx(DG_DBG_MAJOR,
“BMP:%s Line%d ERRNO%d! \r\n”,
FUNCTION,
LINE,
lRet);

DG_KeReleaseSpinLock(&DG_gstrList.strLock,OldIrql);

return DG_BITMAP_STATUS_ERROR;
}
}

DG_KeReleaseSpinLock(&DG_gstrList.strLock,OldIrql);
}

lRet = BITMAP_GetLcElement(pstrBitMap,
ulLcNumber,
bIsBitMapDisk,
pstrDeviceObject,
&pstrLcElement);



}

It crashed in BITMAP_GetLcElement. And the parameters and local variables are like before.

Thanks.

A fre build is optimized by default. I suggest you start debugging instruction by instruction in windbg and track where the compiler is enregistering/storing your locals and passed in parameters. If it is dying in BITMAP_GetLcElement, start debugging there

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@huaweisymantec.com
Sent: Wednesday, June 03, 2009 11:54 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Input parameters and local variables use same address??

It’s a fre build. And I didn’t add no_opt in my code, so may it be the default option? How can I checkout it? Here is part of my code, is it enough to diagnose?

ISSP_INT32 BITMAP_TestBits(IN BITMAP_BITMAPINFO_STRU *pstrBitMap,
IN ISSP_ULONG ulStartingIndex,
IN ISSP_ULONG ulNumberToTest,
IN OUT ISSP_BOOLEAN *pblModle,
IN ISSP_BOOL bIsBitMapDisk,
IN DEVICE_OBJECT *pstrDeviceObject)
{
ISSP_ULONG ulOffset;
ISSP_ULONG ulLcNumber;
struct lc_element *pstrLcElement;
BITMAP_BMLC_ELEMENT *pstrBMLcElement;
ISSP_ULONG ulBMPageSize = BITMAP_GetBMPageSize (pstrBitMap);
RTL_BITMAP strBitMapHeader;
ISSP_INT32 lRet;

DG_ASSERT(pstrBitMap);
DG_ASSERT(pblModle);

(ISSP_VOID)BITMAP_GetPageOffset(ulStartingIndex, ulBMPageSize, &ulOffset);

ulLcNumber = ulStartingIndex / BYTES_TO_BITS(ulBMPageSize);

if (pstrBitMap->pstrHotAreaMd->bIsBitMapDisk)
{
KIRQL OldIrql;

DG_KeAcquireSpinLock(&DG_gstrList.strLock, &OldIrql);

if (FLUSHING == DG_gstrList.ulFlag)
{
lRet = INTF_BITMAP_InsertPageInfo(ulLcNumber, &DG_gstrList);

if (lRet != DG_BITMAP_STATUS_SUCCESS)
{
INTF_UTIL_DbgPrint(DG_DBG_MAJOR,
“BMP:%s Line%d ERRNO%d! \r\n”,
FUNCTION,
LINE,
lRet);

INTF_UTIL_WriteLogsToFilesEx(DG_DBG_MAJOR,
“BMP:%s Line%d ERRNO%d! \r\n”,
FUNCTION,
LINE,
lRet);

DG_KeReleaseSpinLock(&DG_gstrList.strLock,OldIrql);

return DG_BITMAP_STATUS_ERROR;
}
}

DG_KeReleaseSpinLock(&DG_gstrList.strLock,OldIrql);
}

lRet = BITMAP_GetLcElement(pstrBitMap,
ulLcNumber,
bIsBitMapDisk,
pstrDeviceObject,
&pstrLcElement);



}

It crashed in BITMAP_GetLcElement. And the parameters and local variables are like before.

Thanks.


NTDEV 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

That function is called in loops and called many times, and it crashed unexpectable, so it’s a little hard to debug.

Should not the Locals be like this:
Name Value Type Location
pStruct1 0x00000000 struct _STRUCT1 * struct _STRUCT1 b9df0c64
Number1 0x15 unsigned long b9df0c68
Number2 0 int b9df0c6c
pDeviceObject 0x00000000 struct _DEVICE_OBJECT * struct _DEVICE_OBJECT
* b9df0c70
ppStruct2 0x89982150 struct _STRUCT2 ** b9df0c74

Return 0 int b9df0c60
Number3 0x1000 unsigned long b9df0c5c

?and in BITMAP_GetLcElement there are three local parameters, why there are
only two of them. The missing one is declared after Return and before Number3
, so system should already allocate some memory for local parameter2.

I use windbg debugged the driver. And it did the optimize in faith. And when the address is conflict, the Input parameters is not modified wrongly. So is it so abnormity caused this crash, and how can I close this optimize??
Thanks.

> Why it performs like this and why this happens?

Compiler optimization. Use the checked build with /Od if you want better picture.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Or just add no_opt to the build window’s shortcut or however you use the wdk build env

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: Maxim S. Shatskih
Sent: Thursday, June 04, 2009 5:26 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Input parameters and local variables use same address??

> Why it performs like this and why this happens?

Compiler optimization. Use the checked build with /Od if you want better picture.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com


NTDEV 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

xxxxx@huaweisymantec.com wrote:

Hi all,
When I use windbg window Locals to see the parameters and the local variables of the function I see these:

Name Value Type Location
pStruct1 0x00000000 struct _STRUCT1 * struct _STRUCT1 b9df0c64
Number1 0x15 unsigned long b9df0c68
Number2 0 int b9df0c6c
pDeviceObject 0x00000000 struct _DEVICE_OBJECT * struct _DEVICE_OBJECT * b9df0c70
ppStruct2 0x89982150 struct _STRUCT2 ** b9df0c74

Return 0 int b9df0c64
Number3 0x1000 unsigned long b9df0c58
pStruct1,Number1,Number2,pDeviceObject and ppStruct2 is the Input Output parameters of the function, Return,Number3 is the local variable in the function. But Return and pStruct1 are useing same memory location…

No, they don’t. The return value does not actually use a “memory
location”. The return value is returned in the register eax. The
debugger doesn’t know how to tell you that, so it “makes up” a number.

Look, you seem to believe that everything the debugger tells you is
absolutely 100% true. That is NOT THE CASE, especially in an optimized
build. The debugger has to guess about how things are laid out, based
on hints from the compiler and its own smarts, but sometimes it guesses
wrong. You HAVE to use your own brain and your own knowledge of how the
compiler creates code.

o when I modified the return value the Input parameter is changed too, so when I exit this function and use pStruct1 again, the system crashed.

No, your analysis is faulty. The return value will not affect anything
else.


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

Yes, I know now, thanks all.

And now the dump turns to be like this:
0: kd> .cxr 0xffffffffbace2838
eax=00000000 ebx=00000000 ecx=8082196c edx=da7b0002 esi=000493b8 edi=00000000
eip=0000000d esp=bace2c04 ebp=00000000 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
0000000d ?? ???
0: kd> kp
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
bace2c00 bad1cb8e 0xd
bace2c0c bad2126e Xxx!FunctionC
bace2c3c bad21b04 Xxx!FunctionB
bace2c84 bad2248e Xxx!FunctionA
So I plaster bad21b04 in the Disassamble window:
bad21afe 52 push edx
bad21aff e81cf5ffff call Xxx!FunctionB(bad21020)
bad21b04 8945e8 mov dword ptr [ebp-18h],eax
bad21b07 837de800 cmp dword ptr [ebp-18h],0
bad21b0b 7458 je Xxx!FunctionA(bad21b65)

Then bad2126e:
bad21268 52 push edx
bad21269 e8a2b7ffff call Xxx!FunctionC (bad1ca10)
bad2126e 8b4518 mov eax,dword ptr [ebp+18h]
bad21271 8b08 mov ecx,dword ptr [eax]

But when I plaster bad1cb8e in the Disassamble window:


bad1cb88 ff1504e0d4ba call dword ptr [Xxx!_imp_KfReleaseSpinLock (bad4e004)]
bad1cb8e 8be5 mov esp,ebp
bad1cb90 5d pop ebp
bad1cb91 c20800 ret 8
bad1cb94 cc int 3

Is bad1cb8e FunctionC complete and exit?
I plaster bad1cb8e in the memory window:
bad1cb8e 8b e5 5d c2 08 00 cc cc cc cc cc cc cc cc cc cc cc cc
it is the value of mov esp,ebp pop ebp ret 8 int 3 … but the value in eip is 0000000d. It seems the 0000000d is not right and caused the crash. Why?

Thanks!

Hardware error?

xxxxx@huaweisymantec.com wrote:

And now the dump turns to be like this:
0: kd> .cxr 0xffffffffbace2838
eax=00000000 ebx=00000000 ecx=8082196c edx=da7b0002 esi=000493b8 edi=00000000
eip=0000000d esp=bace2c04 ebp=00000000 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
0000000d ?? ???
0: kd> kp
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
bace2c00 bad1cb8e 0xd
bace2c0c bad2126e Xxx!FunctionC
bace2c3c bad21b04 Xxx!FunctionB
bace2c84 bad2248e Xxx!FunctionA

But when I plaster bad1cb8e in the Disassamble window:

bad1cb88 ff1504e0d4ba call dword ptr [Xxx!_imp_KfReleaseSpinLock (bad4e004)]
bad1cb8e 8be5 mov esp,ebp
bad1cb90 5d pop ebp
bad1cb91 c20800 ret 8
bad1cb94 cc int 3

This can happen in several ways. If someone has trashed the stack (by
overwriting, or by not matching pushes and pops), then the “ret”
instruction can pop the wrong address off. Or, if there is an indirect
call or jmp through an address or a register, that can get the wrong
address.

However, there are other possibilities. The function being run is
KeReleaseSpinLock. That reduces the IRQL. If you had queued up a DPC
while you held the spin lock, that DPC will be higher priority than your
plain old driver thread, in which case it will need to be run right
now. If you queue up a DPC with a bogus function pointer, that causes a
jump to outer space like this.


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