Bug 12995

Summary: Wireshark crashes with BadMatch
Product: cairo Reporter: Guy Harris <guy>
Component: generalAssignee: Carl Worth <cworth>
Status: RESOLVED NOTOURBUG QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium CC: dmacks, freedesktop
Version: 1.4.9   
Hardware: All   
OS: Mac OS X (All)   
Whiteboard:
i915 platform: i915 features:

Description Guy Harris 2007-10-29 11:52:52 UTC
When running Wireshark with --sync under GDB, I get a BadMatch error when I try
to capture and stop the capture.

The stack trace is:

#0  0x036ba78c in gdk_x_error ()
#1  0x038c59bc in _XError ()
#2  0x038c6fcc in _XReply ()
#3  0x038bc9d0 in XSync ()
#4  0x038bca74 in _XSyncFunction ()
#5  0x038878ec in XRenderCreatePicture ()
#6  0x037617f0 in _cairo_xlib_surface_ensure_dst_picture (surface=0x58323f0) at
cairo-xlib-surface.c:723
#7  0x03764cb0 in _cairo_xlib_surface_show_glyphs (abstract_dst=0x58323f0,
op=CAIRO_OPERATOR_OVER, src_pattern=0xbfffbcc8, glyphs=0x58326a0, num_glyphs=8,
scaled_font=Cannot access memory at address 0x0
) at cairo-xlib-surface.c:2832
#8  0x03748678 in _cairo_surface_show_glyphs (surface=0x58323f0,
op=CAIRO_OPERATOR_OVER, source=<value optimized out>, glyphs=0x5832a50,
num_glyphs=8, scaled_font=0x582bcc0) at cairo-surface.c:1830
#9  0x0373cde4 in _cairo_gstate_show_glyphs (gstate=0x5832730,
glyphs=0xbfffbf68, num_glyphs=8) at cairo-gstate.c:1449
#10 0x03738038 in cairo_show_glyphs (cr=0x5838c10, glyphs=<value optimized
out>, num_glyphs=<value optimized out>) at cairo.c:2555
#11 0x002ca8b0 in pango_cairo_renderer_draw_glyphs ()
#12 0x009bf940 in pango_renderer_draw_glyphs ()
#13 0x002cb0a8 in _pango_cairo_do_glyph_string ()
#14 0x009bf940 in pango_renderer_draw_glyphs ()
#15 0x009c0d18 in pango_renderer_draw_layout_line ()
#16 0x009c110c in pango_renderer_draw_layout ()
#17 0x0368a36c in gdk_draw_layout_with_colors ()
#18 0x00511030 in draw_row ()
#19 0x005112e4 in draw_rows ()
#20 0x0004b044 in packet_list_thaw () at packet_list.c:705
#21 0x0000d85c in cf_read (cf=0x10e090) at file.c:545
#22 0x00009970 in capture_input_closed (capture_opts=Cannot access memory at
address 0x0
) at capture.c:202
#23 0x0000b350 in sync_pipe_input_cb (source=5, user_data=0x11e1f0,
capture_opts=<value optimized out>) at capture_sync.c:649
#24 0x0003c9cc in pipe_input_cb (data=0x1227f0, source=5, condition=<value
optimized out>) at gui_utils.c:715
#25 0x03683db8 in gdk_io_invoke ()
#26 0x03a2b8a0 in g_main_context_dispatch ()
#27 0x03a2fbb4 in g_main_context_iterate ()
#28 0x03a2ffe4 in g_main_loop_run ()
#29 0x005c6a40 in gtk_main ()
#30 0x00046040 in main (argc=0, argv=0xbfffedc4) at main.c:3036

xdpyinfo says

name of display:    /tmp/launch-ZLB0AT/:0
version number:    11.0
vendor string:    The X.Org Foundation
vendor release number:    70200000
X.Org version: 7.2.0
maximum request size:  16777212 bytes
motion buffer size:  0
bitmap unit, bit order, padding:    32, MSBFirst, 32
image byte order:    MSBFirst
number of supported pixmap formats:    7
supported pixmap formats:
    depth 1, bits_per_pixel 1, scanline_pad 32
    depth 4, bits_per_pixel 8, scanline_pad 32
    depth 8, bits_per_pixel 8, scanline_pad 32
    depth 15, bits_per_pixel 16, scanline_pad 32
    depth 16, bits_per_pixel 16, scanline_pad 32
    depth 24, bits_per_pixel 32, scanline_pad 32
    depth 32, bits_per_pixel 32, scanline_pad 32
keycode range:    minimum 8, maximum 255
focus:  PointerRoot
number of extensions:    28
    Apple-DRI
    Apple-WM
    BIG-REQUESTS
    DAMAGE
    DEC-XTRAP
    DOUBLE-BUFFER
    DPMS
    Extended-Visual-Information
    GLX
    MIT-SCREEN-SAVER
    MIT-SHM
    MIT-SUNDRY-NONSTANDARD
    RECORD
    RENDER
    SECURITY
    SGI-GLX
    SHAPE
    SYNC
    TOG-CUP
    X-Resource
    XAccessControlExtension
    XC-APPGROUP
    XC-MISC
    XFIXES
    XInputExtension
    XKEYBOARD
    XTEST
    XVideo
default screen number:    0
number of screens:    1

screen #0:
  print screen:    no
  dimensions:    1920x1179 pixels (650x399 millimeters)
  resolution:    75x75 dots per inch
  depths (7):    24, 1, 4, 8, 15, 16, 32
  root window id:    0x3f
  depth of root window:    24 planes
  number of colormaps:    minimum 1, maximum 1
  default colormap:    0x21
  default number of colormap cells:    256
  preallocated pixels:    black 0, white 16777215
  options:    backing-store NO, save-unders NO
  largest cursor:    32x32
  current input event mask:    0x0
  number of visuals:    4
  default visual id:  0x23
  visual:
    visual id:    0x23
    class:    TrueColor
    depth:    24 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits
  visual:
    visual id:    0x24
    class:    TrueColor
    depth:    24 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits
  visual:
    visual id:    0x25
    class:    TrueColor
    depth:    24 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits
  visual:
    visual id:    0x26
    class:    TrueColor
    depth:    24 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits

A version of the X server with some debugging printouts added prints

    ProcRenderCreatePicture: BadMatch due to pformat->depth (24) !=
pDrawable->depth (32)

which means that the failure was in

static int
ProcRenderCreatePicture (ClientPtr client)
{
    PicturePtr      pPicture;
    DrawablePtr     pDrawable;
    PictFormatPtr   pFormat;
    int             len;
    int             error;
    REQUEST(xRenderCreatePictureReq);

    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);

    LEGAL_NEW_RESOURCE(stuff->pid, client);
    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
                             SecurityWriteAccess);
    pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
                                                      stuff->format,
                                                      PictFormatType,
                                                      SecurityReadAccess);
    if (!pFormat)
    {
        client->errorValue = stuff->format;
        return RenderErrBase + BadPictFormat;
    }
    if (pFormat->depth != pDrawable->depth)
        return BadMatch;  <-this is the failure

If I configure X11.app to have "thousands" rather than "millions" of colors -
i.e., to offer only 16 bits of color rather than 24 bits of color - the problem
goes away.  (Is the Drawable 24 bits of color + 8 bits of alpha with "millions"
of colors, and does it become 16 bits of color + 8 bits of alpha with only
"thousands" of colors, so that the depth is 24 bits?)

This is with:

    GTK+ 2.12.0
    Pango 1.18.0
    Cairo 1.4.10
    ATK 1.18.0
    GLib 2.14.0

on Mac OS X 10.5.

In thousands-of-colors mode, xdpyinfo prints

name of display:    /tmp/launch-ZLB0AT/:0
version number:    11.0
vendor string:    The X.Org Foundation
vendor release number:    70200000
X.Org version: 7.2.0
maximum request size:  16777212 bytes
motion buffer size:  0
bitmap unit, bit order, padding:    32, MSBFirst, 32
image byte order:    MSBFirst
number of supported pixmap formats:    7
supported pixmap formats:
    depth 1, bits_per_pixel 1, scanline_pad 32
    depth 4, bits_per_pixel 8, scanline_pad 32
    depth 8, bits_per_pixel 8, scanline_pad 32
    depth 15, bits_per_pixel 16, scanline_pad 32
    depth 16, bits_per_pixel 16, scanline_pad 32
    depth 24, bits_per_pixel 32, scanline_pad 32
    depth 32, bits_per_pixel 32, scanline_pad 32
keycode range:    minimum 8, maximum 255
focus:  None
number of extensions:    28
    Apple-DRI
    Apple-WM
    BIG-REQUESTS
    DAMAGE
    DEC-XTRAP
    DOUBLE-BUFFER
    DPMS
    Extended-Visual-Information
    GLX
    MIT-SCREEN-SAVER
    MIT-SHM
    MIT-SUNDRY-NONSTANDARD
    RECORD
    RENDER
    SECURITY
    SGI-GLX
    SHAPE
    SYNC
    TOG-CUP
    X-Resource
    XAccessControlExtension
    XC-APPGROUP
    XC-MISC
    XFIXES
    XInputExtension
    XKEYBOARD
    XTEST
    XVideo
default screen number:    0
number of screens:    1

screen #0:
  print screen:    no
  dimensions:    1920x1179 pixels (650x399 millimeters)
  resolution:    75x75 dots per inch
  depths (7):    15, 1, 4, 8, 16, 24, 32
  root window id:    0x3f
  depth of root window:    15 planes
  number of colormaps:    minimum 1, maximum 1
  default colormap:    0x21
  default number of colormap cells:    32
  preallocated pixels:    black 0, white 32767
  options:    backing-store NO, save-unders NO
  largest cursor:    32x32
  current input event mask:    0x1a0000
    StructureNotifyMask      SubstructureNotifyMask   SubstructureRedirectMask 
  number of visuals:    4
  default visual id:  0x23
  visual:
    visual id:    0x23
    class:    TrueColor
    depth:    15 planes
    available colormap entries:    32 per subfield
    red, green, blue masks:    0x7c00, 0x3e0, 0x1f
    significant bits in color specification:    5 bits
  visual:
    visual id:    0x24
    class:    TrueColor
    depth:    15 planes
    available colormap entries:    32 per subfield
    red, green, blue masks:    0x7c00, 0x3e0, 0x1f
    significant bits in color specification:    5 bits
  visual:
    visual id:    0x25
    class:    TrueColor
    depth:    15 planes
    available colormap entries:    32 per subfield
    red, green, blue masks:    0x7c00, 0x3e0, 0x1f
    significant bits in color specification:    5 bits
  visual:
    visual id:    0x26
    class:    TrueColor
    depth:    15 planes
    available colormap entries:    32 per subfield
    red, green, blue masks:    0x7c00, 0x3e0, 0x1f
    significant bits in color specification:    5 bits

See also Pango bug 476409:

    http://bugzilla.gnome.org/show_bug.cgi?id=476409

Wireshark bug 1953

    http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1953

which are for the same problem; I've also filed a bug against Leopard's X11.app (Radar 5147896, but that's probably not accessible to people outside Apple), as I don't know where the underlying problem is.
Comment 1 Guy Harris 2007-10-29 22:37:22 UTC
Owen Taylor noted in the Pango bug:

    This is almost certainly not a Pango issue. Hard to say what is going on
    without
    knowing what wireshark is doing ... it appears that the cairo surface that
    it's using got created improperly for the actual drawing it's drawing to.

    I'm not quite sure how that could happen, since I think GTK+ always should
    be validating the depth to match that of the drawable. It's conceivable
    that your libX11 is doing something unusual.

    The code that creates the cairo surface is in GTK+ 
    gdk_x11_ref_cairo_surface()

    Check:

     A) the depth of the visual
     B) the depth that GTK+ thinks the drawable (most likely a pixmap) has
     C) the actual depth of the drawable (use XGetGeometry())

and I subsequently noted that

    It was a bit buried in the middle of the initial bug report, so it's easy to
    miss, but I hacked up the X server to report the precise problem; it printed

        ProcRenderCreatePicture: BadMatch due to pformat->depth (24) !=
pDrawable->depth (32)

    which means that the failure was in

    static int
    ProcRenderCreatePicture (ClientPtr client)
    {

            ...

        if (pFormat->depth != pDrawable->depth)
            return BadMatch;  <-this is the failure

    So the X server seems to think the drawable has a depth of 32.

    According to xdpyinfo, the visuals were

      number of visuals:    4
      default visual id:  0x23
      visual:
        visual id:    0x23
        class:    TrueColor
        depth:    24 planes
        available colormap entries:    256 per subfield
        red, green, blue masks:    0xff0000, 0xff00, 0xff
        significant bits in color specification:    8 bits
      visual:
        visual id:    0x24
        class:    TrueColor
        depth:    24 planes
        available colormap entries:    256 per subfield
        red, green, blue masks:    0xff0000, 0xff00, 0xff
        significant bits in color specification:    8 bits
      visual:
        visual id:    0x25
        class:    TrueColor
        depth:    24 planes
        available colormap entries:    256 per subfield
        red, green, blue masks:    0xff0000, 0xff00, 0xff
        significant bits in color specification:    8 bits
      visual:
        visual id:    0x26
        class:    TrueColor
        depth:    24 planes
        available colormap entries:    256 per subfield
        red, green, blue masks:    0xff0000, 0xff00, 0xff
        significant bits in color specification:    8 bits

    so they all appear to be 24-bit.

and later, in response to Owen's suggestion, hacked up gdk_x11_ref_cairo_surface() to print the information he mentioned:

    The following code, stuck after the gdk_drawable_get_visual() call in
    gdk_x11_ref_cairo_surface(), repeatedly swears on a stack of Bibles that the
    visual and the drawable are both of depth 24, as is the depth as reported by
    XGetGeometry():

          if (logfile != NULL) {
            if (visual != NULL)
              fprintf(logfile, "Visual: depth %d\n", visual->depth);
            fprintf(logfile, "Drawable: depth %d\n",
                    gdk_drawable_get_depth(drawable));
            if (XGetGeometry(GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
                                  &root, &x, &y, &xwidth, &xheight, &border_width,
                                  &depth))
              fprintf(logfile, "Drawable: X11 depth %u\n", depth);
            else
              fprintf(logfile, "XGetGeometry failed\n");
          }

    ("logfile" was opened earlier).

    From a quick look at _cairo_xlib_surface_ensure_dst_picture() in Cairo 1.4.10's
    cairo-xlib-surface.c, and from the failure mode on the server (24-bit drawable,
    32-bit format), it appears that surface->drawable would be 24-bit and
    surface->xrender_format would be 32-bit.  That would agree with the debug
    code's insistence that the visual and drawable are 24-bit.
Comment 2 Owen Taylor 2007-10-30 05:11:06 UTC
Well, now you should be able to trace through a single function

_cairo_xlib_surface_create_internal()

And figure out what went wrong and why.

Comment 3 Guy Harris 2007-10-30 19:26:27 UTC
Oh, my goodness.

At the end of _cairo_xlib_surface_create_internal(), I added some fprintfs:

    if (foo != NULL) {
        fprintf(foo, "surface %p, dpy %p, drawable 0x%08lx, xrender_format %p\n",
                surface, surface->dpy, surface->drawable, surface->xrender_format);
        fclose(foo);
    }

and it printed

  surface 0x69d1af0, dpy 0x480fe00, drawable 0x0020023e, xrender_format 0x48114e0

In _cairo_xlib_surface_ensure_dst_picture(), I added some fprintfs:

    FILE *foo;
 
    if (!surface->dst_picture) {
        foo = fopen("/tmp/gtklog", "a");
        if (foo != NULL) {
            Window root;
            int x, y;
            unsigned int xwidth, xheight, border_width, depth;
 
            fprintf(foo, "ensure_dst_picture: surface %p, dpy %p, drawable 0x%08lx, xrender_format %p\n",
                    surface, surface->dpy, surface->drawable,
                    surface->xrender_format);
            if (XGetGeometry(surface->dpy, surface->drawable,
                              &root, &x, &y, &xwidth, &xheight, &border_width,
                              &depth))
                fprintf(foo, "ensure_dst_picture: drawable depth %u\n", depth);
            fprintf(foo, "ensure_dst_picture: surface %p\n", surface);
            if (surface->xrender_format) 
                fprintf(foo, "ensure_dst_picture: xrender_format depth %d\n",
                        surface->xrender_format->depth);
            fclose(foo);
        }
        surface->dst_picture = XRenderCreatePicture (surface->dpy,
                                                     surface->drawable,
                                                     surface->xrender_format,
                                                     0, NULL);
        _cairo_xlib_surface_set_picture_clip_rects (surface);
    } else if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE)
        _cairo_xlib_surface_set_picture_clip_rects (surface);

and it printed

  ensure_dst_picture: surface 0x69d1af0, dpy 0x480fe00, drawable 0x0020023e, xrender_format 0x48114e0
  ensure_dst_picture: drawable depth 24
  ensure_dst_picture: xrender_format depth 24

In the X server, I put in code to log information when the CreatePicture op failed, and it printed

   ProcRenderCreatePicture: BadMatch due to pformat(id 0x0000002c, format 0x00020888)->depth (24) != pDrawable(id 0x0020023e)->depth (32)

so I see a bit of a disagreement between Cairo and the X server about the depth of the drawable.

Am I missing something?

Comment 4 Guy Harris 2007-10-31 16:50:16 UTC
From some debugging code I added to the server, it looks as if the depth of the drawable is somehow getting changed from 24 to 32.  If so, this is probably an X server bug (which is already in the Apple bug database).  If it gets figured out, I'll close this as NOTOURBUG.
Comment 5 Ben Byer 2007-11-02 16:18:51 UTC
Looks like it is Xquartz's fault, after all:

http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commit;h=d2766aeb85cdd80448d5fe4e1aa48e631fff6abc
Comment 6 Guy Harris 2007-11-03 11:31:54 UTC
Yup.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.