I've come across what appears to be a bug in X.Org's implementation of XDrawLines(), which results in a server crash. It seems related to the cap style and join style that is used, since changing it to the join style to JoinMiter and cap style to CapButt makes it works as expected.
The following code can be used to reproduce the crash:
int pen_width = 50;
vals.line_width = pen_width;
vals.line_style = LineOnOffDash;
vals.join_style = JoinBevel;
vals.cap_style = CapProjecting;
GC gc = XCreateGC(dpy, drawable,
GCLineWidth | GCLineStyle
| GCJoinStyle | GCCapStyle, &vals);
int dash_len = 2;
dashes = pen_width*4;
dashes = pen_width*2;
XSetDashes(dpy, gc, 0, dashes, dash_len);
points.x = 141; points.y = 40;
points.x = 488; points.y = -160;
points.x = 638; points.y = 100;
points.x = 291; points.y = 300;
points.x = 141; points.y = 40;
XDrawLines(dpy, drawable, gc, points, 5, CoordModeOrigin);
Verified with git master, see backtrace:
Program received signal SIGABRT, Aborted.
[Switching to Thread -1208375616 (LWP 26833)]
0x00110402 in __kernel_vsyscall ()
#0 0x00110402 in __kernel_vsyscall ()
#1 0x00ba7690 in raise () from /lib/libc.so.6
#2 0x00ba8f91 in abort () from /lib/libc.so.6
#3 0x00bdf9eb in __libc_message () from /lib/libc.so.6
#4 0x00be7ac1 in _int_free () from /lib/libc.so.6
#5 0x00beb0f0 in free () from /lib/libc.so.6
#6 0x08166b40 in Xfree (ptr=0x9e87670) at utils.c:1422
#7 0x0814fa92 in miFillPolyHelper (pDrawable=0x9f2f800, pGC=0x9f2f5d0,
pixel=0, spanData=0x0, y=74, overall_height=31, left=0xbffa6ad8,
right=0xbffa6abc, left_count=1, right_count=0) at miwideline.c:170
#8 0x08152705 in miLineProjectingCap (pDrawable=0x9f2f800, pGC=0x9f2f5d0,
pixel=0, spanData=0x0, face=0xbffa6c08, isLeft=1, xorg=0, yorg=0, isInt=1)
#9 0x08154b75 in miWideDash (pDrawable=0x9f2f800, pGC=0x9f2f5d0, mode=0,
npt=1, pPts=0x9f0f2dc) at miwideline.c:2174
#10 0x003e4bda in fbPolyLine (pDrawable=0x9f2f800, pGC=0x9f2f5d0, mode=0,
npt=5, ppt=0x9f0f2cc) at fbline.c:140
#11 0x002c3794 in ExaCheckPolylines (pDrawable=0x9f2f800, pGC=0x9f2f5d0,
mode=0, npt=5, ppt=0x9f0f2cc) at exa_unaccel.c:176
#12 0x002ba28d in exaPolylines (pDrawable=0x9f2f800, pGC=0x9f2f5d0, mode=0,
npt=5, ppt=0x9f0f2cc) at exa_accel.c:685
#13 0x081bbfe1 in damagePolylines (pDrawable=0x9f2f800, pGC=0x9f2f5d0, mode=0,
npt=5, ppt=0x9f0f2cc) at damage.c:993
---Type <return> to continue, or q <return> to quit---
#14 0x0808a018 in ProcPolyLine (client=0x9f3bff0) at dispatch.c:1676
#15 0x08086bd6 in Dispatch () at dispatch.c:448
#16 0x0806cb64 in main (argc=8, argv=0xbffa6f84, envp=0xbffa6fa8) at main.c:415
Created attachment 16762 [details]
test program that causes crash
Trond's code as a compile-able c file.
on crash miFillPolyHelper() is called from miLineProjectingCap() with the following parameters:
left count: 2
right count: 2
The error is in negative lefts.height and wrong overall_height.
miLineProjectingCap() runs with
There was a similar bug when dx=0, dy<0 led to a negative heigth:
Not sure I understand all the intricacies of these algorithms,
but it seems to me that the following patch is correct.
Created attachment 32284 [details] [review]
Tagging patch; will triage later.
i don't see issuing a patch if you don't know the inners of the algorithm
also what is "git(1) verified" ? never heard of it, is it any good ?
what i see is free() crashing
that means a memory address of the ptr that was freed which was not the same addres the original address that was allocated, or that the chain (the btree) of allocatons on the heap conflict (ie, maybe address wasn't in btree, or duplicate, etc). ie, one cannot have alloc(ptr1); ptr2=ptr1; free(ptr2); seg faults.
it "should be true" that X server checks all X client requests are reasonable, ie, that any bogus pointers passed to X server are good. however if X server ran lint on every ptr and graphics call - it'd be mighty slow.
perhaps let's look further into this and first determine if this is a seg fault
i dont' see here you saying if X server or X client crashed
i'm preeety sure than anything emulating hardware by drawing lines (noting good hw accel cards have postscript curve code in silicon). that's all on X client side. server side is where harware calls are made once client makes up it's mind what it has to say.
your code does not show where dpy is from or whether it's ok to free
i'm unsure if dpy is not conditional upon success, or if you are supposed to call client or server or test dpy before freeing. sorry i couldn't be more help.
now are you SURE there aren't applications using Drawlines out there actually working which do not have this bug, that it really applies to X and not just your test ?
have fun ! jh
> git(1) verified" ? never heard of it
$ man git
git - the stupid content tracker
> i dont' see here you saying if X server or X client crashed
I guess this should be clear from the title or the trace log. Server crashes.
-- GitLab Migration Automatic Message --
This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.
You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/xorg/xserver/issues/370.