I realize what InterlockedCompareExchange does, thats why i used it here. My eventual
goal is to create a platform independent InterlockedPopSList as i need the program to
run on Windows 2000, and that function is available only on XP+.
Ive stepped through it with WinDBG and the failure *looks* like it is occuring between
pTop=pList->pFirst and pNext=pTop->next;
I have windbg open with locals showing and everything, i click the + next to pList
and click the + next to pFirst and i see the *value* of pFirst. however the statement
it access violations at, pNext=pTop->next pTop now has some *bizarre* value. whereas before
it went through the if statement, it had the *correct* value.
im rather sure the issue doesnt involve any sort of side effect of InterlockedComp.Exg.
If anyone can come up with a better implementation of InterlockedPopSList, id be glad to take
it though 
asa
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Alberto Moreira
Sent: Monday, May 02, 2005 9:29 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Stack-based memory corruption
Note that one of the effect of cmpxchg8b is to leave edx:eax
loaded with the old value of dest. I didn’t disassemble the
function, but I imagine that it’s basically a wrapper around
cmpxchg8b, so, I expect it to always return the old dest; hence
the problem.
Assuming that, let me look at the code again. Assume you have a
list with two items, I’ll call them I1 and I2. Let pFirst point
to I1.
Here’s the code:
do
{
pTop=pList->pFirst;
if (pTop==NULL)
return NULL;
pNext=pTop->next;
} while (InterlockedCompareExchangePointer((PVOID *)
&(pList->pFirst), pNext, pTop) != pTop);
Now, this is what could be happening:
do {
pTop = I1
pNext = I1.next = I2
}
pFirst = I1, pTop = I1, pFirst==pTop, pFirst = pNext = I2, I2
!= pTop, so,
do {
pTop = I2
pNext = I2.next = NULL
}
pFirst = I2, pTop = I2, pFirst==pTop, pFirst = pNext = NULL,
NULL != pTop, so,
do {
pTop = NULL
pNext = NULL.next =====> CRASH, BANG!
I did it a bit too fast, so, I may be wrong, but a quick step
through with a debugger will clear it up.
Alberto.
----- Original Message -----
From: “Loren Wilton”
To: “Windows System Software Devs Interest List”
Sent: Sunday, May 01, 2005 9:26 PM
Subject: Re: [ntdev] Stack-based memory corruption
> I’m feeling a little too foggy to analyze the code here, but
> my feeling is
> that if is the CMPXCHG8B that is doing it to you. The way
> this op words
> (ignoring the locking for simplicity) is:
>
> IF (EDX:EAX = DEST)
> ZF <- 1
> DESC <- ECX:EBX
> ELSE
> ZF <- 0
> EDX:EAX <- DEST
>
> Note that this basically says “if the comparand equals the
> destination, set
> the result to the destination. Otherwise set the comparand to
> the
> destination.”
>
> The manual says InterlockedCompareExchangePointer is
> implemented by inline
> code, which would be this op, and maybe a couple others.
>
> Now, what InterlockedCompareExchangePointer says it returns is
> “the pointer
> value pointed to by Destination”. But is this the value
> BEFORE the
> exchange, or the value AFTER the exchange? The documentation
> leaves that to
> your imagination. From the operation of cmpxchg8b, what has
> to be happening
> is this op is returning the Comparand field, which will be
> overloaded with
> the original source value if it was different (in which case
> the exchange
> store WILL NOT happen).
>
> So what this routine must be doing is:
>
> PVOID
> InterlockedCompareExchangePointer(
> IN OUT PVOID *Destination,
> IN PVOID Exchange,
> IN PVOID Comparand
> )
> {
> if (Comparand == *Destination)
> *Destination = Exchange;
> else
> Comparand = *Destination;
> return Comparand;
> }
>
> This makes your overall loop:
>
> do
> {
> pTop=pList->pFirst;
> if (pTop==NULL)
> return NULL;
> pNext=pTop->next;
> } while
> (
> //InterlockedCompareExchangePointer(
> //(PVOID *) &(pList->pFirst), pNext, pTop) != pTop);
>
> if (&(pList->pFirst) == pTop)
> {
> &(pList->pFirst) = pNext;
> return pTop;
> }
> else
> return &(pList->pFirst);
> }
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@ieee.org
> To unsubscribe send a blank email to
> xxxxx@lists.osr.com
—
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@rivin.net
To unsubscribe send a blank email to xxxxx@lists.osr.com