Page 1 of 1

Division broken, Memory corrupted on Nano Pi Duo

Posted: Thu Dec 21, 2017 9:07 am
by lupi
Hi,

I noticed that the division of 64 bit integers is broken on Nano Pi Duo using the gcc and runtime lib from the Ubuntu repositories.

See the following example:

Code: Select all

#include <stdio.h>


unsigned long long int __udivmoddi4(unsigned long long int num, unsigned long long int den, unsigned long long int * rem_p)
{
    unsigned long long int quot = 0, qbit = 1;

    if (den == 0) {
      return 0;      /* If trap returns... */
    }

    /* Left-justify denominator and count shift */
    while ((signed long long int) den >= 0) {
   den <<= 1;
   qbit <<= 1;
    }

    while (qbit) {
   if (den <= num) {
       num -= den;
       quot += qbit;
   }
   den >>= 1;
   qbit >>= 1;
    }

    if (rem_p)
   *rem_p = num;

    return quot;
}

signed long long int div(signed long long int num, signed long long int den){
   bool signNum = num<0, signDen = den<0;
   signed long long int res = (signed long long int)__udivmoddi4((unsigned long long int)(signNum?-num:num), (unsigned long long int)(signDen?-den:den), NULL);
   return signNum!=signDen?-res:res;
}

int main(){

   signed long long int value1 = 999;
   signed long long int value2 = -333;
   value1 = value1 / value2;
   //value1 = div(value1, value2);
   
   printf("value1: %lli\n", value1);

   return 0;
}


You can test it with valgrind after compiling: valgrind --leak-check=yes ./test
If you use the custom div function (value1 = div(value1, value2);) everything works as expected but if you use the normal integer division (value1 = value1 / value2;) you get the following error:

Code: Select all

==2370== Memcheck, a memory error detector
==2370== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2370== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==2370== Command: ./test
==2370==
==2370== Invalid write of size 4
==2370==    at 0x4867B52: ??? (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2370==  Address 0xbde23430 is on thread 1's stack
==2370==  16 bytes below stack pointer
==2370==
==2370== Conditional jump or move depends on uninitialised value(s)
==2370==    at 0x48692FE: __udivmoddi4 (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2370==
==2370== Use of uninitialised value of size 4
==2370==    at 0x4869300: __udivmoddi4 (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2370==
==2370== Use of uninitialised value of size 4
==2370==    at 0x4867BA2: ??? (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2370==
value1: -3
==2370==
==2370== HEAP SUMMARY:
==2370==     in use at exit: 0 bytes in 0 blocks
==2370==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==2370==
==2370== All heap blocks were freed -- no leaks are possible
==2370==
==2370== For counts of detected and suppressed errors, rerun with: -v
==2370== Use --track-origins=yes to see where uninitialised values come from
==2370== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 6 from 3)


Please note: The mentioned __udivmoddi4 is from libgcc_s.so.1 and not from my code, so the error is clearly in the corresponding library. Feel free to comment out the whole replacement and see that the error still occurs.

Re: Division broken, Memory corrupted on Nano Pi Duo

Posted: Fri Dec 22, 2017 3:06 am
by lawrence
Use the following compiler on an ubuntu 16.04 64bit host:
sudo apt-get -y install gcc-arm-linux-gnueabihf
sudo apt-get -y install g++-arm-linux-gnueabihf

Re: Division broken, Memory corrupted on Nano Pi Duo

Posted: Fri Dec 22, 2017 8:19 am
by lupi
Hi,

I'm not doing cross compiling. I have installed gcc on the Nano Pi Duo from the repositories.
(sudo apt-get install g++ directly on the NanoPi). I think this should be the correct compiler or am I wrong about that?

EDIT:
I have just tried it with the mentioned cross compiler and the result is the same.
I fear that the problem is in the shared object and therefore all program using 64 bit integer division on Nano Pi Duo are therefore unstable.

Re: Division broken, Memory corrupted on Nano Pi Duo

Posted: Thu Jan 04, 2018 9:33 am
by lawrence
apt-get install -y gcc-4.8 g++-4.8
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 100

-----------------------------

root@NanoPi-NEO-Air:~# valgrind --leak-check=yes ./test.4.8
==1342== Memcheck, a memory error detector
==1342== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==1342== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==1342== Command: ./test.4.8
==1342==
value1: -3
==1342==
==1342== HEAP SUMMARY:
==1342== in use at exit: 0 bytes in 0 blocks
==1342== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==1342==
==1342== All heap blocks were freed -- no leaks are possible
==1342==
==1342== For counts of detected and suppressed errors, rerun with: -v
==1342== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

Re: Division broken, Memory corrupted on Nano Pi Duo

Posted: Fri Jan 05, 2018 8:12 am
by lupi
Thank you for your reply. Unfortunately the problem is not solved with gcc4.8 (see below).
I believe the problem is about the emulation of 64 bit integer division which is appearently not available in the 32 Bit ARMv7 architecture.
It seems to be however solved if it is compiled with optimization e.g. -O3, because the compiler can do the division in this particular test code at compile time.
If you compile it with -g, you can observe, that the problem still exists even with gcc4.8:

root@SensorBox:/home/pi/test# g++ --version
g++ (Ubuntu/Linaro 4.8.5-4ubuntu2) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

root@SensorBox:/home/pi/test# g++ -g test.cpp -o test
root@SensorBox:/home/pi/test# valgrind --leak-check=yes ./test
==2446== Memcheck, a memory error detector
==2446== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2446== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==2446== Command: ./test
==2446==
==2446== Invalid write of size 4
==2446== at 0x4867B52: ??? (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2446== Address 0xbdccd438 is on thread 1's stack
==2446== 16 bytes below stack pointer
==2446==
==2446== Conditional jump or move depends on uninitialised value(s)
==2446== at 0x48692FE: __udivmoddi4 (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2446==
==2446== Use of uninitialised value of size 4
==2446== at 0x4869300: __udivmoddi4 (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2446==
==2446== Use of uninitialised value of size 4
==2446== at 0x4867BA2: ??? (in /lib/arm-linux-gnueabihf/libgcc_s.so.1)
==2446==
value1: -3
==2446==
==2446== HEAP SUMMARY:
==2446== in use at exit: 0 bytes in 0 blocks
==2446== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==2446==
==2446== All heap blocks were freed -- no leaks are possible
==2446==
==2446== For counts of detected and suppressed errors, rerun with: -v
==2446== Use --track-origins=yes to see where uninitialised values come from
==2446== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 6 from 3)

Re: Division broken, Memory corrupted on Nano Pi Duo

Posted: Fri Apr 05, 2019 7:23 pm
by BACILY
lupi wrote:
Hi,

I'm not doing cross compiling. I have installed gcc on the Nano Pi Duo from the repositories.
(sudo apt-get install g++ directly on the NanoPi). I think this should be the correct compiler or am I wrong about that?

EDIT:
I have just tried it with the mentioned cross compiler and the result is the same.
I fear that the problem is in the shared object and therefore Dafont 192.168.l.l FileHippo all program using 64 bit integer division on Nano Pi Duo are therefore unstable.

I noticed that the division of 64 bit integers [/color][/url] is broken on Nano Pi Duo using the gcc and runtime lib from the Ubuntu repositories.