View previous topic :: View next topic |
Author |
Message |
remittor
Joined: 21 Oct 2019 Posts: 19 Location: Russia
|
(Separately) Posted: Fri Nov 15, 2019 18:58 Post subject: Что должен делать плагин при получении Out of memory? |
|
|
Ни в одном плагине для TotalCmd я не нашёл обработку ошибки Out of Memory.
Сейчас пишу wcx-плагин, в котором все места с выделением дин. памяти имеют проверки. И в случае возникновения оной ошибки управление через ret дойдёт до TotalCmd.
Но честно говоря, в этой ситуации просто хочется вызвать RaiseException и забыть.
Так может так и стоит делать?
В этом случае TotalCmd завершит работу с ошибкой. |
|
Back to top |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Sat Nov 16, 2019 03:08 Post subject: |
|
|
Сознательно грохать Тотал при возникновении проблемы в плагине — это, конечно, сильно. Лично я бы такой плагин первым делом снёс.
В API не зря предусмотрены различные коды ошибок в качестве возвращаемых значений. Если возникает нештатная ситуация, считается, что разработчик плагина должен её обработать в своём коде и вернуть ошибку Тоталу, чтобы тот понял, что операция не удалась. И, кстати, нужно не забывать при этом освобождать ресурсы, чтобы файлы не оставались заблокированными, а память не утекала. _________________ Почему же, ё-моё, ты нигде не пишешь "ё"? |
|
Back to top |
|
|
remittor
Joined: 21 Oct 2019 Posts: 19 Location: Russia
|
(Separately) Posted: Sat Nov 16, 2019 12:43 Post subject: |
|
|
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 |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Sat Nov 16, 2019 14:23 Post subject: |
|
|
Ну, доступные ресурсы — это такая вещь… Сейчас он свалился от нехватки памяти, а следующий запрос на выделение пройдёт успешно из-за того, что какая-то жирная программа освободила блок или вовсе завершила работу. Кроме того, крошечные блоки могут превратиться в некрошечные, если их размер зависит от внешних факторов. Например, пользователь сдуру открыл десятигигабайтный файл, плагин начал его читать в память (крошечными блоками), исчерпал объём, получил исключение и свалился. Грохать весь Тотал в такой ситуации неразумно, ибо ресурсов в системе для нормальной работы вполне достаточно (если, конечно, плагин освободит всю эту сожранную им память). _________________ Почему же, ё-моё, ты нигде не пишешь "ё"? |
|
Back to top |
|
|
remittor
Joined: 21 Oct 2019 Posts: 19 Location: Russia
|
(Separately) Posted: Sat Nov 16, 2019 15:31 Post subject: |
|
|
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 |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Sun Nov 17, 2019 15:52 Post subject: |
|
|
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 |
|
|
|
|
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
|