2007/04/18

Dtrace 활용하기 : Xorg의 버그 finding

오픈 솔라리스를 쓰다보면 확실히 많은 버그에 시달리게 된다. 그나마 썬 솔라리스는 패치도 제공해주고 하니, 가끔씩 패치하면 버그가 줄어드는 것을 볼 수가 있는데, 오픈 솔라리스는 그것도 못하니 새로 깔아야 한단 얘긴데... 참으로 귀찮은 일이 아닐 수 없다.

한편으론 dtrace를 활용하면서 배워보려고 하는 사람들에겐 아주 좋은 환경이 아닐 수 없다.
여기 저기 떠돌아다니는 버그들 덕분에 dtrace 활용율을 늘릴 수는 있을 테니 말이다.

오늘은 firefox 2.0 영문 브라우저를 쓰고 있는데, 미디어 다음 사이트를 접속만 하면 시스템의 CPU가 버닝아웃될 지경이다.(참고로 내 시스템은 Mobile Athlon 3000+/amd64/2G from Acer )

그래서, dtrace로 Xorg의 어느 부분이 문제인지 찾아보고 싶어졌다. 평소에는 바뻐서 그냥 죽였다 다시 살리곤 했는데, 오늘은 시간이 좀 되는 관계로...
prstat상으로 보면, 나는 브라우저를 사용하고 있는데, CPU 점유는 Xorg가 거의 다하고 있다.
Xorg가 누구 때문에 이렇게 열심히 일하는 지를 보려면 /usr/demo/dtrace/whofor.d를 이용하면
쉽게 추측할 수 있다(물론, prstat만 가지고도 어느 정도 예측할 수 있지만  말이다)

#dtrace -s /usr/demo/dtrace/whofor.d

firefox-bin sleeping on Xorg:

           value  ------------- Distribution ------------- count
            2048 |                                         0
            4096 |                                         5
            8192 |@@@@@@@@@@@@@@@                          6102
           16384 |@@@@@@@@@@@@@                            5053
           32768 |@@@@                                     1703
           65536 |@@@                                      1057
          131072 |@                                        587
          262144 |@                                        358
          524288 |@                                        199
         1048576 |@                                        288
         2097152 |@                                        244
         4194304 |                                         148
         8388608 |                                         43
        16777216 |                                         15
        33554432 |                                         16
        67108864 |                                         2
       134217728 |                                         0


챠트상으로 나온 결과를 보면, firefox가 잦은 횟수로 Xorg에 CPU를 빼앗기고 있다.
firefox가 Xorg에 부담을 주고 있는 것으로 예측할 수 있다.

그럼 Xorg의 뭐가 잘못되서 CPU를 이렇게 쓰는 것인지 궁금해졌다. '도대체 Xorg를
왜 이렇게 만들어가지설라무네...'
일단 CPU를 과점하고 있는 Xorg의 pid로 pstack을 찍어봤다. 흠...
Xorg의 문제인지, shared library의 문제인지가 궁금하기 때문이다.
_XSERVTransSocketRead() 란 함수가 불려지고 있는 것으로 나오는데 이게 어느 라이브러리에 붙어있는 것인지 알 수가 없다.

dtrace를 떴다.
#dtrace -b 2g  -n 'pid$target::_XSERVTransSocketRead:entry{ustack();}' -p `pgrep Xorg`
Xorg의 문제이다.

여기서 _XSERVT* 함수가 불릴때만 문제가 되는 것인지 확정할 수 없다. 일단 Xorg가 문제임으로 Xorg의 Sub function들을 대상으로 호출 회수 상태를 알고 싶어졌다. 다시 dtrace를 했다.

#dtrace  -n 'pid$target:Xorg::entry{@[probefunc]=count()}' -p `pgrep Xorg`
Xalloc, Xfree를 과도하게 하고 있는 것이 보인다.
이 함수는 둘다 Xorg의 메모리 할당과 해제를 위한 함수인데, 뭐 때문에 메모리 할당 해제를
이렇게 심하게 반복할까? 궁금해진다. 다시 dtrace를 돌렸다.

Xalloc이 호출될때, 어떤 stack을 경유해서 Xalloc() 이 호출되는 지 궁금하기 때문이다.
이 부분을 알게 되면, Xorg의 문제의 중요 부분을 알 수 있겠다 싶다.

# dtrace  -n 'pid$target:Xorg:Xalloc:entry{@[ustack()]=count();}' -p `pgrep Xorg`
              Xorg`Xalloc
              libxaa.so`XAAInitPixmapCache+0x72b
              Xorg`localAllocateOffscreenArea+0x63
              Xorg`xf86AllocateOffscreenArea+0x36
              libxaa.so`XAACreatePixmap+0x226
              Xorg`ProcCreatePixmap+0xff
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             1932

              Xorg`Xalloc
              libxaa.so`XAAValidateGC+0x305
              Xorg`damageValidateGC+0x40
              Xorg`ValidateGC+0x1a
              Xorg`ProcPolyFillRectangle+0x101
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             3281

              Xorg`Xalloc
              Xorg`miRegionCreate+0xf
              Xorg`miComputeCompositeClip+0x98
              libfb.so`fbValidateGC+0x63
              Xorg`miBSCheapValidateGC+0x89
              libxaa.so`XAAValidateGC+0x63
              Xorg`damageValidateGC+0x40
              Xorg`ValidateGC+0x1a
              Xorg`ProcPolyFillRectangle+0x101
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             3382

              Xorg`Xalloc
              Xorg`AddResource+0xda
              Xorg`ProcCreateGC+0xbd
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             4191

              Xorg`Xalloc
              Xorg`CreateGC+0x1a
              Xorg`ProcCreateGC+0xa5
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             4191

              Xorg`Xalloc
              Xorg`miRectsToRegion+0x13
              Xorg`miChangeClip+0x35
              Xorg`miBSCheapChangeClip+0x27
              libxaa.so`XAAChangeClip+0x43
              Xorg`damageChangeClip+0x44
              Xorg`SetClipRects+0xe1
              Xorg`ProcSetClipRectangles+0x87
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             4949

              Xorg`Xalloc
              Xorg`SetClipRects+0x3f
              Xorg`ProcSetClipRectangles+0x87
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             4949

              Xorg`Xalloc
              libxaa.so`XAADoGlyphs+0x5b7
              libxaa.so`XAAGlyphs+0x95
              Xorg`damageGlyphs+0x337
              Xorg`CompositeGlyphs+0x13e
              Xorg`ProcRenderCompositeGlyphs+0x347
              Xorg`ProcRenderDispatch+0x26
              Xorg`Dispatch+0x2d2
              Xorg`main+0x4de
              Xorg`_start+0x7a
             6327



다시 dtrace를 돌렸다.
흠... 끝의 다섯개의 스택에 관심이 갔다. 특히, 마지막 스택을 유념하게 보게된다.
그 앞의 스택의 호술 횟수(4949)보다 50%이상 많다(6327)

ProcRenderCompositeGlyphs() Glyphs 이라.. 어라, 이건 폰트 문제인데... Glyphs를 damage()
한후 libxaa에 있는 XAAGlyphs를 다시 호출하느라 메모리를 할당하고 있네...
왜 이러지 미쳤나? xaa 라이브러리는 True type 폰트를 위한 anti-aliasing 라이브러리이다.
firefox가 열려고 시도한 웹페이지에서 지정한 true-type 폰트의 anti-aliasing 때문에
생긴 것일까?

어느 정도 원인은 파악했다. 역시 dtrace다 !!!

그런데, 이걸 어떻게 해결해야 하나...가 고민이다. Xorg를 업그레이드 해야 하나? 솔라리스를 다시 깔아야 하나? 아니면, 옵션 변경으로 할 수 있을까?

여기서부터는 dtrace문제 밖인데... 웬지 dtrace가 해결까지 해줬으면 좋겠다는 꿈을 꿔본다.

"도움이 되셨으면 구글 애드센스 살짝 눌러주는 센스를 기대하겠습니다"



댓글 1개:

익명 :

헉... dtrace 강력하군요