LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to find if an OS is 32 bit or 64 bit using a program ? (https://www.linuxquestions.org/questions/programming-9/how-to-find-if-an-os-is-32-bit-or-64-bit-using-a-program-706201/)

lali.p 02-20-2009 09:57 AM

How to find if an OS is 32 bit or 64 bit using a program ?
 
Well my answer is that for a 64 bit OS, the pointer size should be 8 byte and for a 32 bit OS pointer size should be 4 byte ?

So checking the sizeof(void*) should be good enough. But is there any other way ?

Sorry for the question, but i just wanted to know if there was any other way to find the answer to this question programmatically.


Regards
lali

Hko 02-20-2009 10:26 AM

It is possible to get a string describing the processor type. I suppose it is possible to deduct 32-bit or 64-bit from there.

This code prints "i686" on my PC with a Intel 32-bits CPU.
Code:

#include <stdio.h>
#include <sys/utsname.h>

int main()
{
    struct utsname kernel_info;
    if (uname(&kernel_info) < 0) {
        perror("Error reading kernel info");
        return 1;
    }
    puts(kernel_info.machine);
    return 0;
}


johnsfine 02-20-2009 10:52 AM

Quote:

Originally Posted by lali.p (Post 3451163)
Well my answer is that for a 64 bit OS, the pointer size should be 8 byte and for a 32 bit OS pointer size should be 4 byte ?

No. That is testing whether the program itself was compiled 32 bit or 64 bit. That doesn't tell you whether the OS is 32 bit or 64 bit.

In the x86 world, you can compile and run 32 bit programs under a 64 bit OS. Also, nothing in Linux itself says you can't compile and run 64 bit programs under a 32 bit OS. The x86_64 architecture won't let you do that and I don't know of any Linux ports to architectures that let you do that. But if the architecture let you, Linux probably would let you.

Quote:

So checking the sizeof(void*) should be good enough. But is there any other way ?
There are ways for a human to do it that don't seem to require a human level of intelligence. For the basic mechanics (as opposed to the intelligence) of doing almost anything in Linux, if a human can do it then a program could as well.

Hko already gave you a more concrete version of that answer (a human might run uname and look at the result).

wje_lq 02-20-2009 02:36 PM

Would someone with a 64-bit system please compile this program for 32 bit pointers, run it on that 64-bit system, and post the output? If it says 64 bits, then there's your magic bullet.
Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
  char  buffer[1024];

  FILE *phyle;

  phyle=fopen("/proc/self/maps","r");

  if(!fgets(buffer,sizeof(buffer),phyle))
  {
    abort();
  }

  printf("bits per pointer is %d\n",2*(strchr(buffer,' ')-buffer-1));

  return 0;

} /* main() */


johnsfine 02-20-2009 03:09 PM

I'm too lazy to try it, but why should it work? Even for a 64-bit application the length of addresses in /proc/self/maps isn't consistent
Code:

cat /proc/self/maps
00400000-00405000 r-xp 00000000 08:05 22036532                          /bin/cat
00504000-00505000 rw-p 00004000 08:05 22036532                          /bin/cat
00505000-00526000 rwxp 00505000 00:00 0
2a95556000-2a95557000 rw-p 2a95556000 00:00 0
2a9557f000-2a95581000 rw-p 2a9557f000 00:00 0
2a95581000-2a983c4000 r--p 00000000 08:05 786549                        /usr/lib/locale/locale-archive
342c000000-342c015000 r-xp 00000000 08:05 33980418                      /lib64/ld-2.3.4.so
342c114000-342c115000 r--p 00014000 08:05 33980418                      /lib64/ld-2.3.4.so
342c115000-342c116000 rw-p 00015000 08:05 33980418                      /lib64/ld-2.3.4.so
342c200000-342c32f000 r-xp 00000000 08:05 33980421                      /lib64/tls/libc-2.3.4.so
342c32f000-342c42f000 ---p 0012f000 08:05 33980421                      /lib64/tls/libc-2.3.4.so
342c42f000-342c432000 r--p 0012f000 08:05 33980421                      /lib64/tls/libc-2.3.4.so
342c432000-342c434000 rw-p 00132000 08:05 33980421                      /lib64/tls/libc-2.3.4.so
342c434000-342c439000 rw-p 342c434000 00:00 0
7fbfffe000-7fc0000000 rw-p 7fbfffe000 00:00 0
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0

Edit: But it's worse than that. I just copied cat from a 32bit linux to cat32 on a 64 bit linux and ran it:
Code:

cat32 /proc/self/maps
0060b000-00621000 r-xp 00000000 08:05 9158669                            /lib/ld-2.3.4.so
00621000-00622000 r-xp 00015000 08:05 9158669                            /lib/ld-2.3.4.so
00622000-00623000 rwxp 00016000 08:05 9158669                            /lib/ld-2.3.4.so
00625000-0074e000 r-xp 00000000 08:05 9158683                            /lib/tls/libc-2.3.4.so
0074e000-00750000 r-xp 00128000 08:05 9158683                            /lib/tls/libc-2.3.4.so
00750000-00752000 rwxp 0012a000 08:05 9158683                            /lib/tls/libc-2.3.4.so
00752000-00754000 rwxp 00752000 00:00 0
08048000-0804c000 r-xp 00000000 00:26 240676                            /home/fine/cat32
0804c000-0804d000 rwxp 00003000 00:26 240676                            /home/fine/cat32
0804d000-0806e000 rwxp 0804d000 00:00 0
f7dd4000-f7fd4000 r-xp 00000000 08:05 786549                            /usr/lib/locale/locale-archive
f7fd4000-f7fd5000 rwxp f7fd4000 00:00 0
f7ffd000-f7ffe000 rwxp f7ffd000 00:00 0
ffffc000-ffffe000 rw-p ffffc000 00:00 0
ffffe000-fffff000 r-xp ffffe000 00:00 0

That is real hard to tell apart from using cat that way on a 32 bit system. Yes, I really did run that on a 64-bit system.

wje_lq 02-20-2009 06:16 PM

Well, it was worth a shot. Thanks for the info.

gergely89 02-23-2009 11:19 AM

A line like
Quote:

if (cmp1 == 0xFFFFFFE3 && cmp2 == 0xFFFFFF80 && cmp3 == 0xFFFFFF80)
will give different result on 32-bit and 64-bit architectures, the 64-bit version needs to look like
Quote:

if (cmp1 == 0xFFFFFFFFFFFFFFE3 && cmp2 == 0xFFFFFFFFFFFFFF80 && cmp3 == 0xFFFFFFFFFFFFFF80)
to yield the same result (and it also uses unsigned long long instead of unsigned long). This is a real code sample for dealing with 2-byte japanese chars.

The point is, with some bit-testing on unsigned long long and unsigned long variables you can find out the CPU bit-width.

linux

johnsfine 02-23-2009 11:26 AM

Quote:

Originally Posted by gergely89 (Post 3454544)
with some bit-testing on unsigned long long and unsigned long variables you can find out the CPU bit-width.

That is an indirect and unsound way of testing the thing sizeof(void*) tests much more directly and reliably.

If you want to know the size of a pointer in the architecture/mode in which your program is running, just test that. Don't test something indirect.

"CPU bit-width" is a very vague phrase subject to many possible meanings. But I don't think any of those meanings can be reliably tested by the method you propose.

The OP apparently wanted to know the size of a pointer in the architecture/mode in which the Linux kernel is running. That might not be the same as the size of a pointer in the program doing the test.

smkururu 05-20-2009 11:28 AM

I believe this is what you want:
uname -m
on 64 bit computer it'll show x86_64
Give it a try.

Edit: Sorry, I just read that you want to check it programmatically.

soleilarw 05-22-2009 09:41 AM

There are more sound ways to find out the bit-size of the system, but gergely89 gives a quite interesting view on dealing with some value comparing tasks that will certainly give different results on 32-bit and 64-bit systems. He didn't mark his sample as the way to test for 64-bit systems, but as a hint on coding differences. At least that's how I interpreted it. Thanks anyway!

Linux Archive

lali.p 05-23-2009 12:15 PM

Hi,
Firstly thanks for your replies. What i wanted to know was how to "programmatically" find if an OS is 32 or 64 bit without assuming that *nix specific system calls would work on it.

Say, i don't know if the OS in question is windows or *nix.
So is there a way, i can write a program and conclude that the OS in use is 32 bit or 64 bit.

I agree that you can run a 32 bit compiled program on a 64 bit OS(but not the vice versa)

Regards
lali

dmail 05-23-2009 03:40 PM

Quote:

Originally Posted by lali.p (Post 3550394)
Hi,
Say, i don't know if the OS in question is windows or *nix.
So is there a way, i can write a program and conclude that the OS in use is 32 bit or 64 bit.
Regards
lali

Yes but it is going to be platform specific so would have to hide it under a layer of abstraction. For example in windows you could call GetSystemInfo and check the processor type via "wProcessorArchitecture" in the returned SYSTEM_INFO. On Linux you maybe use the same method as wine and parse "/proc/cpuinfo" checking for lm (long mode) in the flags in cpuinfo, if present it is 64bit system.

gnashley 05-24-2009 12:51 AM

Regarding Linux, you'll have to define 'OS'. You could well have a 64-bit-enabled kernel running on a system with 32-bits and binaries.


All times are GMT -5. The time now is 01:24 PM.