Comment 1 for bug 531719

Revision history for this message
In , Karlt (karlt) wrote :

The cairo surface being destroyed is using the window for the drawable, and is
releasing the dst_picture

http://hg.mozilla.org/mozilla-central/annotate/4046f3843bdb/gfx/cairo/cairo/src/cairo-xlib-surface.c#l296

(gdb) f 6
#6 0x00007f8fc6d8a2c2 in _cairo_xlib_surface_finish (
    abstract_surface=0x7f8f8ee56400)
    at /home/karl/moz/dev/gfx/cairo/cairo/src/cairo-xlib-surface.c:341
(gdb) p *surface
$376 = {base = {backend = 0x7f8fc70987e0, type = CAIRO_SURFACE_TYPE_XLIB,
    content = CAIRO_CONTENT_COLOR, ref_count = {ref_count = 0},
    status = CAIRO_STATUS_SUCCESS, finished = 0, user_data = {size = 1,
      num_elements = 1, element_size = 24, elements = 0x7f8f8eee7438,
      is_snapshot = 0}, mime_data = {size = 0, num_elements = 0,
      element_size = 24, elements = 0x0, is_snapshot = 0},
    device_transform = {xx = 1, yx = 0, xy = 0, yy = 1, x0 = 0, y0 = 0},
    device_transform_inverse = {xx = 1, yx = 0, xy = 0, yy = 1, x0 = -0,
      y0 = -0}, x_resolution = 72, y_resolution = 72,
    x_fallback_resolution = 300, y_fallback_resolution = 300,
    clip = 0x7f8f8f0d9260, next_clip_serial = 1, current_clip_serial = 1,
    is_snapshot = 0, has_font_options = 0, font_options = {
      antialias = 2779096485, subpixel_order = 2779096485,
      hint_style = 2779096485, hint_metrics = 2779096485}},
  dpy = 0x7f8fcd151000, display = 0x7f8fac641c10,
  screen_info = 0x7f8fac6163d0, close_display_hook = {prev = 0x7f8f9bfdb520,
    next = 0x7f8f8ed5cd20,
    func = 0x7f8fc6d8f5f2 <_cairo_xlib_surface_detach_display>},
  gc = 0x7f8f8ef0ea60, drawable = 44044608, screen = 0x7f8fcd139180,
  owns_pixmap = 0, visual = 0x7f8fcd11f470, use_pixmap = 0, render_major = 0,
  render_minor = 10, buggy_repeat = 0, width = 1069, height = 619,
  depth = 24, dst_picture = 44045647, src_picture = 0, clip_dirty = 0,
  have_clip_rects = 0, gc_has_clip_rects = 0, embedded_clip_rects = {{x = 0,
      y = 0, width = 1069, height = 619}, {x = -23131, y = -23131,
      width = 42405, height = 42405}, {x = -23131, y = -23131, width = 42405,
      height = 42405}, {x = -23131, y = -23131, width = 42405,
      height = 42405}, {x = -23131, y = -23131, width = 42405,
      height = 42405}, {x = -23131, y = -23131, width = 42405,
      height = 42405}, {x = -23131, y = -23131, width = 42405,
      height = 42405}, {x = -23131, y = -23131, width = 42405,
      height = 42405}}, clip_rects = 0x7f8f8ee5659c, num_clip_rects = 0,
  xrender_format = 0x7f8fcd0fc940, filter = CAIRO_FILTER_NEAREST, repeat = 0,
  xtransform = {matrix = {{65536, 0, 0}, {0, 65536, 0}, {0, 0, 65536}}},
  a_mask = 0, r_mask = 16711680, g_mask = 65280, b_mask = 255}

The drawable of that surface is the Window of the nsIWidget being destroyed
but that Window has already been destroyed, probably when a parent nsIWidget
was destroyed:

http://hg.mozilla.org/mozilla-central/annotate/4046f3843bdb/widget/src/gtk2/nsWindow.cpp#l760

(gdb) f 13
#13 0x00007f8fc6311441 in nsWindow::Destroy (this=0x7f8fa9cd2ba0)
    at /home/karl/moz/dev/widget/src/gtk2/nsWindow.cpp:790
(gdb) p *(GdkWindowObject*)mGdkWindow
$386 = {parent_instance = {parent_instance = {g_type_instance = {
        g_class = 0x7f8fcd179540}, ref_count = 2, qdata = 0x7f8f8ed4a180}},
  impl = 0x7f8f8f018700, parent = 0x0, user_data = 0x0, x = 0, y = 0,
  extension_events = 0, filters = 0x0, children = 0x0, bg_color = {pixel = 0,
    red = 0, green = 0, blue = 0}, bg_pixmap = 0x2, paint_stack = 0x0,
  update_area = 0x0, update_freeze_count = 0, window_type = 2 '\002',
  depth = 24 '\030', resize_count = 0 '\0',
  state = GDK_WINDOW_STATE_WITHDRAWN, guffaw_gravity = 0, input_only = 0,
  modal_hint = 0, composited = 0, destroyed = 1, accept_focus = 1,
  focus_on_map = 1, shaped = 0, event_mask = 176910,
  update_and_descendants_freeze_count = 0, redirect = 0x0}
(gdb) p *(GdkWindowImplX11*)((GdkWindowObject*)mGdkWindow)->impl
$388 = {parent_instance = {parent_instance = {parent_instance = {
        g_type_instance = {g_class = 0x7f8fcd1798c0}, ref_count = 1,
        qdata = 0x0}}, wrapper = 0x7f8f8f018340, colormap = 0x7f8fcd139400,
    xid = 44044608, screen = 0x7f8fcd107000, picture = 0,
    cairo_surface = 0x0}, width = 1069, height = 619, position_info = {x = 0,
    y = 0, width = 1069, height = 619, x_offset = 0, y_offset = 0, big = 0,
    mapped = 1, no_bg = 0, clip_rect = {x = 0, y = 0, width = 1069,
      height = 619}}, toplevel = 0x0, cursor = 0x0,
  toplevel_window_type = -1 'ÿ', override_redirect = 0,
  use_synchronized_configure = 0, damage = 0}
(gdb) p *this
$389 = (nsChildWindow) {<nsWindow> = {<nsBaseWidget> = {<nsIWidget> = {<nsISupports> = {_vptr.nsISupports = 0x7f8fc6599730}, mFirstChild = {
          mRawPtr = 0x7f8f8ef61050}, mLastChild = 0x7f8f8ef61050,
        mNextSibling = {mRawPtr = 0x0}, mPrevSibling = 0x0}, mRefCnt = {
        mValue = 2}, _mOwningThread = {mThread = 0x7f8fcd110040},
      mClientData = 0x0, mEventCallback = 0x7f8fc7b25dea <HandleEvent>,
      mContext = 0x7f8f8ef0ef60, mToolkit = 0x7f8fb43ed400,
      mBackground = 2779096485, mForeground = 2779096485,
      mCursor = eCursor_standard, mWindowType = eWindowType_child,
      mBorderStyle = eBorderStyle_default, mOnDestroyCalled = 0 '\0',
      mBounds = {x = 0, y = 0, width = 1069, height = 619},
      mOriginalBounds = 0x0, mClipRects = {mRawPtr = 0x0},
      mClipRectCount = 0, mZIndex = 0,
      mSizeMode = nsSizeMode_Normal}, <nsSupportsWeakReference> = {<nsISupportsWeakReference> = {<nsISupports> = {
          _vptr.nsISupports = 0x7f8fc6599a68}, <No data fields>},
      mProxy = 0x0}, mOldFocusWindow = 0, mIMEData = 0x7f8fb33ab820,
    mParent = {mRawPtr = 0x0}, mIsTopLevel = 0 '\0', mIsDestroyed = 1 '\001',
    mNeedsResize = 0 '\0', mNeedsMove = 0 '\0', mListenForResizes = 1 '\001',
    mIsShown = 0 '\0', mNeedsShow = 0 '\0', mEnabled = 1 '\001',
    mCreated = 0 '\0', mPlaced = 1 '\001', mShell = 0x0, mContainer = 0x0,
    mGdkWindow = 0x7f8f8f018340, mWindowGroup = 0x0, mContainerGotFocus = 0,
    mContainerLostFocus = 0, mContainerBlockFocus = 0, mCanBeSeen = 0,
    mRetryPointerGrab = 0, mRetryKeyboardGrab = 0, mTransientParent = 0x0,
    mSizeState = 0, mPluginType = nsWindow::PluginType_NONE,
    mTransparencyBitmapWidth = 0, mTransparencyBitmapHeight = 0,
    mThebesSurface = {mRawPtr = 0x0}, mRootAccessible = {mRawPtr = 0x0},
    mIsTransparent = 0, mTransparencyBitmap = 0x0, mDragMotionWidget = 0x0,
    mDragMotionContext = 0x0, mDragMotionX = 0, mDragMotionY = 0,
    mDragMotionTime = 0, mDragMotionTimerID = 0, mDragLeaveTimer = {
      mRawPtr = 0x0}, mLastMotionPressure = 0,
    mLastSizeMode = nsSizeMode_Normal, mKeyDownFlags = {0, 0, 0, 0, 0, 0, 0,
      0}}, <No data fields>}

I suspect we might need to call Destroy() on all nsIWidgets associated with
child native windows. (Currently we only call Destroy() on the nsIWidgets in
the nsIWidget child list which is not all children of the native window.)