Bug#423485: xserver-xorg-video-savage: pScrn->currentMode is set to NULL
Package: xserver-xorg-video-savage
Version: 1:2.1.2+git20070512-0.1debug
Followup-For: Bug #423485
Playing around with gdb, I see that pScrn-currentMode has been set to
NULL by xf86VidMode. If I manually set it to pScrn->modes:
(gdb) set pScrn->currentMode = pScrn->modes
the program will start and seems to run normally.
AFAICS the problem is that xf86VidMode sets it intentionally to NULL
before calling xf86SwitchMode, and that it's then used as a
pointer by SavageDoAdjustFrame inside the xf86SwitchMode call.
See the attachment for the gdb debug session.
1. At the time of the crash:
(gdb) print pScrn->currentMode
$1 = (DisplayModePtr) 0x0
(gdb) print pScrn->modes
$2 = (DisplayModePtr) 0x820a3a0
(gdb) print *pScrn
$3 = {driverVersion = 33619970, driverName = 0xb7bb15f0 "savage",
pScreen = 0x820ac30, scrnIndex = 0, configured = 1, origIndex = 0,
imageByteOrder = 0, bitmapScanlineUnit = 32, bitmapScanlinePad = 32,
bitmapBitOrder = 0, numFormats = 0, formats = {{depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}, {depth = 0 '\0',
bitsPerPixel = 0 '\0', scanlinePad = 0 '\0'}}, fbFormat = {
depth = 16 '\020', bitsPerPixel = 16 '\020', scanlinePad = 32 ' '},
bitsPerPixel = 16, pixmap24 = Pix24DontCare, depth = 16,
depthFrom = X_CONFIG, bitsPerPixelFrom = X_PROBED, weight = {red = 5,
green = 6, blue = 5}, mask = {red = 63488, green = 2016, blue = 31},
offset = {red = 11, green = 5, blue = 0}, rgbBits = 6, gamma = {red = 1,
green = 1, blue = 1}, defaultVisual = 4, maxHValue = 16384,
maxVValue = 2048, virtualX = 1024, virtualY = 768, xInc = 8,
virtualFrom = X_PROBED, displayWidth = 1024, frameX0 = 0, frameY0 = 0,
frameX1 = 1023, frameY1 = 767, zoomLocked = 0, modePool = 0x0,
modes = 0x820a3a0, currentMode = 0x0, confScreen = 0x81f8a90,
monitor = 0x81f8ac8, display = 0x81fe7a0, entityList = 0x8207808,
numEntities = 1, widthmm = 0, heightmm = 0, xDpi = 96, yDpi = 96,
name = 0xb7bb1eba "SAVAGE", driverPrivate = 0x8208f80, privates = 0x8206970,
drv = 0x8206948, module = 0x8208270, colorKey = 0, overlayFlags = 0,
chipset = 0xb7bb172e "Twister", ramdac = 0x0, clockchip = 0x0,
progClock = 1, numClocks = 0, clock = {0 <repeats 128 times>},
videoRam = 16384, biosBase = 0, memPhysBase = 3893362688, fbOffset = 0,
domainIOBase = 0, memClk = 0, textClockFreq = 0, flipPixels = 0,
options = 0x8207dc8, chipID = 0, chipRev = 0, racMemFlags = 0,
racIoFlags = 0, access = 0x8206150, CurrentAccess = 0x81e8778,
resourceType = MEM_IO, busAccess = 0x8207c58, vtSema = 1, pixmapPrivate = {
ptr = 0x0, val = 0, uval = 0, fptr = 0}, silkenMouse = 0,
clockRanges = 0x8209830, adjustFlags = 1, reservedInt = {
0 <repeats 16 times>}, entityInstanceList = 0x8207d18, reservedPtr = {
0x0 <repeats 15 times>}, Probe = 0xb7b98910 <SavageProbe>,
PreInit = 0xb7b991a1 <SavagePreInit>,
ScreenInit = 0xb7b9f70b <SavageScreenInit>,
SwitchMode = 0x80ca730 <CMapSwitchMode>,
AdjustFrame = 0x80d7140 <xf86XVAdjustFrame>,
EnterVT = 0xb7c1fc40 <glxDRIEnterVT>, LeaveVT = 0xb7c1fbe0 <glxDRILeaveVT>,
FreeScreen = 0, ValidMode = 0xb7ba08e5 <SavageValidMode>,
EnableDisableFBAccess = 0x80f85d0 <xf86CursorEnableDisableFBAccess>,
SetDGAMode = 0x80cb940 <CMapSetDGAMode>,
ChangeGamma = 0x80cb4c0 <CMapChangeGamma>,
PointerMoved = 0x80be320 <xf86PointerMoved>, PMEvent = 0, HandleMessage = 0,
DPMSSet = 0xb7ba2f8f <SavageDPMS>,
LoadPalette = 0xb7ba20e5 <SavageLoadPalette>, SetOverscan = 0,
DriverFunc = 0, reservedFuncs = {0 <repeats 11 times>}}
2. If I set a breakpoint and set the currentMode manually
(gdb) set pScrn->currentMode = pScrn->modes
before entering SavageDoAdjustFrame, the program runs.
3. Here I look at currentMode before starting the program and set
a watchpoint to find out where it is being changed.
(gdb) print xf86Screens[0]->currentMode
$5 = (DisplayModePtr) 0x820a3a0
(gdb) print *xf86Screens[0]->currentMode
$6 = {prev = 0x820a900, next = 0x820a440, name = 0x8209dc8 "1024x768",
status = MODE_OK, type = 48, Clock = 65000, HDisplay = 1024,
HSyncStart = 1048, HSyncEnd = 1184, HTotal = 1344, HSkew = 0,
VDisplay = 768, VSyncStart = 771, VSyncEnd = 777, VTotal = 806, VScan = 0,
Flags = 10, ClockIndex = -1, SynthClock = 65000, CrtcHDisplay = 1024,
CrtcHBlankStart = 1024, CrtcHSyncStart = 1048, CrtcHSyncEnd = 1184,
CrtcHBlankEnd = 1344, CrtcHTotal = 1344, CrtcHSkew = 0, CrtcVDisplay = 768,
CrtcVBlankStart = 768, CrtcVSyncStart = 771, CrtcVSyncEnd = 777,
CrtcVBlankEnd = 806, CrtcVTotal = 806, CrtcHAdjusted = 0, CrtcVAdjusted = 0,
PrivSize = 0, Private = 0x0, PrivFlags = 21168449, HSync = 48.3630943,
VRefresh = 60.0038414}
(gdb) watch xf86Screens[0].currentMode
Hardware watchpoint 2: xf86Screens[0].currentMode
(gdb) cont
Continuing.
[Switching to Thread -1211197760 (LWP 3203)]
Hardware watchpoint 2: xf86Screens[0].currentMode
Old value = (DisplayModePtr) 0x820a3a0
New value = (DisplayModePtr) 0x0
VidModeSwitchMode (scrnIndex=0, mode=0x820a590)
at ../../../../hw/xfree86/common/xf86VidMode.c:372
372 ../../../../hw/xfree86/common/xf86VidMode.c: No such file or directory.
in ../../../../hw/xfree86/common/xf86VidMode.c
>From xf86VidMode:
370 /* Force a mode switch */
371 pScrn->currentMode = NULL;
372 retval = xf86SwitchMode(pScrn->pScreen, mode);
373 /* we failed: restore it */
374 if (retval == FALSE)
Obviously it sets currentMode to NULL intentionally. The problem is that currentMode will be used by SavageDoAdjustFrame inside the xf86SwitchMode call.
Reply to: