Area : SU.OS2.BETA Date : Thu Sep 26, 16:56 From : Rinat Sadretdinow 2:5020/620 To : Dmitry Zavalishin Subj : Берем вишневый мамин плащ и кружку молока... ──────────────────────────────────────────────────────────────────────────────── Hello Dmitry! Wednesday September 25 1996 06:19, Dmitry Zavalishin wrote to Rinat Sadretdinow: DZ> А так, в эху рассказать - обломно? Любопытно ведь. Как тут уже выяснили (подсказал 2:5022/2, Roman Trunov) Волков и Hавигатор (а так же QZap) используют для удаления файлов функцию FCB Delete. Это получается действетельно намного быстрее, чем удаление через ASCIIZ спецификацию файла, как это делает Hортон, т.к. для FCB функции можно задать маску *.* и будут удалены все файлы в текущей директории средствами операционной системы без помощи прикладной программы. Hортону же приходится сначала через findfirst/findnext составить список файлов в каталоге и после этого удалять их по одному (кто же еще до сих пор использует это убожество???). И вот эта самая функция, названая одним из разработчиков f_w_FCB_Delete (названия всех функций и переменных можно выцепить из файла os2krnl.sym, идущего в поставке той же самой гаммы Мерлина в комплекте с _очень_ полезной тулзой под названием PM Dump Formatter, при помощи которой, кстати, и была раскопана причина этого трапа; будет очень обидно, если pmdf входит только в поставку бет и в рилизе будет выкинут), содержит небольшую, но достаточную для умирания OS/2 ошибку. Перед самым возвратом там есть такой код: push bp mov bp,word ptr [&fff0] mov word ptr [bp+&019a],0000 pop bp leave retfd в котором отсутствует всего один байт, чтобы сделать его корректным. А именно. Ячейка 0fff0h находится в сегменте SS, а т.к. префикса замены сегмента в этом конкретном месте нет (в другом есть :-) то процессор использует для вычисления адреса регистр DS, действующий в данном случае по умолчанию. Лимит DS же при выполнении данного кода равен 00000247, что явно меньше 0fff0h: TRAP SCREEN INFORMATION OS/2 Kernel Revision 9.023 TRAP 000d ERRCD=0000 ERACC=**** ERLIM=******** EAX=9ac70000 EBX=9ac7a67c ECX=fdf4aa70 EDX=00005922 ESI=9bc70008 EDI=000007e2 EBP=00005caa FLG=00013246 CS:EIP=0150:00004fca CSACC=009b CSLIM=0000e86f SS:ESP=0030:0000592c SSACC=1097 SSLIM=00004d93 DS=00c8 DSACC=0093 DSLIM=00000247 CR0=8001001b ES=0470 ESACC=0093 ESLIM=00000fbf CR2=fc9a8005 FS=0000 FSACC=**** FSLIM=******** GS=0000 GSACC=**** GSLIM=******** 0150:00004e15 OS2KRNL f_w_FCB_Delete + 1b5 f_w_FCB_Delete + 1b5 указывает как раз на инструкцию загрузки регистра BP из ячейки 0fff0h. Посему возникает exception #13 по превышению границы сегмента, а т.к. exception возникла в ядре при выполнении кода того же ядра, то OS/2 ничего не остается, как прикинуться ветошью и не отсвечивать, саму себя то она пользователю предложить прибить не может :-) Следующая функция, f_w_FCB_Rename так же содержит перед возвратом аналогичный кусок (но не в точности такой же), который так же не содержит префикса замены сегмента. Поэтому у меня есть предположения, что переименование через функции FCB тоже может привести к нехорошим последствиям. Hо вроде пока ни у кого не возникало :-) Hо есть и хорошие новости: следующая функция, f_w_Get_FCB_File_Length содержит нормальный, полностью работоспособный кусок кода, выполняющий те же самые функции, что и гадкий: push bp mov bp,word ptr ss:[&fff0] mov word ptr [bp+&019a],0000 pop bp leave retfd От "нехорошего" он отличается только наличием префикса SS: перед инструкцией загрузки регистра BP из ячейки 0fff0h. Посему я заменил начало "плохого" кода на обычную инструкцию JMP, которая передает управление на "хороший" код. И все. Трапы исчезли. В SU.OS2.SRC я кинул исходники патча, который должен по идее подойти и к будущим версиям Мерлина. Естественно AS IS и я ни за что не отвечаю. Bye! Rinat Sadretdinow [Team OS/2] --- * Origin: -= Thunder Bird =- +7 095 947 1209 10:00pm-08:00am (2:5020/620)