Is this a bug from function kernel_int?
Victor Kamensky
kamensky@cisco.com
Tue Jan 22 08:59:00 GMT 2019
On Mon, 21 Jan 2019, David Smith wrote:
> On Sun, Jan 20, 2019 at 3:49 AM Yue Cao <yuecao1990@gmail.com> wrote:
>>
>> Hi there,
>>
>> Recently I find systemtap generates a wrong result when I use kernel_int to
>> print out the int value from the pointer. In my case, systemtap prints out
>> a huge value (18446744072649393666) with kernel_int. As you can see, this
>> value is larger than 2^32 (the maximal value for int). However, when I use
>> kernel_long, the result is within 2^32. The new value (3234809346) actually
>> is equal to what I expected by using kernel_int. I have tried multiple
>> times and the results are same. I wonder is it a bug. Could anyone tell me
>> how to fix it?
>
> You are confusing an 'int' with a 32-bit value. Depending on the
> architecture, they aren't the same. Typically on a 64-bit platform,
> the C language type 'int' is a 64-bit value. Typically on a 32-bit
> platform, the C language type 'int' is a 32-bit value.
David, above does not seem to be true wrt in in C language on today's
64bit Linux systems. Nowdays,
in C language LP64 64-Bit Programming Models: 'int' type is always
32bit value. And its size does not change between 32bit and 64bit
address spaces. The only type that typically changes size in LP64
memory model that Linux uses is long.
Here is simple example
[kamensky@kamensky-w541 tmp]$ cat intsize.c
#include <stdio.h>
int main (void)
{
printf("sizeof(char) = %d\n", sizeof(char));
printf("sizeof(short) = %d\n", sizeof(short));
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(long) = %d\n", sizeof(long));
printf("sizeof(long long) = %d\n", sizeof(long long));
return 0;
}
[kamensky@kamensky-w541 tmp]$ gcc -o intsize intsize.c
[kamensky@kamensky-w541 tmp]$ file intsize
intsize: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=1f8b0f11c6206829ba7dab12f51700b98e350d1c, not stripped
[kamensky@kamensky-w541 tmp]$ ./intsize
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
[kamensky@kamensky-w541 tmp]$ gcc -m32 -o intsize intsize.c
[kamensky@kamensky-w541 tmp]$ file intsize
intsize: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=16a7ff56fc7828a30d63ddccc5a72e91310ddaac, not stripped
[kamensky@kamensky-w541 tmp]$ ./intsize
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 4
sizeof(long long) = 8
You can try to run on any reasonable CPU archs it will come out like
above on all of them, with only size difference of long.
Note in LLP64 (or P64) model long size stays as 4 bytes, I believe this
is model that Windows uses for its 64bit apps.
You can define semantics of kernel_int as you wish, but I agree with
Yue's opinion, current one does defy normal expectaion of well
accepted LP64 model.
Please look at this:
http://www.unix.org/version2/whatsnew/lp64_wp.html
The model that David alluded is ILP64 and actually never used
except very few esoteric, old cases.
Thanks,
Victor
> If you are sure you want a 32-bit value, you can call the __int32()
> function on a value. (Although note that the '__' prefix means that is
> really an internal function by convention.)
>
> So, depending on your architecture, kernel_int() returning a 64-bit
> value could be a bug or could be the expected behavior.
>
> --
> David Smith
> Associate Manager
> Red Hat
>
More information about the Systemtap
mailing list