GNOME Bugzilla – Bug 707033
Hidden division by zero in examples/basic-actor.c
Last modified: 2013-09-24 00:05:16 UTC
During execution of basic-actor.c from clutter 1.14.4, during the first entry of the mouse pointer into the application window, there is a hidden division by zero, as is suggested by several following gdb session pieces pasted together -- when info->max_value equals info->min_value. The question is whether this division-by-zero accompanied by the SIGFPE suppression is the intended mode of operation. The real issue is that when the libclutter code is called from within a different environment (runtime of the SBCL Common Lisp implementation), the SIGFPE, corresponding to this division by zero, is actually raised. [deepfire betelheise cffi-clutter]$ gcc basic-actor.c -o basic-actor -I/usr/include/clutter-1.0/clutter -I/usr/include/clutter-1.0 -I/usr/include/cogl -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/glib-2.0 -I/usr/include/json-glib-1.0 -I/usr/lib64/glib-2.0/include -I/usr/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/pixman-1 -lclutter-1.0 -lglib-2.0 -lgobject-2.0 [deepfire betelheise cffi-clutter]$ gdb ./basic-actor GNU gdb (GDB) Fedora (7.6-34.fc19) Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/deepfire/src/cffi-clutter/basic-actor...done. (gdb) b _clutter_input_device_translate_axis Function "_clutter_input_device_translate_axis" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (_clutter_input_device_translate_axis) pending. (gdb) run Starting program: /home/deepfire/src/cffi-clutter/basic-actor Traceback (most recent call last): File "/usr/share/gdb/auto-load/usr/lib64/libgobject-2.0.so.0.3600.3-gdb.py", line 9, in <module> from gobject import register File "/usr/share/glib-2.0/gdb/gobject.py", line 3, in <module> import gdb.backtrace ImportError: No module named backtrace Traceback (most recent call last): File "/usr/share/gdb/auto-load/usr/lib64/libgobject-2.0.so.0.3600.3-gdb.py", line 9, in <module> from gobject import register File "/usr/share/glib-2.0/gdb/gobject.py", line 3, in <module> import gdb.backtrace ImportError: No module named backtrace [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Missing separate debuginfo for /lib64/libgraphite2.so.3 Try: yum --disablerepo='*' --enablerepo='*debug*' install /usr/lib/debug/.build-id/a1/aa32c91bc181cb69ebc81bbfd03a1349ea4e33.debug [New Thread 0x7fffef7fd700 (LWP 499)] Breakpoint 1, _clutter_input_device_translate_axis (device=device entry=0x7341a0, index_=index_ entry=0, value=633.43291059019975, axis_value=axis_value entry=0x6e8580) at ./clutter-input-device.c:1193 1193 if (device->axes == NULL || index_ >= device->axes->len) Missing separate debuginfos, use: debuginfo-install atk-2.8.0-1.fc19.x86_64 cairo-1.12.14-2.fc19.x86_64 cairo-gobject-1.12.14-2.fc19.x86_64 cogl-1.14.0-3.fc19.x86_64 elfutils-libelf-0.156-3.fc19.x86_64 expat-2.1.0-5.fc19.x86_64 fontconfig-2.10.93-1.fc19.x86_64 freetype-2.4.11-6.fc19.x86_64 gdk-pixbuf2-2.28.2-1.fc19.x86_64 glib2-2.36.3-3.fc19.x86_64 glibc-2.17-13.fc19.x86_64 gtk3-3.8.2-2.fc19.x86_64 harfbuzz-0.9.19-1.fc19.x86_64 json-glib-0.16.0-1.fc19.x86_64 libX11-1.6.0-1.fc19.x86_64 libXau-1.0.8-1.fc19.x86_64 libXcomposite-0.4.4-3.fc19.x86_64 libXcursor-1.1.14-1.fc19.x86_64 libXdamage-1.1.4-3.fc19.x86_64 libXext-1.3.2-1.fc19.x86_64 libXfixes-5.0.1-1.fc19.x86_64 libXi-1.7.2-1.fc19.x86_64 libXinerama-1.1.3-1.fc19.x86_64 libXrandr-1.4.1-1.fc19.x86_64 libXrender-0.9.7-6.20130524git786f78fd8.fc19.x86_64 libXxf86vm-1.1.3-1.fc19.x86_64 libdrm-2.4.46-1.fc19.x86_64 libffi-3.0.13-4.fc19.x86_64 libgcc-4.8.1-1.fc19.x86_64 libpng-1.5.13-2.fc19.x86_64 libselinux-2.1.13-15.fc19.x86_64 lib stdc++-4.8.1-1.fc19.x86_64 libwayland-client-1.2.0-1.fc19.x86_64 libwayland-cursor-1.2.0-1.fc19.x86_64 libwayland-server-1.2.0-1.fc19.x86_64 libxcb-1.9-3.fc19.x86_64 libxkbcommon-0.3.0-1.fc19.x86_64 llvm-libs-3.3-0.6.rc3.fc19.x86_64 mesa-dri-drivers-9.2-0.14.20130723.fc19.x86_64 mesa-libEGL-9.2-0.14.20130723.fc19.x86_64 mesa-libGL-9.2-0.14.20130723.fc19.x86_64 mesa-libgbm-9.2-0.14.20130723.fc19.x86_64 mesa-libglapi-9.2-0.14.20130723.fc19.x86_64 pango-1.34.1-1.fc19.x86_64 pcre-8.32-7.fc19.x86_64 pixman-0.30.0-1.fc19.x86_64 systemd-libs-204-9.fc19.x86_64 zlib-1.2.7-10.fc19.x86_64 (gdb) bt
+ Trace 232434
1194 return FALSE; (gdb) next 1193 if (device->axes == NULL || index_ >= device->axes->len) (gdb) next 1196 info = &g_array_index (device->axes, ClutterAxisInfo, index_); (gdb) next 1198 if (info->axis == CLUTTER_INPUT_AXIS_X || (gdb) next 1202 width = info->max_value - info->min_value; (gdb) next 1207 if (axis_value) (gdb) next 1202 width = info->max_value - info->min_value; (gdb) next 1203 real_value = (info->max_axis * (value - info->min_value) (gdb) next 1204 + info->min_axis * (info->max_value - value)) (gdb) next 1202 width = info->max_value - info->min_value; (gdb) next 1203 real_value = (info->max_axis * (value - info->min_value) (gdb) next 1204 + info->min_axis * (info->max_value - value)) (gdb) next 1203 real_value = (info->max_axis * (value - info->min_value) (gdb) next 1204 + info->min_axis * (info->max_value - value)) (gdb) next 1203 real_value = (info->max_axis * (value - info->min_value) (gdb) next 1207 if (axis_value) (gdb) next 1208 *axis_value = real_value; (gdb) printf "%f %f %f %f\n", info->min_axis, info->max_axis, info->min_value, info->max_value 0.000000 1.000000 -1.000000 -1.000000 (gdb) info registers all rax 0x0 0 rbx 0x0 0 rcx 0x822420 8528928 rdx 0x6e8580 7243136 rsi 0xffffffff 4294967295 rdi 0x611060 6361184 rbp 0x853780 0x853780 rsp 0x7fffffffdbc8 0x7fffffffdbc8 r8 0x823900 8534272 r9 0x0 0 r10 0x0 0 r11 0x382e44daf0 241294433008 r12 0x6e8580 7243136 r13 0x7341a0 7553440 r14 0x8537e8 8730600 r15 0x8537e8 8730600 rip 0x385767aad3 0x385767aad3 <_clutter_input_device_translate_axis+99> eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 st0 0 (raw 0x00000000000000000000) st1 0 (raw 0x00000000000000000000) st2 0 (raw 0x00000000000000000000) st3 0 (raw 0x00000000000000000000) st4 0 (raw 0x00000000000000000000) st5 0 (raw 0x00000000000000000000) st6 0 (raw 0x00000000000000000000) st7 0 (raw 0x00000000000000000000) fctrl 0x37f 895 fstat 0x0 0 ftag 0xffff 65535 fiseg 0x0 0 fioff 0x0 0 foseg 0x0 0 fooff 0x0 0 fop 0x0 0 xmm0 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x80000000, 0x0, 0x0}, v2_int64 = { 0x8000000000000000, 0x0}, uint128 = 0x00000000000000008000000000000000} xmm1 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x8000000000000000, 0x0}, v16_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x7ff0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x7ff00000, 0x0, 0x0}, v2_int64 = {0x7ff0000000000000, 0x0}, uint128 = 0x00000000000000007ff0000000000000} xmm2 {v4_float = {0x0, 0xffffffff, 0x0, 0x0}, v2_double = {0xffffffffffffffff, 0x0}, v16_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xbf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0xbff0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0xbff00000, 0x0, 0x0}, v2_int64 = {0xbff0000000000000, 0x0}, uint128 = 0x0000000000000000bff0000000000000} xmm3 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm4 {v4_float = {0x0, 0xfffffffc, 0x0, 0x0}, v2_double = {0xfffffffffffffd86, 0x0}, v16_int8 = {0x0, 0xd8, 0xd3, 0x99, 0x76, 0xd3, 0x83, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0xd800, 0x99d3, 0xd376, 0xc083, 0x0, 0x0, 0x0, 0x0}, v4_int32 = { 0x99d3d800, 0xc083d376, 0x0, 0x0}, v2_int64 = {0xc083d37699d3d800, 0x0}, uint128 = 0x0000000000000000c083d37699d3d800} xmm5 {v4_float = {0x148, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0xbe, 0x63, 0xa4, 0x43, 0x0 <repeats 12 times>}, v8_int16 = {0x63be, 0x43a4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x43a463be, 0x0, 0x0, 0x0}, v2_int64 = {0x43a463be, 0x0}, uint128 = 0x00000000000000000000000043a463be} xmm6 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm7 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm8 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x49, 0x85, 0x46, 0xbc, 0x0 <repeats 12 times>}, v8_int16 = {0x8549, 0xbc46, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0xbc468549, 0x0, 0x0, 0x0}, v2_int64 = {0xbc468549, 0x0}, uint128 = 0x000000000000000000000000bc468549} xmm9 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm10 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0xcc, 0x21, 0x59, 0x3f, 0x0 <repeats 12 times>}, v8_int16 = {0x21cc, 0x3f59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x3f5921cc, 0x0, 0x0, 0x0}, v2_int64 = {0x3f5921cc, 0x0}, uint128 = 0x0000000000000000000000003f5921cc} xmm11 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm12 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x4a, 0x85, 0x46, 0x3c, 0x0 <repeats 12 times>}, v8_int16 = {0x854a, 0x3c46, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x3c46854a, 0x0, 0x0, 0x0}, v2_int64 = {0x3c46854a, 0x0}, uint128 = 0x0000000000000000000000003c46854a} xmm13 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm14 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x4a, 0x85, 0x46, 0x3c, 0x0 <repeats 12 times>}, v8_int16 = {0x854a, 0x3c46, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x3c46854a, 0x0, 0x0, 0x0}, v2_int64 = {0x3c46854a, 0x0}, uint128 = 0x0000000000000000000000003c46854a} xmm15 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} mxcsr 0x1fa4 [ ZE PE IM DM ZM OM UM PM ] (gdb) disassemble Dump of assembler code for function _clutter_input_device_translate_axis: 0x000000385767aa70 <+0>: mov 0xc8(%rdi),%rdi 0x000000385767aa77 <+7>: xor %eax,%eax 0x000000385767aa79 <+9>: test %rdi,%rdi 0x000000385767aa7c <+12>: je 0x385767aaf0 <_clutter_input_device_translate_axis+128> 0x000000385767aa7e <+14>: cmp %esi,0x8(%rdi) 0x000000385767aa81 <+17>: jbe 0x385767aae8 <_clutter_input_device_translate_axis+120> 0x000000385767aa83 <+19>: mov %esi,%esi 0x000000385767aa85 <+21>: lea (%rsi,%rsi,2),%rcx 0x000000385767aa89 <+25>: shl $0x4,%rcx 0x000000385767aa8d <+29>: add (%rdi),%rcx 0x000000385767aa90 <+32>: mov (%rcx),%esi 0x000000385767aa92 <+34>: sub $0x1,%esi 0x000000385767aa95 <+37>: cmp $0x1,%esi 0x000000385767aa98 <+40>: jbe 0x385767aae8 <_clutter_input_device_translate_axis+120> 0x000000385767aa9a <+42>: movsd 0x20(%rcx),%xmm3 0x000000385767aa9f <+47>: test %rdx,%rdx 0x000000385767aaa2 <+50>: movsd 0x18(%rcx),%xmm2 0x000000385767aaa7 <+55>: movapd %xmm0,%xmm1 0x000000385767aaab <+59>: movapd %xmm3,%xmm4 0x000000385767aaaf <+63>: subsd %xmm2,%xmm3 0x000000385767aab3 <+67>: subsd %xmm2,%xmm1 0x000000385767aab7 <+71>: subsd %xmm0,%xmm4 0x000000385767aabb <+75>: movsd 0x8(%rcx),%xmm0 0x000000385767aac0 <+80>: mulsd 0x10(%rcx),%xmm1 0x000000385767aac5 <+85>: mulsd %xmm4,%xmm0 0x000000385767aac9 <+89>: addsd %xmm0,%xmm1 0x000000385767aacd <+93>: divsd %xmm3,%xmm1 0x000000385767aad1 <+97>: je 0x385767aae0 <_clutter_input_device_translate_axis+112> => 0x000000385767aad3 <+99>: movsd %xmm1,(%rdx) 0x000000385767aad7 <+103>: mov $0x1,%al 0x000000385767aad9 <+105>: retq 0x000000385767aada <+106>: nopw 0x0(%rax,%rax,1) 0x000000385767aae0 <+112>: mov $0x1,%eax 0x000000385767aae5 <+117>: nopl (%rax) 0x000000385767aae8 <+120>: repz retq 0x000000385767aaea <+122>: nopw 0x0(%rax,%rax,1) 0x000000385767aaf0 <+128>: repz retq [deepfire betelheise ~]$ rpm -qi clutter Name : clutter Version : 1.14.4 Release : 4.fc19 Architecture: x86_64 Install Date: Sun 14 Jul 2013 12:53:38 AM MSK Group : Development/Libraries Size : 4376632 License : LGPLv2+ Signature : RSA/SHA256, Wed 26 Jun 2013 07:44:50 PM MSK, Key ID 07477e65fb4b18e6 Source RPM : clutter-1.14.4-4.fc19.src.rpm Build Date : Wed 26 Jun 2013 12:40:05 PM MSK Build Host : buildvm-12.phx2.fedoraproject.org Relocations : (not relocatable) Packager : Fedora Project
So.. does anyone know if the combined FPE-suppression + division by zero is intended behavior?
Created attachment 253948 [details] [review] device: Guard against divisions by zero The range of a device could be 0, so we need to bail out from the scaling during the axis translation.
(In reply to comment #1) > So.. does anyone know if the combined FPE-suppression + division by zero is > intended behavior? it's not "intended" per se, but I never expected input devices with a 0 range, so this could be part of a larger issue with the device or its drivers (in the kernel or in X11). the device seems to have a [ -1, 1 ] range, which would lead to a width of 2. maybe we should be flipping the min/max values in case they are reported the wrong way around. the patch above should at least protect us from a division by zero.
What do I have to read, to be able to build clutter with this patch? Currently I'm bombing out on: [deepfire@betelheise clutter]$ make Making all in clutter make[1]: Entering directory `/home/deepfire/xsrc/clutter/clutter' make all-am make[2]: Entering directory `/home/deepfire/xsrc/clutter/clutter' CC clutter-backend-x11.lo In file included from ../clutter/clutter-types.h:32:0, from ../clutter/clutter-event.h:31, from ./x11/clutter-backend-x11.h:26, from ./x11/clutter-backend-x11.c:40: ./cogl/cogl.h:40:32: fatal error: cogl/cogl-material.h: No such file or directory #include <cogl/cogl-material.h> ^ compilation terminated. make[2]: *** [clutter-backend-x11.lo] Error 1 make[2]: Leaving directory `/home/deepfire/xsrc/clutter/clutter' make[1]: *** [all] Error 2 make[1]: Leaving directory `/home/deepfire/xsrc/clutter/clutter' make: *** [all-recursive] Error 1 Cogl does not appear to be mentioned anywhere in the README/HACKING..
Emmanuele, I'm happy to report that the provided patch solves my problem -- clutter 1.14.4, as per the released tarball, with the above patch applied, successfully avoids raising the division by zero condition, when run under SBCL! Thank you!
If you have some C code I could run, to help you pin down the weirdo input device -- I'd be happy to do it.
okay, I pushed the patch to the clutter-1.16 branch, and it's in the 1.16.0 release of Clutter. thanks for testing!