Re: ref parameter

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Jun 6, 1:45 pm, "Peter Duniho" <NpOeStPe...@xxxxxxxxxxxxxxxx>
wrote:
On Fri, 06 Jun 2008 10:09:32 -0700, parez <psaw...@xxxxxxxxx> wrote:
[...]
When you did it the wrong way, you passed it the address of the byte
on the stack. Now, I'm going to *guess* that the stack looked
something like:

[value of TagType]
[value of SerialNo]
[address of param]

(because param is passed in by reference)

The DLL then merrily writes over SerialNo *and then part of 'address
of param'*. Not a problem so far, but...

Why would the dll overwrite the address of param? Just curious..

Let's make sure we understand what is meant by "param" first. :)
Technically, "param" is the local argument to the method. The "address"
of that is simply an offset relative to the current stack frame. But I
don't think that's what's meant in the text quoted.

Rather, in that context, "param" refers to the original parameter, which
is passed as an address stored in a location that is referenced as an
offset relative to the current stack frame. Here, the phrase "address of
param" refers not to the actual address of the local argument relative to
the current stack frame, but rather to the value stored in that location,
the address of the original parameter..

Confused yet? :)

What happens is that when the DLL is called, the OP incorrectly passed the
address of a single byte of storage, rather than an array of bytes of
storage. Furthermore, that single byte was stored on the stack as a local
variable, rather than in the heap. So, when the called function went to
write data to what it thought was an array of bytes, it was actually
writing to that local variable.

But the address of the original parameter passed as "param" was stored in
the stack just past that local variable. Since the local variable didn't
use enough of the stack to accomodate all of the data that the called
function tried to write to it, the address of "param" winds up getting
overwritten as well.

Ironically, the code could have failed in much more spectacular ways. The
OP is fortunate to have had such a clearly incorrect result, but one which
was still testable. :)

Pete

(Bonus reading: of course, the "single byte" variable actually takes up
more room on the stack than just the one byte. I haven't checked, but
probably it's consuming a full 4 bytes, due to alignment requirements.
But that's still not enough for the called function, which apparently was
expecting 7 bytes [why 7? I don't know...that's a weird size for a
buffer]. So three more bytes get written into the "address of param"
storage...just one byte would have been enough to cause the later
assignment to fail, and so it does).

That makes sense. I thought the original problem was somthing else.

v=0
Test(ref v)
// v = 2, as expected

Test2(ref v)
// v = 1. There is no exception thrown

that makes sense.. I thought it was uninitialised ref variable vs
initialised ref. Silly of me. that shouldnt compile..
.



Relevant Pages

  • Re: ref parameter
    ... I'm going to *guess* that the stack looked ... (because param is passed in by reference) ... The DLL then merrily writes over SerialNo *and then part of 'address ... Rather, in that context, "param" refers to the original parameter, which is passed as an address stored in a location that is referenced as an offset relative to the current stack frame. ...
    (microsoft.public.dotnet.languages.csharp)
  • Strange hang with Dns.GetHostEntry
    ... is tough to debug. ... The stack looks correct. ... The param is only ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: [Clax86list] Noob Question
    ... The trick is that the C calling conventions have changed. ... ; rcx; 4th param for C call ... Are they put on the stack? ...
    (comp.lang.asm.x86)
  • Re: [Clax86list] Noob Question
    ... ; rcx; 4th param for C call ... Are they put on the stack? ...
    (comp.lang.asm.x86)
  • Re: PEP thought experiment: Unix style exec for function/method calls
    ... frame or /replacing/ the current stack frame with the new one. ... differentiate what I mean by a unix style exec from python. ... This transfers execution to the function that would normally be called ...
    (comp.lang.python)