-
Notifications
You must be signed in to change notification settings - Fork 677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infinite loop and stack smash in ecma_errol0_dtoa #3724
Comments
Hi @anonpoet, does the conversion always output incorrect results, or it works in general, and misbehaves in specific cases? If the latter, it would be great if you could post the hex value of a double that triggers the issue. Additionally, could you try with one of the precompiled toolchains from the ARM Developer site, and see if the issue is persists? One more thing, the |
Here's the CMAKE file. I'll grab the compiler and post the results.
|
Sorry this took so long. Switching out compilers ended up being major surgery. I recompiled with a cross compiler that used the raspberry pi's hardware floating point unit. The version with the new compiler doesn't seem to have the bug. I haven't stared at the code for long enough, but I suspect that what was happening is that the soft float division when dividing by 10.0 was using its prerogative and approximating a value. The resulting value isn't guaranteed to not set the least significant bits to a random value. This could cause an infinite loop. |
I've got a bug that only shows up when cross compiling for a raspberry pi target. The code base was cloned from github in October 2019. Unfortunately, the git information wasn't preserved when it was cloned. It looks like the relevant functions haven't changed since then. I'm not terribly familiar with the jerryscript code base so if someone could weigh in and help debug, that would be great.
On the raspberry pi target, I'm getting a stack smash in ecma_errol0_dtoa()
. The backtraces and whatnot are shown below. It appears that in ecma_errol0_dtoa() iterates around the loop "while (high_bound.value != 0.0 || high_bound.offset != 0.0)" adding 0x30 to the buffer until it walks up the stack and clobbers something that causes the crash.
The maddening thing is that this bug only shows up on the raspberry pi builds and only triggers every few builds. The X64 and ESP8266 targets never have the same crash.
r0 0x0 0
r1 0x0 0
r2 0x75dcf000 1977413632
r3 0x30 48
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0xfff80000 4294443008
r8 0x7efff532 2130703666
r9 0x1 1
r10 0x1000 4096
r11 0x75dcde64 1977409124
r12 0x80000000 2147483648
sp 0x75dcda20 0x75dcda20
lr 0x37fa0 229280
pc 0x24c04 0x24c04 <ecma_errol0_dtoa+1472>
cpsr 0x30 48
Thread 4 "main.bad" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x75dce470 (LWP 18880)]
0x00024c04 in ecma_errol0_dtoa ()
(gdb) bt
#0 0x00024c04 in ecma_errol0_dtoa ()
#1 0x000244f0 in ecma_number_to_utf8_string ()
#2 0x000255a8 in ecma_new_ecma_string_from_number ()
#3 0x30303030 in ?? (). <---smashed obviously :(
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
(gdb) x/10i $pc
=> 0x24c04 <ecma_errol0_dtoa+1472>: strb r3, [r2, #0]
0x24c06 <ecma_errol0_dtoa+1474>: movs r0, r4
0x24c08 <ecma_errol0_dtoa+1476>: bl 0x38394 <____aeabi_i2d_from_thumb>
0x24c0c <ecma_errol0_dtoa+1480>: movs r2, r0
0x24c0e <ecma_errol0_dtoa+1482>: movs r3, r1
0x24c10 <ecma_errol0_dtoa+1484>: movs r0, r6
0x24c12 <ecma_errol0_dtoa+1486>: movs r1, r7
0x24c14 <ecma_errol0_dtoa+1488>: bl 0x38258 <____aeabi_dsub_from_thumb>
0x24c18 <ecma_errol0_dtoa+1492>: movs r2, #0
0x24c1a <ecma_errol0_dtoa+1494>: ldr r3, [pc, #304] ; (0x24d4c <ecma_errol0_dtoa+1800>)
(gdb) x/100bx $r2-80 <- 5200 0x30 written over the stack. This is the tail end of them.
0x75dcefb0: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefb8: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefc0: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefc8: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefd0: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefd8: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefe0: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcefe8: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dceff0: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dceff8: 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30
0x75dcf000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x75dcf008: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x75dcf010: 0x00 0x00 0x00 0x00
Build platform
Mac OS X 10.14.6 (Darwin 18.7.0 x86_64)
arm-unknown-linux-gnueabi-gcc (crosstool-NG 1.24.0) 8.3.0
Build steps
python tools/build.py --profile=minimal --external-context=ON --verbose --clean --toolchain cmake/toolchain_raspberry_pi.cmake --lto off --jerry-cmdline off
Javascript
print('Task Init');
automation.thisDevice.deviceID="8acaf075-2edd-4c27-ab9b-74c62b14d41d";
var p=automation.points[0];
print("Initial point",JSON.stringify(p));
This is the output on a loop that didn't crash. The conversion is obviously bad here as well.
Initial point {"globalPointID":"20605adf-9566-80eb-7646-9a28c5fa3af3","localPointID":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","description":"Percent door open","value":0.0005000000249999986823290498705318896099925041198730468750,"type":7}
p is a structure created in C. The double that it's trying to convert to a string is created using this function.
jerry_value_t pointValueToJerryValue(PointValueVariant* v){
debug3("pointValueToJerryValue\n");
}
I'm happy to provide a test binary with the issue.
Thanks in advance!
The text was updated successfully, but these errors were encountered: