[cairo] Segfault at sweep_line_delete on video playback

Bryce W. Harrington b.harrington at samsung.com
Thu Mar 20 14:33:50 PDT 2014


On Thu, Mar 20, 2014 at 09:56:02PM +0100, Thibaut wrote:
> On Mon, Mar 17, 2014, Bryce W. Harrington wrote:
> 
> > On Sun, Mar 16, 2014 at 06:29:15AM -0500, David Smith wrote:
> >> Can any of the Cairo devs take a look at this bug report and determine
> >> whether or not this is a Cairo bug or if it's something else?
> >>
> >>
> >> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=739262#50
> 
> > Yes, it does look like a bug in the tessellation code.  ickle is
> > probably the dev you should talk to.  Meanwhile, it would be helpful to
> > have:
> 
> >  gdb> print *sweep
> >  gdb> print *rectangle
> >  gdb> print *(rectangle->left.prev)
> 
> > Detailed steps to reproduce would of course be extremely helpful here
> > too.
> 
> Program received signal SIGSEGV, Segmentation fault.
> sweep_line_delete (rectangle=0x7fffffff5c70, sweep=0x7fffffff5930)
>     at /tmp/buildd/cairo-1.12.16/src/cairo-bentley-ottmann-rectangular.c:567
> 567   
> /tmp/buildd/cairo-1.12.16/src/cairo-bentley-ottmann-rectangular.c: Aucun
> fichier ou dossier de ce type.
> (gdb) bt
> #0  sweep_line_delete (rectangle=0x7fffffff5c70, sweep=0x7fffffff5930)
>     at /tmp/buildd/cairo-1.12.16/src/cairo-bentley-ottmann-rectangular.c:567
> #1  _cairo_bentley_ottmann_tessellate_rectangular (
>     rectangles=rectangles at entry=0x7fffffff5b00,
>     num_rectangles=num_rectangles at entry=3,
>     fill_rule=fill_rule at entry=CAIRO_FILL_RULE_WINDING,
>     do_traps=do_traps at entry=0, container=container at entry=0x7fffffff6c00)
>     at /tmp/buildd/cairo-1.12.16/src/cairo-bentley-ottmann-rectangular.c:659
> #2  0x00007ffff2f2f193 in _cairo_bentley_ottmann_tessellate_boxes (
>     in=in at entry=0x7fffffff6e50,
>     fill_rule=fill_rule at entry=CAIRO_FILL_RULE_WINDING,
>     out=out at entry=0x7fffffff6c00)
>     at /tmp/buildd/cairo-1.12.16/src/cairo-bentley-ottmann-rectangular.c:877
> (gdb) print *sweep
> $1 = {rectangles = 0x7fffffff5b20, stop = 0x7fffffff5af0, head = {
>     next = 0x7fffffff5bc0, prev = 0x0, right = 0x0, x = -2147483648,
>     top = 218112, dir = 0}, tail = {next = 0x0, prev = 0x7fffffff5be8,
>     right = 0x0, x = 2147483647, top = 32767, dir = 0},
>   insert = 0x7fffffff5c70, cursor = 0x7fffffff5bc0, current_y = 256,
>   last_y = 0, stop_size = 2, insert_x = 256,
>   fill_rule = CAIRO_FILL_RULE_WINDING, do_traps = 0,
>   container = 0x7fffffff6c00, unwind = {{__jmpbuf = {3,
> -6409794171536495218,
>         140737488313280, 140737488313072, 140737488313088, 140737488317440,
>         -6409794172308247154, -6409805128873759346}, __mask_was_saved = 0,
>       __saved_mask = {__val = {936783907097600, 936783907083008, 1, 0, 0,
>           140737488311953, 0, 936783907097600, 665719930882, 218091,
>           936693712552091, 936783906865408, 936783907083243, 4294967295, 0,
>           140737488312832}}}}}
> (gdb) print *rectangle
> $2 = {left = {next = 0x7fffffff5c98, prev = 0x0, right = 0x0, x = 256,
>     top = 0, dir = -1}, right = {next = 0x0, prev = 0x7fffffff5c70,
>     right = 0x0, x = 256, top = 32767, dir = 1}, top = 256, bottom = 256}
> (gdb) print *(rectangle->left.prev)
> Cannot access memory at address 0x0

So we see rectangle->left is NULL in this case, so fails when
dereferenced in sweep_line_delete().

This is deep in code I'm unfamiliar with, so really should be looked at
by ickle.  There's probably an important reason why the pointer is null
at this point.  But here's a really stupid patch, to see if just
papering over the bug helps at all, or if it just shifts the crash
elsewhere.  Give it a try and if it still crashes post another backtrace.


diff --git a/src/cairo-bentley-ottmann-rectangular.c b/src/cairo-bentley-ottmann-rectangular.c
index 5541bdc..042a9d8 100644
--- a/src/cairo-bentley-ottmann-rectangular.c
+++ b/src/cairo-bentley-ottmann-rectangular.c
@@ -563,6 +563,9 @@ sweep_line_delete (sweep_line_t	*sweep, rectangle_t *rectangle)
 {
     cairo_bool_t update;
 
+    if (!rectangle->left && !rectangle->right)
+	return FALSE;
+
     update = TRUE;
     if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING &&
 	rectangle->left.prev->dir == rectangle->left.dir)


More information about the cairo mailing list