Subject: Re: Problem with libgtop2
To: Julio M. Merino Vidal <jmmv@menta.net>
From: George Peter Staplin <GeorgePS@XMission.com>
List: tech-userlevel
Date: 04/12/2004 09:53:26
On Mon, 12 Apr 2004, Julio M. Merino Vidal wrote:

> Hi all,

Hi,
 
> [ posting to -userlevel because this is not exactly a packages question ]
> 
> I've found a problem in libgtop2, where it doesn't pass parameters correctly
> between some functions.  Consider the following test case (which, aside from
> the 'buf' thing does the same as libgtop2):
> 
> #include <sys/types.h>
> #include <stdio.h>
> 
> void foo(void *ptr)
> {
>     int64_t *params = (int64_t *)ptr;
>     printf("arg1: %d\n", params[0]);
>     printf("arg2: %d\n", params[1]);
> }
> 
> void func(int64_t a, int64_t b)
> {
>     int64_t buf[2];
> 
>     foo((void *)&a); /* This is what libgtop does */
> 
>     buf[0] = a;
>     buf[1] = b;
>     foo((void *)&buf);
> }

We had a and b on the stack from the call to func.

foo((void *)&a) essentially causes a push of &a, then we would just have
&a alone.  The second value (params[1]) in foo would be undefined behavior
as I understand it.

The case of foo((void *)&buf) is different, because it's actually filling 
the stack before the call to foo with data from a and b.
 
> int main(void) {
>     func((int64_t) 10, (int64_t) 20);
>     return 0;
> }

First main pushes the constant 0, because the particular processor I'm
using has a 4 byte word that isn't large enough to fit 8 bytes for the
int64_t.  Then the lower values which are $20 and $10.

 pushl $0
 pushl $20
 pushl $0
 pushl $10
 call func


> 
> Which outputs:
> 
> arg1: 10
> arg2: 1208273232

This could be a return address, or junk leftover on the stack.

> arg1: 10
> arg2: 20
> 
> Note the second line, which shows an incorrect value, just like libgtop2.

It seems like a bug in libgtop2.
 
> Using 'long' instead of int64_t, works.  This same program works properly
> under linux.
> 
> What's happening here?  I can't figure it out :(

You're just getting lucky.  The compiler happens to have the value for
arg2/b on the stack leftover from the call to func when it works.  The
compiler is free to clobber it.
 
> Thanks.

You're welcome.

George