retitle 283127 xserver-xfree86: [ati/radeon] SEGV in fbBlt() during large pixmap allocation on unknown chipset (0x5964) rev 1 (RV280 [Radeon 9200 SE])
tag 283127 = upstream help
thanks
On Sun, Dec 19, 2004 at 05:22:55PM +0200, Sami Liedes wrote:
> I've tried to start the server in 3 different ways:
>
> 1. As a normal user using the command "X"
> 2. As a normal user using the command "startx $(which x-terminal-emulator)"
> 3. As root using the command "startx $(which x-terminal-emulator)"
>
> Of these, #1 and #3 crash when I run the gv client, #2 doesn't (after
> a few tries, anyway; #1 and #3 seem to crash always).
>
> #3 indeed produces a core file in /etc/X11/, after which it goes into
> some kind of an endless loop (after printing "When reporting a server
> crash..."), eating all CPU it gets and unable to be killed even with
> -KILL. #1 doesn't go into an endless loop, but doesn't produce a core
> file either.
Given where you're seeing the SEGV, that there is any difference in the
above baffles me.
> Unfortunately gdb doesn't seem able to give useful information:
[...]
> However I tried to attach to a running X process and was able to get
> the following backtrace (running the crash-provoking client
> immediately after issuing the first 'cont' command):
[...]
> Program received signal SIGSEGV, Segmentation fault.
> 0x0853ba9a in fbBlt (srcLine=0x23f2762c, srcStride=21641, srcX=0,
> dstLine=0xbffff4fc, dstStride=21641, dstX=0, width=692512, height=0,
> alu=3, pm=16777215, bpp=32, reverse=0, upsidedown=0) at fbblt.c:180
> 180 fbblt.c: No such file or directory.
> in fbblt.c
> (gdb) bt
> #0 0x0853ba9a in fbBlt (srcLine=0x23f2762c, srcStride=21641, srcX=0,
> dstLine=0xbffff4fc, dstStride=21641, dstX=0, width=692512, height=0,
> alu=3, pm=16777215, bpp=32, reverse=0, upsidedown=0) at fbblt.c:180
[...]
> (gdb) bt full
> #0 0x0853ba9a in fbBlt (srcLine=0x23f2762c, srcStride=21641, srcX=0,
> dstLine=0xbffff4fc, dstStride=21641, dstX=0, width=692512, height=0,
> alu=3, pm=16777215, bpp=32, reverse=0, upsidedown=0) at fbblt.c:180
> src = (FbBits *) 0x23f1240c
> dst = (FbBits *) 0xbffea2d8
> leftShift = 0
> rightShift = 0
> startmask = 0
> endmask = 0
> bits = 0
> bits1 = 0
> n = 21640
> nmiddle = 21641
> destInvarient = 0
> startbyte = 0
> endbyte = 0
> _ca1 = 0
> _cx1 = 4278190080
> _ca2 = 16777215
> _cx2 = 0
[...]
> Hope this information helps. If there's still something I can do to
> gather more information, I'll be happy to.
Excellent. Thank you very much for this detailed followup!
Let's have a look at that fbBlt function. This is a long paste. I have
some comments inlined after line number 180, and then at the very end.
40 void
41 fbBlt (FbBits *srcLine,
42 FbStride srcStride,
43 int srcX,
44
45 FbBits *dstLine,
46 FbStride dstStride,
47 int dstX,
48
49 int width,
50 int height,
51
52 int alu,
53 FbBits pm,
54 int bpp,
55
56 Bool reverse,
57 Bool upsidedown)
58 {
59 FbBits *src, *dst;
60 int leftShift, rightShift;
61 FbBits startmask, endmask;
62 FbBits bits, bits1;
63 int n, nmiddle;
64 Bool destInvarient;
65 int startbyte, endbyte;
66 FbDeclareMergeRop ();
67
68 #ifdef FB_24BIT
69 if (bpp == 24 && !FbCheck24Pix (pm))
70 {
71 fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
72 width, height, alu, pm, reverse, upsidedown);
73 return;
74 }
75 #endif
76 FbInitializeMergeRop(alu, pm);
77 destInvarient = FbDestInvarientMergeRop();
78 if (upsidedown)
79 {
80 srcLine += (height - 1) * (srcStride);
81 dstLine += (height - 1) * (dstStride);
82 srcStride = -srcStride;
83 dstStride = -dstStride;
84 }
85 FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
86 nmiddle, endmask, endbyte);
87 if (reverse)
88 {
89 srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
90 dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
91 srcX = (srcX + width - 1) & FB_MASK;
92 dstX = (dstX + width - 1) & FB_MASK;
93 }
94 else
95 {
96 srcLine += srcX >> FB_SHIFT;
97 dstLine += dstX >> FB_SHIFT;
98 srcX &= FB_MASK;
99 dstX &= FB_MASK;
100 }
101 if (srcX == dstX)
102 {
103 while (height--)
104 {
105 src = srcLine;
106 srcLine += srcStride;
107 dst = dstLine;
108 dstLine += dstStride;
109 if (reverse)
110 {
111 if (endmask)
112 {
113 bits = *--src;
114 --dst;
115 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
116 }
117 n = nmiddle;
118 if (destInvarient)
119 {
120 while (n--)
121 *--dst = FbDoDestInvarientMergeRop(*--src);
122 }
123 else
124 {
125 while (n--)
126 {
127 bits = *--src;
128 --dst;
129 *dst = FbDoMergeRop (bits, *dst);
130 }
131 }
132 if (startmask)
133 {
134 bits = *--src;
135 --dst;
136 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
137 }
138 }
139 else
140 {
141 if (startmask)
142 {
143 bits = *src++;
144 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
145 dst++;
146 }
147 n = nmiddle;
148 if (destInvarient)
149 {
150 #if 0
151 /*
152 * This provides some speedup on screen->screen blts
153 * over the PCI bus, usually about 10%. But fb
154 * isn't usually used for this operation...
155 */
156 if (_ca2 + 1 == 0 && _cx2 == 0)
157 {
158 FbBits t1, t2, t3, t4;
159 while (n >= 4)
160 {
161 t1 = *src++;
162 t2 = *src++;
163 t3 = *src++;
164 t4 = *src++;
165 *dst++ = t1;
166 *dst++ = t2;
167 *dst++ = t3;
168 *dst++ = t4;
169 n -= 4;
170 }
171 }
172 #endif
173 while (n--)
174 *dst++ = FbDoDestInvarientMergeRop(*src++);
175 }
176 else
177 {
178 while (n--)
179 {
180 bits = *src++;
Here's where we SEGVd.
Looks like we walked off the end of the src FbBits array.
> src = (FbBits *) 0x23f1240c
The actual problem is probably higher up in the call stack, but I am
distressed that I see no assert()s in this code, which relies so heavily on
externally-supplied values, and which ends up at the bottom of tall call
stacks.
If this code were commented, I might better understand what "n" and
"nmiddle" are. :-/
> n = 21640
> nmiddle = 21641
It strikes me as suspicious that the SEGV occurs when n has just been
decremented below value of nmiddle. But since I do not understand the
code, I don't know if that is significant.
181 *dst = FbDoMergeRop (bits, *dst);
182 dst++;
183 }
184 }
185 if (endmask)
186 {
187 bits = *src;
188 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
189 }
190 }
191 }
192 }
193 else
194 {
195 if (srcX > dstX)
196 {
197 leftShift = srcX - dstX;
198 rightShift = FB_UNIT - leftShift;
199 }
200 else
201 {
202 rightShift = dstX - srcX;
203 leftShift = FB_UNIT - rightShift;
204 }
205 while (height--)
206 {
207 src = srcLine;
208 srcLine += srcStride;
209 dst = dstLine;
210 dstLine += dstStride;
211
212 bits1 = 0;
213 if (reverse)
214 {
215 if (srcX < dstX)
216 bits1 = *--src;
217 if (endmask)
218 {
219 bits = FbScrRight(bits1, rightShift);
220 if (FbScrRight(endmask, leftShift))
221 {
222 bits1 = *--src;
223 bits |= FbScrLeft(bits1, leftShift);
224 }
225 --dst;
226 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
227 }
228 n = nmiddle;
229 if (destInvarient)
230 {
231 while (n--)
232 {
233 bits = FbScrRight(bits1, rightShift);
234 bits1 = *--src;
235 bits |= FbScrLeft(bits1, leftShift);
236 --dst;
237 *dst = FbDoDestInvarientMergeRop(bits);
238 }
239 }
240 else
241 {
242 while (n--)
243 {
244 bits = FbScrRight(bits1, rightShift);
245 bits1 = *--src;
246 bits |= FbScrLeft(bits1, leftShift);
247 --dst;
248 *dst = FbDoMergeRop(bits, *dst);
249 }
250 }
251 if (startmask)
252 {
253 bits = FbScrRight(bits1, rightShift);
254 if (FbScrRight(startmask, leftShift))
255 {
256 bits1 = *--src;
257 bits |= FbScrLeft(bits1, leftShift);
258 }
259 --dst;
260 FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
261 }
262 }
263 else
264 {
265 if (srcX > dstX)
266 bits1 = *src++;
267 if (startmask)
268 {
269 bits = FbScrLeft(bits1, leftShift);
270 bits1 = *src++;
271 bits |= FbScrRight(bits1, rightShift);
272 FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
273 dst++;
274 }
275 n = nmiddle;
276 if (destInvarient)
277 {
278 while (n--)
279 {
280 bits = FbScrLeft(bits1, leftShift);
281 bits1 = *src++;
282 bits |= FbScrRight(bits1, rightShift);
283 *dst = FbDoDestInvarientMergeRop(bits);
284 dst++;
285 }
286 }
287 else
288 {
289 while (n--)
290 {
291 bits = FbScrLeft(bits1, leftShift);
292 bits1 = *src++;
293 bits |= FbScrRight(bits1, rightShift);
294 *dst = FbDoMergeRop(bits, *dst);
295 dst++;
296 }
297 }
298 if (endmask)
299 {
300 bits = FbScrLeft(bits1, leftShift);
301 if (FbScrLeft(endmask, rightShift))
302 {
303 bits1 = *src;
304 bits |= FbScrRight(bits1, rightShift);
305 }
306 FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
307 }
308 }
309 }
310 }
311 }
I don't have time to dig into this further right at the moment, but if
someone would like to help chase this down, that would be great.
--
G. Branden Robinson | You don't just decide to break
Debian GNU/Linux | Kubrick's code of silence and then
branden@debian.org | get drawn away from it to a
http://people.debian.org/~branden/ | discussion about cough medicine.
Attachment:
signature.asc
Description: Digital signature