Server crash uploading multiple glyphs at once with XRenderAddGlyphs
Clemens Eisserer
linuxhippy at gmail.com
Sun Aug 16 15:59:51 PDT 2009
Hi Dave,
> Can you get valgrind traces by any chance? not sure we can tell
> much other than memory got corrupted from this.
It seems at least for this case, sha1_block_data_order is reading data
from random locations:
==17163== Invalid read of size 4
==17163== at 0x439E91A: sha1_block_data_order (sx86-elf.s:76)
==17163== by 0xFA42F463: ???
==17163== Address 0x4815360 is 0 bytes after a block of size 4,096 alloc'd
==17163== at 0x4028D7E: malloc (vg_replace_malloc.c:207)
==17163== by 0x80AE954: Xalloc (utils.c:1056)
==17163== by 0x80AA42D: AllocateInputBuffer (io.c:1017)
==17163== by 0x80A9545: InsertFakeRequest (io.c:498)
I had a look at the source but I have a pretty hard time figuring out
whats going on there :-/
The crash appears with a quite large framework I am working on, quite
hard to build your own. I could provide a binary package or wireshark
protocol if that would help?
The valgrind log is attached, hope it helps a bit.
Thanks, Clemens
PS: I've found another problem when uploading multiple glyphs at once
causes a memleak. I've attached a short testcase - fills up my 3GB
pretty quick.
There's a malloc in CreatePicture which is in some cases never freed,
called at render.c : 1147.
But again, I don't understand why it works sometimes and sometimes not :-/
-------------- next part --------------
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
#include <stdlib.h>
Display *display;
int screen;
Window root, window;
XEvent event;
char* alphaData;
XRenderPictFormat *fmt_a8;
GlyphSet gs12a8;
Picture sourcePicture;
Picture picture;
#define GLYPH_SIZE 96
#define GLYPH_BATCH 5
void memleak() {
XGlyphInfo xginfo[GLYPH_BATCH];
Glyph gid[GLYPH_BATCH];
int i=0;
for(; i < GLYPH_BATCH; i++) {
gid[i] = i + 100;
xginfo[i].width = GLYPH_SIZE;
xginfo[i].height = GLYPH_SIZE;
xginfo[i].x = 0;
xginfo[i].y = 0;
xginfo[i].xOff = GLYPH_SIZE;
xginfo[i].yOff = 0;
}
XRenderAddGlyphs(display, gs12a8, &gid[0], &xginfo[0], GLYPH_BATCH, alphaData, GLYPH_SIZE*GLYPH_SIZE*GLYPH_BATCH);
XGlyphElt32 elt = {.glyphset=gs12a8, .chars= (unsigned int*) &gid, GLYPH_BATCH, GLYPH_SIZE, GLYPH_SIZE};
XRenderCompositeText32 (display, PictOpOver, sourcePicture, picture, fmt_a8, 0, 0, GLYPH_SIZE, GLYPH_SIZE, &elt, 1);
XRenderFreeGlyphs (display, gs12a8, &gid[0], GLYPH_BATCH);
}
Picture create_pen(int red, int green, int blue, int alpha, int width, int height, int depth, char* sm)
{
XRenderColor color={.red=red, .green=green, .blue=blue, .alpha=alpha};
XRenderPictFormat *fmt;
if(depth == 24) {
fmt = XRenderFindStandardFormat(display, PictStandardRGB24);
}else {
fmt = XRenderFindStandardFormat(display, PictStandardARGB32);
}
Pixmap pm = XCreatePixmap(display, window, width, height, depth);
XRenderPictureAttributes pict_attr;
pict_attr.repeat=RepeatNormal;
Picture picture = XRenderCreatePicture(display, pm, fmt, CPRepeat, &pict_attr);
XRenderFillRectangle(display, PictOpSrc, picture, &color, 0, 0, width, height);
return picture;
}
int main(int argc, char *argv[])
{
alphaData = malloc(1024*1024);
//Open display and check that it actually opens
display=XOpenDisplay(NULL);
if ( display == NULL ) {
printf("Unable to open display, is X running? Set DISPLAY enviorment variable.\n");
return 1;
}
int render_event_base, render_error_base;
int render_present=XRenderQueryExtension(display, &render_event_base, &render_error_base);
if (!render_present) {
fprintf(stderr, "RENDER extension missing!\n");
abort();
}
//Check version of xrender extension, v0.10 is needed.
int render_version_major, render_version_minor;
if ( XRenderQueryVersion(display, &render_version_major, &render_version_minor) != 0 ) {
if( render_version_minor < 10 ){
printf("RENDER Version %d.%d is too old! Requires 0.10\n",render_version_major,render_version_minor);
return 1;
}
}else{
return 1;
abort();
}
/* obtain a few parameters */
XRenderPictFormat *fmt=XRenderFindStandardFormat(display, PictStandardRGB24);
screen=DefaultScreen(display);
root=DefaultRootWindow(display);
/* create window and all related resources */
window = XCreateWindow(display, root, 0, 0, 640, 480, 0,
DefaultDepth(display, screen), InputOutput,
DefaultVisual(display, screen),
0, NULL);
XRenderPictureAttributes pict_attr;
picture=XRenderCreatePicture(display, window, fmt, 0, &pict_attr);
XSelectInput(display, window, KeyPressMask|KeyReleaseMask|ExposureMask
|ButtonPressMask|StructureNotifyMask);
sourcePicture = create_pen(0,0,0xffff,0xdfff, 1, 1, 32, NULL);
/* now make the window visible */
XMapWindow(display, window);
fmt_a8 = XRenderFindStandardFormat(display, PictStandardA8);
gs12a8 = XRenderCreateGlyphSet(display, fmt_a8);
while(1) {
XNextEvent(display, &event);
switch(event.type) {
case Expose:
{
while(1) {
memleak();
}
}
break;
case DestroyNotify:
return 0;
}
}
return 0;
}
/* XGlyphInfo xginfo[GLYPH_BATCH];
Glyph gid[GLYPH_BATCH];
int i=0;
for(; i < GLYPH_BATCH; i++) {
gid[i] = i + 100;
xginfo[i].width = area;
xginfo[i].height = area;
xginfo[i].x = 0;
xginfo[i].y = 0;
xginfo[i].xOff = area;
xginfo[i].yOff = 0;
}
XRenderAddGlyphs(display, gs12a8, &gid[0], &xginfo[0], GLYPH_BATCH, alphaData, area*area*GLYPH_BATCH);
XGlyphElt32 elt = {.glyphset=gs12a8, .chars= (unsigned int*) &gid, GLYPH_BATCH, area, area};
XRenderCompositeText32 (display, PictOpOver, sourcePicture, backBuffer, fmt_a8, 0, 0, 100, 100, &elt, 1);
XRenderFreeGlyphs (display, gs12a8, &gid[0], GLYPH_BATCH);*/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: xorg_valgrind_log_short.txt.bz2
Type: application/x-bzip2
Size: 11505 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg/attachments/20090816/9441ff1a/attachment.bin>
More information about the xorg
mailing list