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.