GNOME Bugzilla – Bug 681546
evince-3.4.0 crashes on start due to division by zero
Last modified: 2012-09-17 15:48:57 UTC
Created attachment 220819 [details] [review] Proposed fix evince-3.4.0 compiled for Loongson MIPS architecture crashes with SIGILL on start-up when GCC optimization is set to -O2 level. GDB session: Starting program: /home/petr/evince-3.4.0/work/evince-3.4.0/shell/.libs/evince [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/libthread_db.so.1". [New Thread 0x7697b330 (LWP 31106)] [New Thread 0x7617b330 (LWP 31107)] Program received signal SIGILL, Illegal instruction. 0x77f176ac in ev_view_set_adjustment_values (view=0x10270058, orientation=GTK_ORIENTATION_HORIZONTAL) at ev-view.c:618 618 new_value = CLAMP (upper * factor + 0.5, 0, upper - page_size); (gdb) disassemble 0x77f17664 <+292>: mul.d $f13,$f20,$f13 0x77f17668 <+296>: dmtc1 zero,$f13 0x77f1766c <+300>: lw t9,-31676(gp) 0x77f17670 <+304>: jalr t9 0x77f17674 <+308>: move a0,s0 0x77f17678 <+312>: lw t9,-31060(gp) 0x77f1767c <+316>: mov.d $f13,$f22 0x77f17680 <+320>: jalr t9 0x77f17684 <+324>: move a0,s0 0x77f17688 <+328>: lw v0,108(s1) 0x77f1768c <+332>: li v1,1 0x77f17690 <+336>: beq v0,v1,0x77f17788 <ev_view_set_adjustment_values+584> ---Type <return> to continue, or q <return> to quit--- 0x77f17694 <+340>: move at,at 0x77f17698 <+344>: bnez v0,0x77f176d0 <ev_view_set_adjustment_values+400> 0x77f1769c <+348>: li v1,2 0x77f176a0 <+352>: lw v0,-32716(gp) 0x77f176a4 <+356>: sub.d $f20,$f22,$f20 0x77f176a8 <+360>: ldc1 $f0,-23736(v0) => 0x77f176ac <+364>: madd.d $f0,$f22,$f24 0x77f176b0 <+368>: c.lt.d $f20,$f0 0x77f176b4 <+372>: bc1t 0x77f17864 <ev_view_set_adjustment_values+804> (gdb) info float f0: 0x3fe0000000000000 flt: 0 dbl: 0.5 f1: 0x3ff0000000000000 flt: 0 dbl: 1 f2: 0x0000000000000001 flt: 1.40129846e-45 dbl: 4.9406564584124654e-324 f3: 0x4076800000000000 flt: 0 dbl: 360 f4: 0x3fe0ab0ca9742035 flt: -5.42068187e-14 dbl: 0.52088006111535512 f5: 0x40456db6db6db6c3 flt: -6.69105181e+16 dbl: 42.857142857142684 f6: 0x3fdee3c6eb396bb0 flt: -2.24159816e+26 dbl: 0.48265240641711227 f7: 0x3fdee3c6eb396bb0 flt: -2.24159816e+26 dbl: 0.48265240641711227 f8: 0x3fe1285057ca4ac2 flt: 4.44844862e+14 dbl: 0.53617112299465242 f9: 0x3fe3333333333333 flt: 4.17232506e-08 dbl: 0.59999999999999998 f10: 0x0000000000000000 flt: 0 dbl: 0 f11: 0x0000000000000000 flt: 0 dbl: 0 f12: 0x3ff0000000000000 flt: 0 dbl: 1 f13: 0x3ff0000000000000 flt: 0 dbl: 1 f14: 0x0000000000000000 flt: 0 dbl: 0 f15: 0x0000000000000000 flt: 0 dbl: 0 f16: 0x3ff0000000000000 flt: 0 dbl: 1 f17: 0x0000000000000000 flt: 0 dbl: 0 f18: 0x3ff0000000000000 flt: 0 dbl: 1 f19: 0xffffffffffffffff flt: -nan dbl: -nan f20: 0x0000000000000000 flt: 0 dbl: 0 f21: 0xffffffffffffffff flt: -nan dbl: -nan f22: 0x3ff0000000000000 flt: 0 dbl: 1 ---Type <return> to continue, or q <return> to quit--- f23: 0xffffffffffffffff flt: -nan dbl: -nan f24: 0x7ff7ffffffffffff flt: -nan dbl: nan f25: 0xffffffffffffffff flt: -nan dbl: -nan f26: 0xffffffffffffffff flt: -nan dbl: -nan f27: 0xffffffffffffffff flt: -nan dbl: -nan f28: 0xffffffffffffffff flt: -nan dbl: -nan f29: 0xffffffffffffffff flt: -nan dbl: -nan f30: 0xffffffffffffffff flt: -nan dbl: -nan f31: 0xffffffffffffffff flt: -nan dbl: -nan fcsr: 0x800044 fir: 0x501 The crash is located on this line in libview/ev-view.c: switch (view->pending_scroll) { case SCROLL_TO_KEEP_POSITION: case SCROLL_TO_FIND_LOCATION: 618: → new_value = CLAMP (upper * factor + 0.5, 0, upper - page_size); Expanded: switch (view->pending_scroll) { case SCROLL_TO_KEEP_POSITION: case SCROLL_TO_FIND_LOCATION: new_value = (((upper * factor + 0.5) > (upper - page_size)) ? (upper - page_size) : (((upper * factor + 0.5) < (0)) ? (0) : (upper * factor + 0.5))); gtk_adjustment_set_value (adjustment, (int)new_value); break; Studying the disassembly shows the SIGILL comes from FPU exception while computing (upper * factor + 0.5) where factor is not-a-number using optimized multiply-and-add instruction. Obviously multiplying by NaN is not allowed by this instruction. Tracing origin of `factor' value revealed the factor is result of division by zero (0 / 0) here: switch (view->pending_scroll) { case SCROLL_TO_KEEP_POSITION: case SCROLL_TO_FIND_LOCATION: → factor = value / upper; break; I have no idea why `upper' value is zero, but it is and that puts NaN into factor. Attached patch guards the factor computation by check for upper value and resolves the problem for me.
I'm not an Evince developer, but the patch seems fine to me. Maybe a g_warning message could be added in order to show an exception has been triggered.
Review of attachment 220819 [details] [review]: We can actually skip the whole switch when upper is == 0. Thanks!