Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет mumuntu ([info]mumuntu)
@ 2005-08-11 12:08:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
[Help]
Платформа PPC, приложение - xorg-x11, файл xc/programs/Xserver/hw/xfree86/common/xf86Init.c
Вот такой кусок кода:

    for (i = 0; i < xf86NumScreens; i++) {
        xf86EnableAccess(xf86Screens[i]);
        if (xf86Screens[i]->PreInit &&
            xf86Screens[i]->PreInit(xf86Screens[i], 0))

            xf86Screens[i]->configured = TRUE;
    }


Если верить gdb, то получается, что перед выполнением зеленой строчки i=0, как и положено.
А перед выполнением красной строчки, ... ......, i=1.
Ой-ой-ой-ой, я, кажется, понял. Это GCC так оптимизирует.

InitOutput (pScreenInfo=0x1020b38c, argc=1, argv=0x7fb61ae4) at xf86Init.c:586
586         for (i = 0; i < xf86NumScreens; i++) {
(gdb) step
587             xf86EnableAccess(xf86Screens[i]);
(gdb) print i
$1 = 0
(gdb) step
586         for (i = 0; i < xf86NumScreens; i++) {
(gdb) print i
$2 = 0
(gdb) step
587             xf86EnableAccess(xf86Screens[i]);
(gdb) print i
$3 = 1
(gdb) step
xf86EnableAccess (pScrn=0x103e0408) at xf86Bus.c:694
694         register EntityAccessPtr peAcc = (EntityAccessPtr) pScrn->access;
(gdb)


Похоже, надо отрубать оптимизацию. Других мыслей пока нет. А у вас есть?


(Читать комментарии) - (Добавить комментарий)


(Анонимно)
2005-08-11 04:53 (ссылка)
x/40i $pc покажет 40 инструкций с текущего РС. Так функция вызывается один или два раза? GDB может показывать что угодно для оптимизированного кода.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 05:48 (ссылка)

(gdb) x/50i $pc
0x10029e2c <InitOutput+2096>: lwz r0,-13680(r25)
0x10029e30 <InitOutput+2100>: li r28,0
0x10029e34 <InitOutput+2104>: cmpw cr7,r28,r0
0x10029e38 <InitOutput+2108>: bge- cr7,0x10029ffc <InitOutput+2560>
0x10029e3c <InitOutput+2112>: lis r16,4128
0x10029e40 <InitOutput+2116>: li r30,1
0x10029e44 <InitOutput+2120>: b 0x10029e54 <InitOutput+2136>
0x10029e48 <InitOutput+2124>: lwz r0,-13680(r25)
0x10029e4c <InitOutput+2128>: cmpw cr7,r28,r0
0x10029e50 <InitOutput+2132>: bge- cr7,0x10029ffc <InitOutput+2560>
0x10029e54 <InitOutput+2136>: lwz r9,-13608(r16)
0x10029e58 <InitOutput+2140>: rlwinm r31,r28,2,0,29
0x10029e5c <InitOutput+2144>: addi r28,r28,1
0x10029e60 <InitOutput+2148>: lwzx r3,r31,r9
0x10029e64 <InitOutput+2152>: bl 0x1002d6c0 <xf86EnableAccess>


Функция один раз вызывается, но, как видно из ассемблерного куска, единичка к счетчику добавляется до вызова xf86EnableAccess. Так что следующий вызов уже получит неправильный адрес в массиве. Вот только я не совсем понял, как так xf86EnableAccess получает нолик, а не единичку. И где тут у них стек...


(gdb) info address i
Symbol "i" is a variable in register r28.
(gdb)


Такие дела.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:04 (ссылка)
Хехе.
Там все сложнее, чем я думал.


(gdb) x/50i $pc
0x10029e2c <InitOutput+2096>: lwz r0,-13680(r25)
0x10029e30 <InitOutput+2100>: li r28,0
0x10029e34 <InitOutput+2104>: cmpw cr7,r28,r0
0x10029e38 <InitOutput+2108>: bge- cr7,0x10029ffc <InitOutput+2560>
0x10029e3c <InitOutput+2112>: lis r16,4128
0x10029e40 <InitOutput+2116>: li r30,1
0x10029e44 <InitOutput+2120>: b 0x10029e54 <InitOutput+2136>
0x10029e48 <InitOutput+2124>: lwz r0,-13680(r25)
0x10029e4c <InitOutput+2128>: cmpw cr7,r28,r0
0x10029e50 <InitOutput+2132>: bge- cr7,0x10029ffc <InitOutput+2560>
0x10029e54 <InitOutput+2136>: lwz r9,-13608(r16)
0x10029e58 <InitOutput+2140>: rlwinm r31,r28,2,0,29
0x10029e5c <InitOutput+2144>: addi r28,r28,1
0x10029e60 <InitOutput+2148>: lwzx r3,r31,r9
0x10029e64 <InitOutput+2152>: bl 0x1002d6c0 <xf86EnableAccess>
0x10029e68 <InitOutput+2156>: lwz r11,-13608(r16)
0x10029e6c <InitOutput+2160>: li r4,0
0x10029e70 <InitOutput+2164>: lwzx r9,r31,r11
0x10029e74 <InitOutput+2168>: lwz r0,1024(r9)
0x10029e78 <InitOutput+2172>: mr r3,r9
0x10029e7c <InitOutput+2176>: cmpwi cr7,r0,0
0x10029e80 <InitOutput+2180>: beq+ cr7,0x10029e48 <InitOutput+2124>
0x10029e84 <InitOutput+2184>: mtlr r0
0x10029e88 <InitOutput+2188>: blrl


Валится конкретно на последней инструкции в этом листинге.
Что эта мнемоника означает, я даже и не понял пока что.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:18 (ссылка)
А вот, кстати, и нифига.
Нет тут никакой ошибки оптимизации, похоже, дело в чем-то другом.
Но вот хер ли тогда gdb не показывает исходники, когда осуществлен вызов функции по указателю? Это gdb такой дурной?

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2005-08-11 06:34 (ссылка)
Давненько не брал я в руки шашек. Выглядит всё нормально, к тому моменту, когда р28 увеличен, его прежнее значение ыже не нужно. Проблема с xf86Screens[i]->PreInit (в r0 @0x10029e84). Если функция по этому адресу скомпилирована без оптимизации, gdb туда не поидет. Если по этоми адресу нет функции, все упадет с SIGBUS/SIGSEGV

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:40 (ссылка)
На самом деле, там функция есть, и gdb инструкции видит.
Но не сопоставляет их с исходниками и вообще не видит debug info, что меня здорово смутило сначала.
Я проверил адрес, который в массиве записей об экранах этой функции соответствует - переход выполнен правильно.
Вот только отлаживать в gdb дальше нельзя. Похоже, придется делать #define DEBUG и пересобирать Xorg заново, он тогда должен в логи каждый чих писать.

(Ответить) (Уровень выше)


[info]ex_sighup150@lj
2005-08-11 06:43 (ссылка)
Если этот указатель не проинициализирован (то бишь r0 равно нулю), то перехода туда не будет. Так что валится оно уже внутри этого PreInit наверняка.
Саш, как именно валится-то, кстати?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:54 (ссылка)
SIGSEGV ловит.
Причем, что самое неприятное, там stack corruption - я не могу по корке backtrace посмотреть даже.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]ex_sighup150@lj
2005-08-11 07:03 (ссылка)
Что за драйвер?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 07:19 (ссылка)
Radeon

(Ответить) (Уровень выше)


[info]ex_sighup150@lj
2005-08-11 06:26 (ссылка)
Безусловный переход по адресу в регистре LR.
Предыдущая инструкция грузит туда содержимое r0.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:30 (ссылка)
Ага.
Я уже понял. :)
А ты не знаешь, где можно все эти мнемоники найти?
Я нашел где-то у буржуЕв, но там неполное множество.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]ex_sighup150@lj
2005-08-11 06:53 (ссылка)
Вот тут хорошо:
http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixassem/alangref/alangref02.htm#ToC

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:58 (ссылка)
Ага, спасибо.
Но про blrl там тоже нет, что характерно.
Пойду-ка я посплю немного, а то я с ночи сижу.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]ex_sighup150@lj
2005-08-11 07:03 (ссылка)
Есть :) Поищи "extended branch mnemonics".

(Ответить) (Уровень выше)


[info]sobaker@lj
2005-08-11 15:07 (ссылка)
Выложу-ка и я парочку:

http://vk.infolio.ru/ppc/ppc.zip

внутри PowerPC RISC CPU Reference Manual и PowerPC Compiler Writer's Guide. Обоими пользуюсь, очень хороши, по-моему.

(Ответить) (Уровень выше)


(Анонимно)
2005-08-11 06:37 (ссылка)
Вызов функции по LR (Branch and Link to LR)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]ex_sighup150@lj
2005-08-11 06:55 (ссылка)
Ну, да, не просто безусловный переход, а безусловный переход с сохранением адреса возврата в LR :)

(Ответить) (Уровень выше)


[info]alexclear@lj
2005-08-11 06:28 (ссылка)
Угу.
Все он правильно ходит.
Вот только исходник не показывает, сволочЪ.
Это, наверное, ограничение gdb, надо будет на каком-нибудь простом примере попробовать с указателями на функции.

(Ответить) (Уровень выше)


[info]parafin@lj
2005-08-11 06:28 (ссылка)
Не надо забывать про оптимизацию. i то увеличивается, только я подозреваю, что адрес элемента xf86Screens[i] сохраняется в другом регистре. Надо будет про синтаксис почитать, а то половина инструкций непонятна.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:33 (ссылка)
Да, я сейчас проверил дополнительно адрес той функции, которая по указателю вызывается, и где все валится.
Все верно - увеличение i происходит уже после того, как все данные об элементе по регистрам распихали, так что ошибки оптимизации нет никакой.
Но отлаживать через gdb дальше не получается - он после вызова функции по указателю перестает видеть границы функций.

(gdb) step
Cannot find bounds of current function
(gdb)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]parafin@lj
2005-08-11 06:39 (ссылка)
Есть подозрение, что эта функция находится в библиотеке, которая скомпилена без поддержки отладки. Других вариантов я не вижу. И если мне не изменяет память, при оптимизации на PPC по - умолчанию отключены frame-pointer, что может быть причиной. Может попробовать перекомпилировать для отладки с -O0?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:51 (ссылка)
По идее, Xorg самодостаточен, особенно для имлементаций PreInit(...) для разных карт. Я могу попробовать в so-шках порыться и посмотреть, есть там отладачная инфа в этих функциях, или нет. А для начала, действительно, пересоберу с -O0.

(Ответить) (Уровень выше)


(Анонимно)
2005-08-11 06:52 (ссылка)
Попробуйте stepi

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 06:57 (ссылка)
stepi нормально ходит, да.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2005-08-11 07:03 (ссылка)
Так можно теперь проверить, куда ходит, и по этим адресам определить, где код -- в .so библиотеке или в основном бинарнике, после чего слинковать с отладочной информацией.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 11:42 (ссылка)
Тут нечто странное получается.


(gdb) info target
Symbols from "/usr/bin/Xorg".
Unix child process:
Using the running image of child process 16105.
While running this, GDB does not access memory from...
Local exec file:
`/usr/bin/Xorg', file type elf32-powerpc.
Entry point: 0x10027818
0x10000174 - 0x10000181 is .interp
0x10000184 - 0x100001a4 is .note.ABI-tag
0x100001a4 - 0x10005f9c is .hash
0x10005f9c - 0x1001570c is .dynsym
0x1001570c - 0x10024c3f is .dynstr
0x10024c40 - 0x10026b2e is .gnu.version
0x10026b30 - 0x10026bf0 is .gnu.version_r
0x10026bf0 - 0x10026c2c is .rela.dyn
0x10026c2c - 0x100277f0 is .rela.plt
0x100277f0 - 0x10027818 is .init
0x10027818 - 0x10287c20 is .text
0x10287c20 - 0x10287c40 is .fini
0x10287c40 - 0x102a4e74 is .rodata
0x102a4e74 - 0x102a4e88 is .eh_frame_hdr
0x102a4e88 - 0x102a4ec0 is .eh_frame
0x102b5000 - 0x102b5008 is .ctors
0x102b5008 - 0x102b5010 is .dtors
0x102b5010 - 0x102b5014 is .jcr
0x102b5014 - 0x102b5838 is .got2
0x102b5838 - 0x102b5930 is .dynamic
0x102b5930 - 0x102e6804 is .data
0x102e6804 - 0x102e6818 is .got
---Type to continue, or q to quit---
0x102e6818 - 0x102e6974 is .sdata
0x102e6978 - 0x102e75cc is .sbss
0x102e75cc - 0x102e81d8 is .plt
0x102e81d8 - 0x102f8db4 is .bss
0x0ffce0d4 - 0x0ffce35c is .hash in /lib/libz.so.1
0x0ffce35c - 0x0ffce92c is .dynsym in /lib/libz.so.1



(gdb) stepi
0x10afa234 in ?? ()
(gdb)


Адрес в эту секцию попадает: 0x10027818 - 0x10287c20 is .text, для файла "/usr/bin/Xorg", а он-то точно с debug info собран.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2005-08-11 18:24 (ссылка)
Не, не попадает. Можно посмотреть /pid//maps

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 18:35 (ссылка)
Ага, сейчас посмотрю, спасибо!

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2005-08-11 18:51 (ссылка)
Кстати, gdb должен показать имя функции даже без отладочной информации (если только не обрезана таблица символов). Вы уверены, что это настоящая функция, а не случайный адрес? Покажите, пжлста, инструкции по этому адресу.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-11 19:58 (ссылка)
Инструкции вот такие:


0x10028870 588 if (xf86Screens[i]->PreInit &&
(gdb) stepi
0x10afa22c in ?? ()
(gdb) x/30i $pc
0x10afa22c: stwu r1,-64(r1)
0x10afa230: mflr r0
0x10afa234: stw r29,52(r1)
0x10afa238: stw r31,60(r1)
0x10afa23c: stw r0,68(r1)
0x10afa240: mr r31,r1
0x10afa244: stw r3,8(r31)
0x10afa248: stw r4,12(r31)
0x10afa24c: li r0,0
0x10afa250: stw r0,20(r31)
0x10afa254: li r0,0
0x10afa258: stw r0,24(r31)
0x10afa25c: lwz r9,8(r31)
0x10afa260: lwz r0,224(r9)
0x10afa264: cmpwi cr7,r0,1
0x10afa268: beq- cr7,0x10afa278
0x10afa26c: li r0,0
0x10afa270: stw r0,36(r31)
0x10afa274: b 0x10afac5c
0x10afa278: lwz r3,8(r31)
0x10afa27c: bl 0x10aefaec
0x10afa280: mr r0,r3
0x10afa284: cmpwi cr7,r0,0
0x10afa288: bne- cr7,0x10afa298
---Type to continue, or q to quit---
0x10afa28c: li r0,0
0x10afa290: stw r0,36(r31)
0x10afa294: b 0x10afac5c
0x10afa298: lwz r9,8(r31)
0x10afa29c: lwz r0,248(r9)
0x10afa2a0: stw r0,16(r31)
(gdb)


Сейчас проверю листинг на повторимость, ведь, если адрес случаен, инструкции будут другие.

(Ответить) (Уровень выше)


[info]alexclear@lj
2005-08-11 20:01 (ссылка)
Угу, instruction set все время один и тот же, это не случайный адрес.
Сейчас посмотрю maps.

(Ответить) (Уровень выше)


[info]alexclear@lj
2005-08-11 20:06 (ссылка)
Вот:


root@mamontenok ~ # ps axf | grep 16907
16907 ? T 0:00 | \_ /usr/bin/Xorg
16985 pts/1 S+ 0:00 \_ grep 16907
root@mamontenok ~ # cat /proc/16907/maps
0fc91000-0fd06000 r-xp 00000000 03:0b 1248343 /usr/lib/libfreetype.so.6.3.7
0fd06000-0fd11000 ---p 00075000 03:0b 1248343 /usr/lib/libfreetype.so.6.3.7
0fd11000-0fd1c000 rwxp 00070000 03:0b 1248343 /usr/lib/libfreetype.so.6.3.7
0fd1c000-0fd1d000 rwxp 0fd1c000 00:00 0
0fd2d000-0fd3e000 r-xp 00000000 03:0b 1605651 /usr/lib/modules/fonts/libfreet
ype.so
0fd3e000-0fd4d000 ---p 00011000 03:0b 1605651 /usr/lib/modules/fonts/libfreet
ype.so
0fd4d000-0fd4f000 rwxp 00010000 03:0b 1605651 /usr/lib/modules/fonts/libfreet
ype.so
0fd5f000-0fe86000 r-xp 00000000 03:0b 1346731 /lib/libc-2.3.4.so
0fe86000-0fe8f000 ---p 00127000 03:0b 1346731 /lib/libc-2.3.4.so
0fe8f000-0fe91000 r--p 00130000 03:0b 1346731 /lib/libc-2.3.4.so
0fe91000-0fe95000 rwxp 00132000 03:0b 1346731 /lib/libc-2.3.4.so
0fe95000-0fe97000 rwxp 0fe95000 00:00 0
0fea7000-0feab000 r-xp 00000000 03:0b 1414763 /usr/lib/libXau.so.6.0
0feab000-0feb7000 ---p 00004000 03:0b 1414763 /usr/lib/libXau.so.6.0
0feb7000-0febb000 rwxp 00000000 03:0b 1414763 /usr/lib/libXau.so.6.0
0fecb000-0fece000 r-xp 00000000 03:0b 475205 /lib/libpam_misc.so.0.77
0fece000-0fedb000 ---p 00003000 03:0b 475205 /lib/libpam_misc.so.0.77
0fedb000-0fedf000 rwxp 00000000 03:0b 475205 /lib/libpam_misc.so.0.77
0feef000-0fef1000 r-xp 00000000 03:0b 1346708 /lib/libdl-2.3.4.so
0fef1000-0feff000 ---p 00002000 03:0b 1346708 /lib/libdl-2.3.4.so
0feff000-0ff00000 r--p 00010000 03:0b 1346708 /lib/libdl-2.3.4.so
0ff00000-0ff01000 rwxp 00011000 03:0b 1346708 /lib/libdl-2.3.4.so
0ff11000-0ff1a000 r-xp 00000000 03:0b 475293 /lib/libpam.so.0.77
0ff1a000-0ff21000 ---p 00009000 03:0b 475293 /lib/libpam.so.0.77
0ff21000-0ff2a000 rwxp 00000000 03:0b 475293 /lib/libpam.so.0.77
0ff3a000-0ffad000 r-xp 00000000 03:0b 1346743 /lib/libm-2.3.4.so
0ffad000-0ffba000 ---p 00073000 03:0b 1346743 /lib/libm-2.3.4.so
0ffba000-0ffbb000 r--p 00080000 03:0b 1346743 /lib/libm-2.3.4.so
0ffbb000-0ffbe000 rwxp 00081000 03:0b 1346743 /lib/libm-2.3.4.so
0ffce000-0ffdf000 r-xp 00000000 03:0b 1247567 /lib/libz.so.1.2.3
0ffdf000-0ffee000 ---p 00011000 03:0b 1247567 /lib/libz.so.1.2.3
0ffee000-0fff0000 rwxp 00010000 03:0b 1247567 /lib/libz.so.1.2.3
10000000-102a5000 r-xp 00000000 03:0b 1415078 /usr/bin/Xorg
102b5000-102e7000 rwxp 002a5000 03:0b 1415078 /usr/bin/Xorg
102e7000-10b86000 rwxp 102e7000 00:00 0 [heap]
30000000-30017000 r-xp 00000000 03:0b 1346606 /lib/ld-2.3.4.so
30017000-30018000 rw-p 30017000 00:00 0
3001e000-30020000 rw-p 3001e000 00:00 0
30020000-30021000 r--p 00020000 03:0b 1346606 /lib/ld-2.3.4.so
30021000-30022000 rwxp 00021000 03:0b 1346606 /lib/ld-2.3.4.so
30022000-30042000 rw-s f0000000 00:0c 4823 /dev/mem
7fa2e000-7fa43000 rw-p 7fa2e000 00:00 0 [stack]
root@mamontenok ~ #

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2005-08-12 06:35 (ссылка)
Откуда вообще берется это PreInit?


Выглядит так, если бы Xorg или сам сгенерил этот код или каким-то образом сам загрузил (не через dlopen()) - код находится в heap-e. Т.е. концы найти проблематично. Это какой-то binary-only драйвер для Xorg?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-12 10:34 (ссылка)
А ведь и действительно в heap.
Что-то я вчера не сообразил, что 2 это меньше, чем A c недосыпу.
Видимо, и правда binary-only драйвер, сейчас проверю.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]parafin@lj
2005-08-13 15:08 (ссылка)
А это случаем не DRM модуль он подгружает из Mesa3D, может стоит в конфиге отключить поддержку OpenGL и ещё раз проверить?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alexclear@lj
2005-08-13 15:29 (ссылка)
Я сейчас попробую, но, по моим воспоминаниям, в самом начале я специально врубил OpenGL и DRI, потому что без них вообще не шло. Правда, не помню, был ли SIGSEGV...

(Ответить) (Уровень выше)


(Читать комментарии) -