Bug 2399

Summary: Циклическая генерация исключений
Product: WINE@Etersoft Reporter: Alexeev Alexey <alexeev>
Component: ОбщееAssignee: Anton Rudnev <mibori>
Status: CLOSED FIXED QA Contact:
Severity: minor    
Priority: P4 CC: kondratyuk, lav, night
Version: 1.0.9   
Target Milestone: ---   
Hardware: PC   
OS: All   
URL: http://rt.etersoft.ru/Ticket/Display.html?id=7964
Whiteboard:
Заявки RT: Связано с:
Дата напоминания:
Bug Depends on: 2357    
Bug Blocks: 1802    
Attachments: решение

Description Alexeev Alexey 2008-09-09 18:08:47 MSD
Вылетает с следующим сообщением:
user@host:~> wine --attach /home/user1/all
First running... Using WINEPREFIX=/home/serg/.wine
Using shared WINE tree in /home/user1/all
Device 'c:' created as link for '/home/user1/all' target.
WINE@Etersoft 1.0 Network (1.0.9), registration number is 665D-0024.
Legality check is available on the page http://sales.etersoft.ru/product/.

Initialize registry and environments...
ALSA lib seq_hw.c:457:(snd_seq_hw_open) open /dev/snd/seq failed: Нет
такого файла или каталога
err:rpc:I_RpcReceive we got fault packet with status 0x3e6
err:seh:setup_exception_record stack overflow 28 bytes in thread 000b eip
7de20980 esp 00241314 stack 0x240000-0x241000-0x340000

Список установленных пакетов:
host:/home/user # rpm -qa | grep wine
wine-1.0.9-eter17suse
libwine-1.0.9-eter17suse
wine-etersoft-network-1.0.9-eter5suse

Пробовал воспроизвести через предоставленный клиентом ssh, воспроизвести не получилось из-за возникшей ошибки из баги 2357. Скорее всего, получится воспроизвести после устранения 2357.
Comment 1 Константин Кондратюк 2008-09-11 12:55:27 MSD
*** Bug 2131 has been marked as a duplicate of this bug. ***
Comment 2 Константин Кондратюк 2008-09-11 13:14:12 MSD
Та же проблема на ALT Linux в current-сборке.
Comment 3 Константин Кондратюк 2008-09-11 15:20:21 MSD
Сразу после ошибки RPC возникает исключение:

0009:Call KERNEL32.RaiseException(000003e6,00000000,00000000,00000000) ret=7eb95415
0009:trace:seh:raise_exception code=3e6 flags=0 addr=0x7b842c10
0009:trace:seh:raise_exception  eax=7b82c86d ebx=7b8b287c ecx=00000000 edx=00000000 esi=0033a5e0 edi=0033a560
0009:trace:seh:raise_exception  ebp=0033a548 esp=0033a4e4 cs=0073 ds=007b es=007b fs=0033 gs=003b flags=00000246

А потом происходит зацикливание на вот таких строках, вплоть до переполнения:

0009:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7e23a9b0
0009:trace:seh:raise_exception  info[0]=00000000
0009:trace:seh:raise_exception  info[1]=7e23a9b0
0009:trace:seh:raise_exception  eax=00000000 ebx=7bc8a44c ecx=7bc928a4 edx=7bc928b8 esi=014f45b0 edi=0033a0e0
0009:trace:seh:raise_exception  ebp=0033a0f8 esp=0033a08c cs=0073 ds=007b es=007b fs=0033 gs=003b flags=00010293
Comment 4 Константин Кондратюк 2008-09-11 17:36:51 MSD
Похоже, что при вызове исключения возникает ситуация, когда исключения начинаются генерироваться циклически. 
К --attach не имеет прямого отношения, переформулирую багу.
Comment 5 Константин Кондратюк 2008-09-11 17:37:42 MSD
Возникает в current-сборке (стоит на euclid) и в вайне, собранном из git.
Comment 6 Константин Кондратюк 2008-09-12 12:55:53 MSD
Не проявляется в alt20 (сборка уже стоит на euclid).
Так что воспроизведение возможно только на старой сборке или в какой-то другой ситуации.
Comment 7 Vitaly Lipatov 2008-09-12 13:05:01 MSD
Должно легко воспроизводится на сборке из git, но возникает только в случае,
если mountmgr.sys грузится (на некоторых системах этого не происходит).
Comment 8 Anton Rudnev 2008-09-22 19:20:19 MSD
наконец удалось воспроизвести багу.

с патчем из 1990, при установленной WINESEHBLOCK подвисает сразу перед строчками

err:rpc:I_RpcReceive we got fault packet with status 0x3e6
err:seh:setup_exception_record stack overflow 1724 bytes in thread 0009 eip 7bc3b9cb esp 00230c74 stack 0x230000-0x231000-0x330000

причину, пока не знаю.
Но пока информации из http://bugs.etersoft.ru/show_bug.cgi?id=2399#c3 достаточно, чтобы начать копать, в месте генерации исключения.
Comment 9 Anton Rudnev 2008-09-22 22:33:36 MSD
> с патчем из 1990, при установленной WINESEHBLOCK
Опрос строки из stdin, как и вывод в stdout оканчивается неудачей.
Скорее всего потому, что ни того ни другого не существует.
Из за этого анализа входной строки не происходит, и REPL зацикливается до бесконечности.

Первая мысль которая приходит в голову - опрашивать с GUI.
Вторая мысль, если stdin и stdout блокируются/не существуют, то их надо разблокировать/создать...



Comment 10 Anton Rudnev 2008-09-23 15:40:39 MSD
> Вторая мысль, если stdin и stdout блокируются/не
> существуют, то их надо
> разблокировать/создать...

идея реализовать ввод/вывод через fopen("/dev/tty", "rb+") пока терпит неудачу.
При обычном исключении работает нормально (вводит и выводит по дескриптору).
Но когда возникает то самое исключение, которое потом повторяется рекурсивно, fopen возвращает ноль, т. е. не дает открыть /dev/tty
Comment 11 Vitaly Lipatov 2008-09-25 22:37:48 MSD
Обсуждение вопроса управления из консоли в случае закрытых дескрипторов 0, 1
лучше вести в другой баге.
Comment 12 Anton Rudnev 2008-09-26 13:16:45 MSD
(In reply to comment #11)
> Обсуждение вопроса управления из консоли в
> случае закрытых дескрипторов 0, 1
> лучше вести в другой баге.

да, по конкретной баге следующее...
в общем случае при обработке исключения функцией raise_exception
сначала запускаются обработчики VEH, а уж потом SEH.
Так вот здесь мы имеем дело с VEH исключением.

шаг 0
В где-то посередине процесса выполнения команды ww wineboot --update функция DllMain из dlls/ntoskrnl.exe/ntoskrnl.c добавляет через RtlAddVectoredHandler векторный обработчик исключения. В качестве векторного обработчика выступает функция vectored_handler из того же dlls/ntoskrnl.exe/ntoskrnl.c

шаг 1
После этого, когда происходит какое-либо исключение и начинают выполнятся векторные обработчики, первым выполняется как раз vectored_handler (по краней мере функция с таким же адресом, которая была установлена через RtlAddVectoredHandler).

шаг 2
сразу как только она выполняется, вызывается программное исключение с кодом c0000005 - Access Violation. Т. е. выполнение функции vectored_handler не происходит вообще (не заходит внутрь ее). Из чего следует предположить, что память, в которой располагается функция vectored_handler не executable.
Т. к. вызывается исключение Access Violation мы переходим к шагу 1

При этом в шаге 1 до раскрутки стека дело не доходит, с каждом вызовом vectored_handler вызывается raise_exception и таким образом стек переполняется.
----------
на вскидку самое простое решение этому - проверка в raise_exception области памяти векторного обработчика исключения на executable.

но вопрос, почему память получается не executable остаётся...
----------
Comment 13 Anton Rudnev 2008-10-07 18:24:16 MSD
> но вопрос, почему память получается не
> executable остаётся...

при LoadLibrary ntoskrnl.DllMain добавляет новый обработчик исключений
но когда происходит FreeLibrary, ntoskrnl.DllMain не удаляет его

После этого, при возникновении любого исключения вызывается обработчик - функция, которая находится на данный момент в выгруженной библиотеки, поэтому Access Violation.
Comment 14 Anton Rudnev 2008-10-07 18:26:15 MSD
Created attachment 771 [details]
решение

решение проблемы

п.с.: возможно бага: не всегда, но появляется где-то не закрытая критическая секция.