Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Что должен делать плагин при получении Out of memory?

 
Post new topic   Reply to topic    Total Commander Forum Index -> Написание плагинов для Total Commander printer-friendly view
View previous topic :: View next topic  
Author Message
remittor



Joined: 21 Oct 2019
Posts: 14
Location: Russia

Post (Separately) Posted: Fri Nov 15, 2019 18:58    Post subject: Что должен делать плагин при получении Out of memory? Reply with quote

Ни в одном плагине для TotalCmd я не нашёл обработку ошибки Out of Memory.

Сейчас пишу wcx-плагин, в котором все места с выделением дин. памяти имеют проверки. И в случае возникновения оной ошибки управление через ret дойдёт до TotalCmd.

Но честно говоря, в этой ситуации просто хочется вызвать RaiseException и забыть.

Так может так и стоит делать?
В этом случае TotalCmd завершит работу с ошибкой.
Back to top
View user's profile Send private message
CaptainFlint



Joined: 14 Dec 2004
Posts: 5955
Location: Москва

Post (Separately) Posted: Sat Nov 16, 2019 03:08    Post subject: Reply with quote

Сознательно грохать Тотал при возникновении проблемы в плагине — это, конечно, сильно. Лично я бы такой плагин первым делом снёс.

В API не зря предусмотрены различные коды ошибок в качестве возвращаемых значений. Если возникает нештатная ситуация, считается, что разработчик плагина должен её обработать в своём коде и вернуть ошибку Тоталу, чтобы тот понял, что операция не удалась. И, кстати, нужно не забывать при этом освобождать ресурсы, чтобы файлы не оставались заблокированными, а память не утекала.
_________________
Почему же, ё-моё, ты нигде не пишешь "ё"?
Back to top
View user's profile Send private message
remittor



Joined: 21 Oct 2019
Posts: 14
Location: Russia

Post (Separately) Posted: Sat Nov 16, 2019 12:43    Post subject: Reply with quote

CaptainFlint wrote:
Сознательно грохать Тотал при возникновении проблемы в плагине — это, конечно, сильно.

Во всех плагинах, что я видел, не перехватывается исключение EOutOfMemory/bad_alloc, что ведёт к завершению работы процесса с выдачей ошибки.
Да там вообще нет никакой обработки исключений.
Если в плагине юзается System.String/std::string , то без обработки исключений есть шанс словить EOutOfMemory от плагина.

CaptainFlint wrote:
Лично я бы такой плагин первым делом снёс.

В плагинах DEB И RPM используется System.String и при этом вообще нет отлова исключений. Поэтому можно смело сносить эти плагины, т.к. они могут сгенерить исключение EOutOfMemory.
К тому же в плагине DEB нет проверки результата GetMem, что тоже может привести к "падению" TotalCmd.

В плагине Office2007wlx используется оператор new() , но перехвата исключения bad_alloc нету. Вообще нету try/catch!!!

В плагине NTLinks проверяется результат malloc. А вот результат realloc (вызывается внутри какого то объекта) не проверяется совсем никак.

CaptainFlint wrote:
В API не зря предусмотрены различные коды ошибок в качестве возвращаемых значений. Если возникает нештатная ситуация, считается, что разработчик плагина должен её обработать в своём коде и вернуть ошибку Тоталу, чтобы тот понял, что операция не удалась.

Всегда так и делаю. Вопрос был о другом. Сейчас сам TotalCmd никак не обрабатывает EOutOfMemory/bad_alloc. Поэтому при реальной нехватке памяти вы управление возвратите в TotalCmd, но он сам при этом "свалится" при первой работе с System.String и т.п.

Поэтому и встаёт вопрос: а нафига заморачиваться с ловлей EOutOfMemory/bad_alloc (для крошечных блоков памяти), коли сам TotalCmd не ловит эти исключения?
Back to top
View user's profile Send private message
CaptainFlint



Joined: 14 Dec 2004
Posts: 5955
Location: Москва

Post (Separately) Posted: Sat Nov 16, 2019 14:23    Post subject: Reply with quote

Ну, доступные ресурсы — это такая вещь… Сейчас он свалился от нехватки памяти, а следующий запрос на выделение пройдёт успешно из-за того, что какая-то жирная программа освободила блок или вовсе завершила работу. Кроме того, крошечные блоки могут превратиться в некрошечные, если их размер зависит от внешних факторов. Например, пользователь сдуру открыл десятигигабайтный файл, плагин начал его читать в память (крошечными блоками), исчерпал объём, получил исключение и свалился. Грохать весь Тотал в такой ситуации неразумно, ибо ресурсов в системе для нормальной работы вполне достаточно (если, конечно, плагин освободит всю эту сожранную им память).
_________________
Почему же, ё-моё, ты нигде не пишешь "ё"?
Back to top
View user's profile Send private message
remittor



Joined: 21 Oct 2019
Posts: 14
Location: Russia

Post (Separately) Posted: Sat Nov 16, 2019 15:31    Post subject: Reply with quote

CaptainFlint wrote:
Ну, доступные ресурсы — это такая вещь… Сейчас он свалился от нехватки памяти, а следующий запрос на выделение пройдёт успешно из-за того, что какая-то жирная программа освободила блок или вовсе завершила работу.

Всё верно. Для этого все и должны использовать RAII + try/catch.
Но в описанной вами ситуации сам TotalCmd может в классе System.String или GetMem сгенерировать EOutOfMemory.
Получается, что TotalCmd можно болт забивать на ловлю исключений, а нам нельзя?

CaptainFlint wrote:
Кроме того, крошечные блоки могут превратиться в некрошечные, если их размер зависит от внешних факторов. Например, пользователь сдуру открыл десятигигабайтный файл, плагин начал его читать в память (крошечными блоками), исчерпал объём, получил исключение и свалился.

Зачем весь десятигигабайтный файл читать целиком в память?

CaptainFlint wrote:
Грохать весь Тотал в такой ситуации неразумно, ибо ресурсов в системе для нормальной работы вполне достаточно.

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

Что должен делать плагин, когда в конструкторе какого либо класса произошёл EOutOfMemory при инициализации динамической строки System.String/std::string ?
Из конструктора код ошибки не возвратить. Нужно обрамлять в try/catch весь код.
Back to top
View user's profile Send private message
CaptainFlint



Joined: 14 Dec 2004
Posts: 5955
Location: Москва

Post (Separately) Posted: Sun Nov 17, 2019 15:52    Post subject: Reply with quote

remittor wrote:
Получается, что TotalCmd можно болт забивать на ловлю исключений, а нам нельзя?

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

remittor wrote:
Зачем весь десятигигабайтный файл читать целиком в память?

Да мало ли ситуаций… Скажем, плагин просмотра картинок, который не ожидал, что его вызовут на гигапиксельную Hubble eXtreme Deep Field. Или просмотр кода с подсветкой синтаксиса, где некоторые грамматики требуют полного парсинга. Ну или бывает, что сам файл держать в памяти необязательно, можно обрабатывать потоковым алгоритмом, но результаты парсинга в итоге занимают столько же, а то и больше места (как какой-нибудь JSON, XML).

remittor wrote:
Что должен делать плагин, когда в конструкторе какого либо класса произошёл EOutOfMemory при инициализации динамической строки System.String/std::string ?
Из конструктора код ошибки не возвратить. Нужно обрамлять в try/catch весь код.

Учитывая, что API не является объектно-ориентированным, на верхнем уровне всё равно будет реализация какого-нибудь ListLoad(). Я не вижу, в чём проблема обернуть содержимое этого метода в один большой try/catch. Сложнее, конечно, разобраться с освобождением ресурсов, если исключение всё же произошло, но тут уже от конкретного кода всё зависит.
_________________
Почему же, ё-моё, ты нигде не пишешь "ё"?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Написание плагинов для Total Commander All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group