### Division broken, Memory corrupted on Nano Pi Duo

Posted:

**Thu Dec 21, 2017 9:07 am**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:

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:

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.

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.