This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Is this a bug from function kernel_int?
- From: Victor Kamensky <kamensky at cisco dot com>
- To: David Smith <dsmith at redhat dot com>
- Cc: Yue Cao <yuecao1990 at gmail dot com>, systemtap <systemtap at sourceware dot org>
- Date: Tue, 22 Jan 2019 00:59:51 -0800 (PST)
- Subject: Re: Is this a bug from function kernel_int?
- References: <CAKwrreJ8rLhRxktXs65EOpvuZ6DZ4TVW4qmYjMHyukcf-ksjGA@mail.gmail.com> <CAKFOr-Yhfe20J-xFQiDParCHuSwiF=p3cUaB8NJFExDHWotb6Q@mail.gmail.com>
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