[erlang-bugs] win32sysinfo.c doesn't understand DWORDLONG is unsigned and long
Björn-Egil Dahlberg
egil@REDACTED
Thu Jan 28 18:59:14 CET 2010
Hi Matthew,
Thank you for reporting this issue.
I will have a look at this but I think you are correct.
%I64d seems to be the wrong thing here.
Regards,
Björn-Egil
Erlang/OTP
Matthew Sackman wrote:
> void get_avail_mem_ext() {
> char answer[512];
> MEMORYSTATUSEX ms;
> ms.dwLength=sizeof(MEMORYSTATUSEX);
> GlobalMemoryStatusEx(&ms);
> sprintf(answer,"%d %I64d %I64d %I64d %I64d %I64d %I64d\n",
> ms.dwMemoryLoad,
> ms.ullTotalPhys,
> ms.ullAvailPhys,
> ms.ullTotalPageFile,
> ms.ullAvailPageFile,
> ms.ullTotalVirtual,
> ms.ullAvailVirtual
> );
> return_answer(answer);
> /*
> DWORD dwLength;
> DWORD dwMemoryLoad;
> DWORDLONG ullTotalPhys;
> DWORDLONG ullAvailPhys;
> DWORDLONG ullTotalPageFile;
> DWORDLONG ullAvailPageFile;
> DWORDLONG ullTotalVirtual;
> DWORDLONG ullAvailVirtual;
> */
> }
>
> DWORD and DWORDLONG are unsigned and long. By printing with %I64d, you're
> reinterpreting them as signed ints, leading to windows users with 4GB of
> RAM being told they have negative amounts of RAM (or even 0). Eg:
>
> $ cat foo.c
> #include <stddef.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <stdint.h>
>
> main()
> {
> uint64_t n = 4293308416;
> printf("%I64d\n", n);
> printf("%I64u\n", n);
> printf("%I64lu\n", n);
> return 0;
> }
>
> $ gcc -o foo foo.c && ./foo
> -1658880
> 4293308416
> 4293308416
>
> Elsewhere in win32sysinfo.c, there are %I64u format specifiers. It looks
> like the only occurrence of %I64d is in the get_avail_mem_ext function.
>
> Because they're long, I *think* they should be %I64lu. I think what's
> happening is that the d makes it an int, thus the msb is set, hence the
> negative answer. And indeed, setting n to 4294967297 (i.e. 2^32 + 1)
> gives:
>
> 1
> 1
> 4294967297
>
> Note that the above is running under a 64-bit Linux. I don't know if the
> behaviour of %I64 is the same under Windows. I also don't know what size
> an int is in a 32-bit application running on 64-bit windows. My C isn't
> all that great. My reading is that the %I64 just says to use the system
> locale, and to pad with whitespace up to 64 characters.
>
> Matthew
>
> ________________________________________________________________
> erlang-bugs mailing list. See http://www.erlang.org/faq.html
> erlang-bugs (at) erlang.org
>
More information about the erlang-bugs
mailing list