Server crash uploading multiple glyphs at once with XRenderAddGlyphs

Clemens Eisserer linuxhippy at
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;
	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	
  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");
        //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;
                return 1;

	/* obtain a few parameters */
	XRenderPictFormat *fmt=XRenderFindStandardFormat(display, PictStandardRGB24);
	/* 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

	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) {
			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: <>

More information about the xorg mailing list