Package: procps Version: 2:3.3.12-3+deb9u1 Severity: normal Tags: upstream patch
Dear Maintainer, The output of free --mega, --giga and up are erroneous. I could reproduce this error on stretch and jessie. Free takes the values in /proc/meminfo, where the units are wrongly labled. They are in KiB, so you have to multiply by 1024 to get the bytes amount. For some reason this was done for -b and --kilo, but not for other units. To calculate --mega, free takes the value in KiB and divides by 1000, which makes little sense. This error carried over to the dejagnu tests. Attached you will find a patch for both free.c and the dejagnu tests, which I have taken from upstream. This problem is fixed in upstream version 3.3.15 as far as I can tell. Have a nice day. -- System Information: Debian Release: 9.5 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.17.0-0.bpo.1-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US:en (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages procps depends on: ii init-system-helpers 1.48 ii libc6 2.24-11+deb9u3 ii libncurses5 6.0+20161126-1+deb9u2 ii libncursesw5 6.0+20161126-1+deb9u2 ii libprocps6 2:3.3.12-3+deb9u1 ii libtinfo5 6.0+20161126-1+deb9u2 ii lsb-base 9.20161125 Versions of packages procps recommends: ii psmisc 22.21-2.1+b2 procps suggests no packages. -- no debconf information
--- a/free.c +++ b/free.c @@ -130,18 +130,12 @@ snprintf(buf, sizeof(buf), "%lld", ((long long int)size) * 1024); return buf; } - if (args.exponent == 2) { - if (!(flags & FREE_SI)) - snprintf(buf, sizeof(buf), "%ld", size); - else - snprintf(buf, sizeof(buf), "%ld", (long int)(size / 0.9765625)); - return buf; - } - if (args.exponent > 2) { + if (args.exponent > 1) { /* In desired scale. */ snprintf(buf, sizeof(buf), "%ld", - (long int)(size / power(base, args.exponent - 2)) + (long int)(size * 1024.0 / power(base, args.exponent - 1)) ); + return buf; } } @@ -172,11 +166,11 @@ case 6: if (4 >= snprintf(buf, sizeof(buf), "%.1f%c", - (float)(size / power(base, i - 2)), *up)) + (float)(size * 1024 / power(base, i - 1)), *up)) return buf; if (4 >= snprintf(buf, sizeof(buf), "%ld%c", - (long)(size / power(base, i - 2)), *up)) + (long)(size * 1024 / power(base, i - 1)), *up)) return buf; break; case 7: --- a/testsuite/free.test/free.exp +++ b/testsuite/free.test/free.exp @@ -19,12 +19,12 @@ spawn $free -b expect_pass "$test" "^${free_header}Mem:\\s+${memtotal}\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s*Swap:\\s+${swaptotal}\\s+\\d+\\s+\\d+\\s*" -foreach {arg divisor } {-k 1 -m 1024 -g 1048576 --mega 1000 --giga 1000000 } { +foreach {arg divisor } {-k 1024 -m 1048576 -g 1073741824 --kilo 1000 --mega 1000000 --giga 1000000000 } { set test "free with $arg argument" - set memtotal [ expr { $memtotal_kb / $divisor } ] - set swaptotal [ expr { $swaptotal_kb / $divisor } ] + set memtest [ expr { $memtotal / $divisor } ] + set swaptest [ expr { $swaptotal / $divisor } ] spawn $free $arg - expect_pass "$test" "^${free_header}Mem:\\s+$memtotal\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s*Swap:\\s+${swaptotal}\\s+\\d+\\s+\\d+\\s*" + expect_pass "$test" "^${free_header}Mem:\\s+$memtest\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s*Swap:\\s+${swaptest}\\s+\\d+\\s+\\d+\\s*" } #set test "free with human readable output"