[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#688082: New testcase and further analysis



I've poked around some more and attached a testcase to reproduce this crash
without needing Iceweasel.  It looks to me like the codepath leading up to the
crash only occurs on NV04 chips, and the actual segfault happens in
drm_nouveau/pushbuf.c:pushbuf_krel - the function uses the return value
of cli_kref_get without checking for null returns, and cli_kref_get returns
NULL if it can't find the kref it's looking for.
#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>

void gradient_fill(Display *g_display, Drawable drawable, GC gc)
{
    int r;
    int g = 0;
    while (g<3072) {
        r = 0;
        while (r<3571) {
            XSetForeground(g_display, gc, ((r&0xff)<<24)+((g&0xff)<<16)+0xffff);
            XFillRectangle(g_display, drawable, gc, g, r, 16, 1);
            r+=10;
        }
        g+=8;
    }
}

int main (int argc, char **argv)
{
    Display *g_display = XOpenDisplay(NULL);
    if (!g_display) {
        printf("Error initializing display.\n");
        exit(1);
    }
    int major_opcode, first_event, first_error;
    if (XQueryExtension(g_display, "BIG-REQUESTS", &major_opcode, &first_event, &first_error)) {
        printf("Big requests.\n");
    } else {
        printf("No big requests.\n");
    }
    int g_screen = DefaultScreen(g_display);
    Window g_rootwin = RootWindow(g_display, g_screen);
    static XSetWindowAttributes attribs;
    Window g_win = XCreateWindow(g_display, g_rootwin, 0, 0, 1024, 900,
        0, CopyFromParent, InputOutput, CopyFromParent, 0, &attribs);
    XMapRaised(g_display, g_win);
    XEvent ev;
    static XGCValues gcvalues;
    GC gc = XCreateGC(g_display, g_win, 0, &gcvalues);
    XSetForeground(g_display, gc, 0xff8000ff);
    Pixmap small = XCreatePixmap(g_display, g_win, 100,100,24);
    XFillRectangle(g_display, small, gc, 0, 0, 50, 100);
    XFlush(g_display);
    XCopyArea(g_display, small, g_win, gc, 0, 0, 100, 100,  100, 100);
    XFlush(g_display);
    Pixmap huge = XCreatePixmap(g_display, g_win, 3072, 3571, 24);
    gradient_fill(g_display, huge, gc);
    //XFillRectangle(g_display, huge, gc,  0,0,3072,3571);
    // does not crash: XCopyArea(g_display, huge, g_win, gc, 0, 0, 100, 100, 200, 100);
    gcvalues.subwindow_mode = IncludeInferiors;
    XChangeGC(g_display, gc, GCSubwindowMode, &gcvalues);
    XCopyArea(g_display, huge, g_win, gc, 0, 0, 1033, 937,8,27);
    while (1) {
        while (XPending(g_display)) {
            XNextEvent(g_display,&ev);
        }
    }
}

Reply to: