New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

С ru-board: падение FarColorer при некорректном вызове через Plugin.Call(MainGuid,0) #19

Closed
VictorVG opened this Issue Feb 15, 2017 · 8 comments

Comments

Projects
None yet
4 participants
@VictorVG
Copy link

VictorVG commented Feb 15, 2017

С форума ru-board: падение FarColorer при некорректном вызове через Plugin.Call(MainGuid,0)

Alexyz21

Проверял на 4882. Запускаем FAR, в комстроке вводим: lua:Plugin.Call("D2F36B62-A470-418D-83A3-ED7A3710E5B5",0), Enter, получаем падение Colorer - это нормально? - Если да, то как объехать? Если до того того открывали редактор, то всё работает - открывается меню колорера.

вызов явно не корректен и по идее должен игнорироваться, а не падать.

Факт падения на b4898 x64 Win7 SP1 если выдать команду lua:Plugin.Call("D2F36B62-A470-418D-83A3-ED7A3710E5B5",0) сразу после запуска Far подтверждаю, падает с AV в OpenW():

Исключение: Нарушение доступа (чтение из 0x00000000000000F8)
Адрес: 0x000007FEE35F205D GetMinFarVersionW
Функция: OpenW
Модуль: .\Far\plugins\editor\colorer\bin\colorer.dll

Стек:

0x000007FEE35F205D GetMinFarVersionW
0x000007FEE35F153C OpenW
0x000000013FF65607
0x000000013FF64985
0x000000013FF625CD
0x0000000140033904
0x0000000140032E05
0x000000013FFEB3D6
0x0000000140018F0C
0x000007FEE5912A87 LF_LoadFile
0x0000000066D82C13
0x0000000066D8EF93 lua_pcall
0x000007FEE5910891 LF_SetFindList
0x000007FEE59109B2 LF_SetFindList
0x000007FEE591253C LF_LoadFile
0x000007FEE58D8FF8 OpenW
0x000000013FF65607
0x000000013FF64985
0x000000013FF625CD
0x0000000140033904
0x0000000140032E05
0x000000013FFE5AA3
0x000000013FFE5B36
0x000000013FFE6B75
0x000000013FFDF155
0x000000013FFDF773
0x000000013FFE01AD
0x000000013FFFBA5D
0x000000013FFFB8ED
0x000000013FFF64E9
0x000000013FFF8A60
0x000000013FFF8CBB
0x000000013FFF8D78
0x000000013FFF8DA6
0x000000013FFF8D30
0x00000001400F1E89
0x0000000076C259CD BaseThreadInitThunk
0x0000000076E5A561 RtlUserThreadStart

Far.mdmp.7z (~22 Mb, 7-Zip v16.04, LZMA, SOLID, MAXIMUM) на момент падения (дамп развернётся на 100 Мб) прилагаю.

Запись на Мантисе: M#3396, только констатация факта:)

@z0hm

This comment has been minimized.

Copy link

z0hm commented Feb 15, 2017

Я не согласен, что вызов должен игнорироваться - должны игнорироваться только пункты, относящиеся к непосредственной работе в редакторе, конфигурация должна быть доступна.

@VictorVG

This comment has been minimized.

Copy link
Author

VictorVG commented Feb 15, 2017

Диалог, который зовётся данным вызовом может быть обработан только после запуска и инициализации плагина, а если он зовётся в момент запуска, то некорректный по смыслу вызов должн быть проигнорирован чтобы не происходило падения. Это нормальная защита от ошибок оператора и по другому делать нельзя.

Идея звать диалог до инициализации плагина а после удивляться тому, что он упал аналогична тому как водитель вызвавший аварию в своё оправдание говорит "Я рулю правильно, это дорога кривая!".:)

@shmuz

This comment has been minimized.

Copy link

shmuz commented Feb 15, 2017

@z0hm, если всё, что вам нужно из панелей - это меню конфигурации, то для этого есть Plugin.Config. (Естественно, падать при вызове Plugin.Call нехорошо).

@VictorVG

This comment has been minimized.

Copy link
Author

VictorVG commented Feb 15, 2017

Добавлю - первопричина падения это нарушение временной последовательности событий когда более поздняя по времени операция - вызов подпрограммы осуществляется до того как запустится и инициализируется основная процедура что приводит к неопределённому состоянию задачи на момент его обработки и передаче управления по случайному адресу с непредсказуемыми последствиями, а потому такой вызов должен по умолчанию игнорироваться либо его обработка должна происходить по следующему алгоритму:

If main_procedure_ready Then Call(subroutin) Else 
        Begin:
          m1:: If main_procedure_ready Then Call(subroutin) Else Wait(main_procedure_ready) End;
           If ReturnCode(subroutin) == True Then Goto done Else Goto m1 End; 
        End;
End;
done::

но, не падать, ибо падение это исключительная ситуация говорящая о том, что алгоритм не смог обработать ошибку.

@z0hm

This comment has been minimized.

Copy link

z0hm commented Feb 15, 2017

В момент вызова Plugin.Call() неизвестно в каком состоянии находится плагин, соответственно корректная отработка вызова целиком и полностью в его зоне ответственности. Если какие-либо структуры не проинициализированы, то нужно их инициализировать и лишь затем выполнять код обработки вызова.

@VictorVG

This comment has been minimized.

Copy link
Author

VictorVG commented Feb 15, 2017

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

ctapmex added a commit that referenced this issue Feb 19, 2017

@ctapmex ctapmex added the bug label Feb 19, 2017

@ctapmex ctapmex closed this Feb 19, 2017

@VictorVG

This comment has been minimized.

Copy link
Author

VictorVG commented Feb 19, 2017

Добренько, соберём.

@VictorVG

This comment has been minimized.

Copy link
Author

VictorVG commented Feb 19, 2017

Готово, лежит у меня в ./Far3, собрано в VC++2010, х86 для XP SP3, AMD64 для Vista и выше (линкер вставляет четыре функции fls*() по информации MSDN реализованные начиная с Vista).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment