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