Bug 17898

Summary: crash - XRandR rotation - radeon_drv using XAA w/o DRI enabled
Product: xorg Reporter: Lee Leahu <6khRTwRnE3AB>
Component: Driver/RadeonAssignee: xf86-video-ati maintainers <xorg-driver-ati>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: 7.2 (2007.02)   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
screen shot of data for pict and pict->pDrawable
none
initialize rotate_offset when using XAA and DRI is disabled none

Description Lee Leahu 2008-10-03 22:33:02 UTC
X.org built 7.2 (without DRI support)
Gentoo OS

Kernel:  2.6.24-gentoo-r8

Video Card:  ATI Technologies Inc RV350 AP [Radeon 9600] (dual head)
Video Driver:  ati (wrapper for radeon)

1st head:  1280x1024 19" lcd panel
2nd head:  1024x768 15" lcd panel (rotated clockwise 90 degrees)

The Goal:   Rotate the display on the 15" lcd panel from a 1024x768 landscape format to a 768x1024 portrait format.


X is started using it's own auto generated run-time configuration.
 - No X config file used
 - Command Run:
     X -ac

After X is started and the displays are active (in clone mode), xrandr is run to rotate the 2nd display:

   xrandr --output DVI-0 --rotate right

X then crashes with signal 11 (segsigv / segmentation fault)

----------------------------
Program received signal SIGSEGV, Segmentation fault.
0xb7a2b508 in fbStore_x8r8g8b8 (bits=0x67540ff4, values=0xbfe78704, x=0, width=1024, indexed=0x0) at fbcompose.c:1039
1039    fbcompose.c: No such file or directory.
        in fbcompose.c
----------------------------


The bracktrace:

----------------------------
#0  0xb7a2b508 in fbStore_x8r8g8b8 (bits=0x67540ff4, values=0xbfe78704, x=0, width=1024, indexed=0x0) at fbcompose.c:1039
#1  0xb7a357a0 in fbStore (pict=0x82a0118, x=0, y=0, width=1024, buffer=0xbfe78704) at fbcompose.c:3399
#2  0xb7a35fe8 in fbCompositeRect (data=0xbfe776e4, scanline_buffer=0xbfe77704) at fbcompose.c:3554
#3  0xb7a36862 in fbCompositeGeneral (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at fbcompose.c:3657
#4  0xb7a416ba in fbComposite (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at fbpict.c:1279
#5  0xb79f00de in XAAComposite (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at xaaPict.c:545
#6  0x081c18d5 in damageComposite (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at damage.c:576
#7  0x081a4186 in CompositePicture (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at picture.c:1795
#8  0x08125841 in xf86RotateCrtcRedisplay (crtc=0x829b8f0, region=0xbfe7db94) at xf86Rotate.c:208
#9  0x08125c43 in xf86RotateRedisplay (pScreen=0x82a1c08) at xf86Rotate.c:312
#10 0x08125cab in xf86RotateBlockHandler (data=0x82a1c08, pTimeout=0xbfe7de54, pRead=0x826baa0) at xf86Rotate.c:327
#11 0x08098da2 in BlockHandler (pTimeout=0xbfe7de54, pReadmask=0x826baa0) at dixutils.c:418
#12 0x0821e5fc in WaitForSomething (pClientsReady=0xbfe7df00) at WaitFor.c:225
#13 0x0808acf9 in Dispatch () at dispatch.c:383
#14 0x080749b6 in main (argc=2, argv=0xbfe7e434, envp=0xbfe7e440) at main.c:445
----------------------------




The source for fbStore_x8r8g8b8 in fbcompose.c:
----------------------------
static FASTCALL void
fbStore_x8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
{
    int i;
    CARD32 *pixel = (CARD32 *)bits + x;
    for (i = 0; i < width; ++i)
        *pixel++ = values[i] & 0xffffff;    <========== LINE 1039
}
----------------------------
Comment 1 Lee Leahu 2008-10-03 22:50:49 UTC
Additional debugging with gdb...




--------------------------------------------------------------

# gdb /mnt/cdrom/usr/bin/Xorg 
...
(gdb) break fbStore_x8r8g8b8
Function "fbStore_x8r8g8b8" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (fbStore_x8r8g8b8) pending.
(gdb) run -ac
Starting program: /mnt/cdrom/usr/bin/Xorg -ac
...
Breakpoint 2, fbStore_x8r8g8b8 (bits=0x67690ff4, values=0xbfab4b44, x=0, width=1024, indexed=0x0) at fbcompose.c:1037
1037    fbcompose.c: No such file or directory.
        in fbcompose.c
(gdb) list
1032    in fbcompose.c
(gdb) n
1038    in fbcompose.c
(gdb) print i
$1 = 537004168
(gdb) n
1039    in fbcompose.c
(gdb) print i
$2 = 0
(gdb) print pixel
$3 = (CARD32 *) 0x67690ff4
(gdb) print &pixel
$4 = (CARD32 **) 0xbfab39c4
(gdb) x/x &values
0xbfab39b0:     0xbfab4b44
(gdb) x/x &values[0]
0xbfab4b44:     0xffffffff
(gdb) x/x &values[1]
0xbfab4b48:     0xff000000
(gdb) x/x &values[2]
0xbfab4b4c:     0xff000000
(gdb) x/x &values[3]
0xbfab4b50:     0xff000000
(gdb) x/x &values[4]
0xbfab4b54:     0xffffffff
(gdb) x/x &values[5]
0xbfab4b58:     0xff000000
(gdb) x/x &pixel[0] 
0x67690ff4:     Cannot access memory at address 0x67690ff4
(gdb) x/x &pixel   
0xbfab39c4:     0x67690ff4
(gdb) x/x pixel
0x67690ff4:     Cannot access memory at address 0x67690ff4
(gdb) x/x pixel[0]
Cannot access memory at address 0x67690ff4
(gdb) x/x *pixel   
Cannot access memory at address 0x67690ff4
(gdb) x/x &pixel
0xbfab39c4:     0x67690ff4
(gdb) x/x &pixel[0]
0x67690ff4:     Cannot access memory at address 0x67690ff4
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0xb7ad3508 in fbStore_x8r8g8b8 (bits=0x67690ff4, values=0xbfab4b44, x=0, width=1024, indexed=0x0) at fbcompose.c:1039
1039    in fbcompose.c
(gdb) 

--------------------------------------------------------------


Comment 2 Lee Leahu 2008-10-04 18:48:46 UTC
A little more light to shed...
Looks like fbStore_x8r8g8b8 cannot read from the picture...
I see *pixel pointing at a memory location that it cannot read from.



---------------------------------------
...
in fbStore_x8r8g8b8 - i: 0
in fbStore_x8r8g8b8 - values[i]: ffffffff
in fbStore_x8r8g8b8 - values[i] & 0xffffffff: ffffffff
in fbStore_x8r8g8b8 - (unsigned long)pixel: 67639ff4

Program received signal SIGSEGV, Segmentation fault.
0xb7aa7824 in fbStore_x8r8g8b8 (bits=0x67639ff4, values=0xbf9291b4, x=0, width=1024, indexed=0x0) at fbcompose.c:1044
1044            ErrorF("in fbStore_x8r8g8b8 - *pixel: %x\n", *pixel);
(gdb) list
1039        {
1040            ErrorF("in fbStore_x8r8g8b8 - i: %i\n", i);
1041            ErrorF("in fbStore_x8r8g8b8 - values[i]: %x\n", values[i]);
1042            ErrorF("in fbStore_x8r8g8b8 - values[i] & 0xffffffff: %x\n", values[i] & 0xffffffff);
1043            ErrorF("in fbStore_x8r8g8b8 - (unsigned long)pixel: %x\n", (unsigned long)pixel);
1044            ErrorF("in fbStore_x8r8g8b8 - *pixel: %x\n", *pixel);
1045            ErrorF("in fbStore_x8r8g8b8 - *pixel++: %x\n", *pixel++);
1046            *pixel++ = values[i] & 0xffffff;
1047        }
1048    }
(gdb) bt
#0  0xb7aa7824 in fbStore_x8r8g8b8 (bits=0x67639ff4, values=0xbf9291b4, x=0, width=1024, indexed=0x0) at fbcompose.c:1044
#1  0xb7ab1bb8 in fbStore (pict=0x82a0118, x=0, y=0, width=1024, buffer=0xbf9291b4) at fbcompose.c:3412
#2  0xb7ab2438 in fbCompositeRect (data=0xbf928194, scanline_buffer=0xbf9281b4) at fbcompose.c:3567
#3  0xb7ab2cb2 in fbCompositeGeneral (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at fbcompose.c:3670
#4  0xb7abe066 in fbComposite (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at fbpict.c:1279
#5  0xb7a6c0de in XAAComposite (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at xaaPict.c:545
#6  0x081c18e1 in damageComposite (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at damage.c:576
#7  0x081a4192 in CompositePicture (op=1 '\001', pSrc=0x829e8f8, pMask=0x0, pDst=0x82a0118, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1024, height=768) at picture.c:1795
#8  0x0812584d in xf86RotateCrtcRedisplay (crtc=0x829b8f0, region=0xbf92e644) at xf86Rotate.c:208
#9  0x08125c4f in xf86RotateRedisplay (pScreen=0x82a1c08) at xf86Rotate.c:312
#10 0x08125cb7 in xf86RotateBlockHandler (data=0x82a1c08, pTimeout=0xbf92e904, pRead=0x826baa0) at xf86Rotate.c:327
#11 0x08098da2 in BlockHandler (pTimeout=0xbf92e904, pReadmask=0x826baa0) at dixutils.c:418
#12 0x0821e608 in WaitForSomething (pClientsReady=0xbf92e9b0) at WaitFor.c:225
#13 0x0808acf9 in Dispatch () at dispatch.c:383
#14 0x080749b6 in main (argc=2, argv=0xbf92eee4, envp=0xbf92eef0) at main.c:445
(gdb) 
---------------------------------------


For reference, I added some debug statements to the fbStore_x8r8g8b8 function:
---------------------------------------
static FASTCALL void
fbStore_x8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
{
    int i;
    CARD32 *pixel = (CARD32 *)bits + x;
    for (i = 0; i < width; ++i)
    {
        ErrorF("in fbStore_x8r8g8b8 - i: %i\n", i);
	ErrorF("in fbStore_x8r8g8b8 - values[i]: %x\n", values[i]);
	ErrorF("in fbStore_x8r8g8b8 - values[i] & 0xffffffff: %x\n", values[i] & 0xffffffff);
	ErrorF("in fbStore_x8r8g8b8 - (unsigned long)pixel: %x\n", (unsigned long)pixel);
	ErrorF("in fbStore_x8r8g8b8 - *pixel: %x\n", *pixel);
	ErrorF("in fbStore_x8r8g8b8 - *pixel++: %x\n", *pixel++);
        *pixel++ = values[i] & 0xffffff;
    }
}
---------------------------------------
Comment 3 Lee Leahu 2008-10-04 19:27:01 UTC
More information:

In the macro - fbGetDrawable (defined in fb/fb.h)
 PixmapPtr _pPix (assigned from pict->pDrawable) does not contain the data that
  _pPix->devPrivate.ptr points to.

 In other words, the size of pict->pDrawable appears to be sizeof(DrawableRec) 
 instead of sizeof(PixmapRec).  Both *Rec structures are defined in 
 include/pixmatstr.h.

Looks like the fb* stuff is expecting to use data that hasn't been provided 
and is getting some uninitialized random data.
Comment 4 Lee Leahu 2008-10-04 19:29:14 UTC
Created attachment 19383 [details]
screen shot of data for pict and pict->pDrawable

screen shot of data for pict and pict->pDrawable

supplements comment #3
Comment 5 Lee Leahu 2008-10-04 21:23:19 UTC
According to the backtrace, at step #8, in xf86RotateCrtcRedisplay
     crtc->rotatedPixmap->drawable contains the width and height of the
          second monitor - 15" lcd panel (1024x768)
     crtc->scrn->pScreen contains the width and height of the
          first monitor - 19" lcd panel (1280x1024)

That doesn't seem right...
My configuration is the default out of the box, basically a dual head in clone mode.

I reconfigured my setup for a more "basic" configuration.
  - ATI Radeon 9600 (same card)
  - only 1 monitor connected - VGA port - to the 19" lcd panel
  - the 15" lcd panel is physically disconnected.

X started with no configuration

The following xrandr commands were run:

------------------------------
$ xrandr --query
Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 1280 x 1200
VGA-0 connected 1280x1024+0+0 (normal left inverted right) 376mm x 301mm
   1280x1024      60.0*+   74.9     75.0     59.9  
   1152x864       75.0  
   1024x768       74.9     75.1     70.1     60.0     59.9  
   832x624        74.6  
   800x600        72.2     75.0     74.9     60.3     59.9     56.2  
   640x480        75.0     72.8     74.8     66.7     60.0     59.4  
   720x400        70.1  
DVI-0 disconnected (normal left inverted right)
S-video disconnected (normal left inverted right)

$ xrandr -o right
------------------------------


The crash is the same:
------------------------------
...
fbGetDrawable - (pDrawable)->type != DRAWABLE_PIXMAP
in fbCompositeRect - calling store (with else)
Before calling fbGetDrawable: 82303a7
fbGetDrawable - not (pDrawable)->type != DRAWABLE_PIXMAP
After calling fbGetDrawable: 6757fff4
Before calling store: 6757fff4
in fbStore_x8r8g8b8 - i: 0
in fbStore_x8r8g8b8 - values[i]: ffd7bbce
in fbStore_x8r8g8b8 - values[i] & 0xffffffff: ffd7bbce
in fbStore_x8r8g8b8 - pixel: 6757fff4

Program received signal SIGSEGV, Segmentation fault.
0xb7a4a824 in fbStore_x8r8g8b8 (bits=0x6757fff4, values=0xbfccf8f4, x=0, width=1280, indexed=0x0) at fbcompose.c:1044
/mnt/cdrom/var/tmp/portage/x11-base/xorg-server-1.3.0.0-r6/work/xorg-server-1.3.0.0/fb/fbcompose.c:1044:30818:beg:0xb7a4a824
(gdb) bt
#0  0xb7a4a824 in fbStore_x8r8g8b8 (bits=0x6757fff4, values=0xbfccf8f4, x=0, width=1280, indexed=0x0) at fbcompose.c:1044
#1  0xb7a54bb8 in fbStore (pict=0x83d0e00, x=0, y=0, width=1280, buffer=0xbfccf8f4) at fbcompose.c:3412
#2  0xb7a55454 in fbCompositeRect (data=0xbfcce4d4, scanline_buffer=0xbfcce4f4) at fbcompose.c:3569
#3  0xb7a55cce in fbCompositeGeneral (op=1 '\001', pSrc=0x83d12b0, pMask=0x0, pDst=0x83d0e00, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1280, height=1024) at fbcompose.c:3672
#4  0xb7a61082 in fbComposite (op=1 '\001', pSrc=0x83d12b0, pMask=0x0, pDst=0x83d0e00, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1280, height=1024) at fbpict.c:1279
#5  0xb7a0f0de in XAAComposite (op=1 '\001', pSrc=0x83d12b0, pMask=0x0, pDst=0x83d0e00, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1280, height=1024) at xaaPict.c:545
#6  0x081c18e1 in damageComposite (op=1 '\001', pSrc=0x83d12b0, pMask=0x0, pDst=0x83d0e00, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1280, height=1024) at damage.c:576
#7  0x081a4192 in CompositePicture (op=1 '\001', pSrc=0x83d12b0, pMask=0x0, pDst=0x83d0e00, xSrc=0, ySrc=0, xMask=0, yMask=0, xDst=0, yDst=0, width=1280, height=1024) at picture.c:1795
#8  0x0812584d in xf86RotateCrtcRedisplay (crtc=0x829b418, region=0xbfcd4984) at xf86Rotate.c:208
#9  0x08125c4f in xf86RotateRedisplay (pScreen=0x82a0d40) at xf86Rotate.c:312
#10 0x08125cb7 in xf86RotateBlockHandler (data=0x82a0d40, pTimeout=0xbfcd4c44, pRead=0x826baa0) at xf86Rotate.c:327
#11 0x08098da2 in BlockHandler (pTimeout=0xbfcd4c44, pReadmask=0x826baa0) at dixutils.c:418
#12 0x0821e608 in WaitForSomething (pClientsReady=0xbfcd4cf0) at WaitFor.c:225
#13 0x0808acf9 in Dispatch () at dispatch.c:383
#14 0x080749b6 in main (argc=2, argv=0xbfcd5224, envp=0xbfcd5230) at main.c:445
(gdb) list
1039	    {
1040	        ErrorF("in fbStore_x8r8g8b8 - i: %i\n", i);
1041		ErrorF("in fbStore_x8r8g8b8 - values[i]: %lx\n", (unsigned long)values[i]);
1042		ErrorF("in fbStore_x8r8g8b8 - values[i] & 0xffffffff: %lx\n", (unsigned long)values[i] & 0xffffffff);
1043		ErrorF("in fbStore_x8r8g8b8 - pixel: %lx\n", (unsigned long)pixel);
1044		ErrorF("in fbStore_x8r8g8b8 - *pixel: %lx\n", (unsigned long)*pixel);
1045		ErrorF("in fbStore_x8r8g8b8 - *pixel++: %lx\n", (unsigned long)*pixel++);
1046	        *pixel++ = values[i] & 0xffffff;
1047	    }
1048	}
(gdb) 
------------------------------
Comment 6 Lee Leahu 2008-10-04 22:20:43 UTC
Interesting...

crtc->rotatedData is allocated by ctrc->funcs->shadow_allocate

In this case, ctrc->funcs->shadow_allocate is a reference to the function
 radeon_crtc_shadow_allocate, in the radeon_drv library.


The call to ctrc->funcs->shadow_allocate occurs in the function xf86CrtcRotate
 in the file 'xf86Rotate.c'.

After putting a break point on this function, I discovered something...

The first call to the function is successful - crtc->rotatedData is allocated 
properly and the 'fbStore_x8r8g8b8' completes successfuly.

There is a second call to the function, and it is this second call that fails.
The shadow_allocate function in the radeon_drv library returns a pointer to
data at 0x6787b120, which cannot be accessed.

This is the cause of the segmentation fault later in fbStore_x8r8g8b8.
Comment 7 Lee Leahu 2008-10-04 22:52:28 UTC
Closer...

In the radeon driver package, in the file radeon_crtc.c, there is the
function 'radeon_crtc_shadow_allocate'.


In this function is a variable 'rotate_offset' (unsigned long).  It is not
initialized by default.

If the accelleration method is EXA it gets set.
If the accelleration method is XAA *and* DRI is enabled it gets set.
If the accelleration method is XAA *and* DRI is not enabled it does not get set.

Thus, in this case, since my setup is XAA and no DRI, this variable is not
being initialized properly, but is being used to calculate the return value.


This is a problem in both the 6.8.0-r1 and 6.9.0 builds of the radeon_drv library.
Comment 8 Lee Leahu 2008-10-04 23:01:54 UTC
Created attachment 19385 [details] [review]
initialize rotate_offset when using XAA and DRI is disabled

Resolved...

The rotate_offset variable needed to be initialized when not using DRI.

This patch initialized the rotate_offset variable when DRI is not enabled.

I've tested this patch with one and two lcd panels attached and no crashes!

Let's get this patch applied into the official source code.

Gentoo builds 6.8.0-r1 and 6.9.0 both need this patch.
Comment 9 Lee Leahu 2008-10-04 23:03:09 UTC
Component changed to 'Driver/Radeon' as the root cause was an uninitialized variable in the radeon_drv driver.
Comment 10 Lee Leahu 2008-10-04 23:05:28 UTC
Please see the attached patch.

It fixes a variable initialization problem when the following is true:
 - XRandR used to rotate the screen
 - Acceleration method is XAA
 - Driver build without DRI support.

The patch is for the 6.8.0-r1 and 6.9.0 gentoo builds of the radeon_drv driver.
Comment 11 Lee Leahu 2008-10-04 23:09:34 UTC
Summary line updated to be more descriptive.
Comment 12 Alex Deucher 2008-10-05 23:32:39 UTC
This should be fixed in ati git master already, but the patch is still relevant for older versions of the driver.
Comment 13 Lee Leahu 2008-10-06 06:16:01 UTC
(In reply to comment #12)
> This should be fixed in ati git master already, but the patch is still relevant
> for older versions of the driver.
> 

Confirming fixed in ati git master.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.