RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : проблема со стеком


Список сообщений | Написать новое | Ответить на сообщение | Домой Поиск:
Предыдущее сообщение | Следующее сообщение
From : zuko, 2:5050/13.29, http://zuko.mitm.ru
To : Valery Sedletski (aka heretic)
Subj : проблема со стеком


> # u %D1f18c28 - 10
>
> -------cut-------------------------------
> OS2KRNL intKernelExit:
> %D1f18c28 8f05b80bddff pop dword ptr [ffdd0bb8]
> %D1f18c2e 0fa9 pop gs
> %D1f18c30 0fa1 pop fs
> ^^^^^^^^^ ^^^^^^^^^^
> %D1f18c32 07 pop es
> %D1f18c33 1f pop ds
> %D1f18c34 61 popad
> %D1f18c35 83c408 add esp,+08
> %D1f18c38 cf iretd
> OS2KRNL PrivateStackExit:
> -------cut------------------------------
> -- Выход из кернела?

этот кусочек - возврат из обработчика прерываний ring0.
там картинка такая: происходит аппаратное прерывание - управление
попадает в ядро ос2, в процедуру intIRQRouter, в ней на стеке сохранаются
все регистры, плюс делаются дополнительные магические пассы на тему 32-битных стеков. потом эта функа ищщет по структурам ядра хоть один зарегистрированный
обработчик прерываний для данного номера IRQ, вызывает его - таким образом
управление попадает в обработчик прерывания конкретного драйвера. после того как он сделает все свои грязные дела он делает retf и управление попадает назад в
эту функу, дальнейшее ее выполнение оканчивается искомым intKernelExit, который восстанавливает со стека все запомненные регистры и на этом обработка прерывания завершается.

мы наблюдаем порчу стека.
выглядит все так, будто обработчик прерывания драйвера попортил значения в стеке. тут удивительно то, что он не все там запорол - ибо управление таки дошло до intKernelExit, значит как минимум адрес возврата в ядро на стеке лежал верный.

(между прочим 2246h - это селектор в LDT причем ring=2.)

> Стек:
>
> # dd 0030:00005000 l200
>
> -------cut------------------------------
> 0030:00005000 25a0517c 00000000 50760001 0608294c
> 0030:00005010 0030504e 47100029 51b05001 00600000
> 0030:00005020 0001000a 47100029 1f585536 fef12cd4
> 0030:00005030 00000069 40010000 9ff24001 0100ffeb
> 0030:00005040 22460000 1e3b0000 8c86fff2 1e1cf9f4
> 0030:00005050 5092fff2 23480000 8c86fff2 d44cf9f4
> 0030:00005060 2246ffec 27d70000 0002ffdd 8c860000
> 0030:00005070 8e0ef9f4 000afff1 00000160 ffdd2795
> 0030:00005080 ffdd27d7 00000002 ffdd27d5 f9f48cd4
> 0030:00005090 00040000 b4090000 27e90160 12000a00
> 0030:000050a0 ffff2246 00040000 28090000 0a008020
> 0030:000050b0 2d090004 388c1200 fff1eb1c fff10168
> 0030:000050c0 ea60237c 0000010a 00000000 fff1eb1c
> 0030:000050d0 ea600000 fdbd2f78 fefc54a0 00000004
> 0030:000050e0 000050f4 ffecb4e8 ffff0080 00002cb0
> 0030:000050f0 00000004 ffec0000 00000650 00000160
> 0030:00005100 00000160 0000000e 00000000 fff18c30
> 0030:00005110 00000168 00012046 00202246 01600a00
> ~~~~~~~~
> вершина стека

[...]

> Причем в стеке (на вершине) находится двойное слово
> 00202246. Вообще-то, имхо за селектором наверное должны
> идти нули (выравнивание по границе дв. слова), а там
> почему-то 0020.

а почему ты думаешь что тут вообще 32-битный стек? :)
он вовсе себе 16-битный...

хотя надо посмотреть на опыте как именно пихают 32-битные команды
данные в 16-битный стек :)
push fs будучи выполнено из CODE32 в 32-битный стек сохраняет туда
32-битное слово, но _не_ расширяет его нулями, вместо них старшие
16-бит содержат то что там было.

> Еще что можно заметить, так это то, что прямо перед
> инструкцией "pop fs" было прерывание (прямо над вершиной
> стека 3 двойных слова: fff18c30 00000168 00012046 --
> eip, cs и регистр флагов).

мне почему то кажется, что это данные обработчика trap e ;)

> Пока не знаю, как узнать, что это было за прерывание
> и как попасть в его обработчик. Возможно, он и поместил
> в стек мусор (00202246).

надо узнать что за прерывание было обработано в этом вызове intIRQRouter.
и смотреть обработчик прерывания этого драйвера.
думаю это можно сделать по имеющимся данным. во всяком случае можно попробовать..

> Пока непонятно, что значит ebp=00000004, ведь ebp
> должен указывать на базу кадра стека, а здесь он
> указывает вообще за пределы стека. Может, это тоже
> особенность expand-down стеков, или все-таки ошибка?

он никуда никому не должен указывать.
он _может_ указывать на стек фрейм, если такой код будет написан.

судя по коду intIRQRouter там как раз [e]bp не используется для указания на кадр.
к тому же оно неопределено после возврата из драйвера.

> ЗЗЗЗЫ
> А что ты можешь сказать насчет того, какая здесь
> связь: трап в кернеле, нехватка стека и новый большой
> жесткий диск (Barracuda 80 Gb)? Ведь все траблы начались
> именно с установкой нового винта, со старым (ibm 60 Gb)
> такого не было. У KuiSa-Ka вообще 2 терабайта массив,
> а глюков почему-то нет. Тут наверно имеет значение
> комбинация винт-контроллер-драйвера-ядро. Я ставил
> и более новые ядра (стабильные -- 14.065, 14.085, и
> с тесткейса -- 14.089E), обновлял os2dasd, danis506,
> ibm1s506, но проблема как была, так и есть.
> (А может быть имеет значение то, что у KuiSa-Ka наверное
> JFS, а у меня HPFS386?)
> Глюки по идее должны быть где-то в драйверах дисков,
> но они почему-то в ядре.

глюки получились на выходе из обработчика прерывания.

> Кстати, у меня один раз трап-
> нулось в os2dasd.dmd. Может, проблема именно в os2dasd?
> Может, os2dasd передает неправильный запрос ядру, а то
> от этого трапается? В общем, не знаю, раскручивать надо.

ну типа ядро, все драйвера, IFS - они все в ring0, потому любая несогласованность их между собой и любая ошибка в ком либо из них, например, которая будет проялвяться только при втыкании определенного винта(большого ;)) может проявиться в любом из этих компонентов.
там же все связано друг с другом..


Sat 25 Jan 2003 03:00 Mozilla/5.0 (OS/2; U; Warp 4.5; en-US; rv:1.2.1) Gecko/20021




Programmed by Dmitri Maximovich, Dmitry I. Platonoff, Eugen Kuleshov.
25.09.99 (c) 1999, RU/2. All rights reserved.
Rewritten by Dmitry Ban. All rights ignored.