Выходишь из приложения - освобождаешь ресурсы?

Тема в разделе "WASM.BEGINNERS", создана пользователем hapr, 28 апр 2018.

  1. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Здравствуйте.

    Как я понимаю в Windows в User mode все ресурсы привязаны к процессу и освобождаются при уничтожении его, например через ExitProcess. И соответственно все что используется в течении всей жизни процесса можно спокойно не освобождать, не смотря на постоянные напоминания про это в MSDN.
    Возник у меня этот вопрос потому что сейчас балуюсь с хуками (WH_KEYBOARD_LL и WH_MOUSE_LL ), и перед ExitProcess я не использую UnhookWindowsHookEx для отключения хукав.
    В MSDN есть такое примечания:
    Все бы ни чего, но у меня заглючила уже по одному разу клавиатура и мышь - и меня начали обуревать сомнения может все таки надо перед ExitProcess удалять все хуки?
    Собственно вопрос в том нужно ли освобождать занятые ресурсы приложением или все связанное с приложением само удалиться при выходе с приложения?
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    И чем же они привязаны? Только те которые имеют handle, остальные не факт. Привязывать умели во времена Win311 а после была анархия. А затем с выходом Win7 МС напомнила что разработчикам драйверов следует привязывать свои ресурсы к процессом. И с ново анархия.
     
  3. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Эээ а разве в пользовательском режиме в том или ином виде явна или не явно все имеет хендл? Поэтому по идеи к процессу привязать не сложно...
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    hapr,

    Обьекты уничтожаются при обнулении счётчика ссылок на обьект; эти счётчики работают при референсе/дереференсе на обьект - то самое создание и закрытие описателей. Так же обьект может быть помечен как перманентный, тогда при обнулении числа ссылок обьект не будет уничтожен.

    Освобождать ресурсы необходимо, чистить всё за собой. Во первых иначе это плохой стиль, что может привести к ошибкам. А во вторых поведение такого апп может быть непредсказуемо, так как хуки это IPC.
     
  5. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Теперь понятно с хуками, не удивительно, что у меня уже клавиатура и мышь глючила.

    По поводу освобождения ресурсов когда они уже не нужны, это да, но те которые в течении всей жизни приложения так или иначе используются, думаю смысла освобождать перед выходом нет.
    Я ведь как понимаю все ресурсы типа: меню, память, окна, иконки и т.д. без проблем сами при выходе через ExitProcess освободятся?
     
  6. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    Одно исключение: при выхода из процесса, где освобождение ресурсов (особенно тех которые связанны с памятью) может замедлить выход программы, и негативно повлиять на всю систему, включаю другие процессы. Конкретный пример: если при выходе освобождать свою память на heap'е, которая уже давно программой не использовалась и была убрана из working set'a процесса (paged out), то освобожденее её заставить memory manager операционной системы напрасно вытащить страницу с диска (pagefile) в оперативную память (physical memory, bring back into working set) только для того чтоб heap manager прописал этот блок памяти как свободным и готовым для будущей эксплуатации (которой точно не предвидится, так как процесс выходит из бытья). А вытащить страницу из pagefile'а в оперативную память это дорого, и часто означает что память иной программы (которая раньше занимала этот кусок оперативной памяти) должна быть прописана в pagefile (trim working set).

    Совершенно верно. Если операционная система не умеет надежно справляться с выходом программ которые оставили за собой неубранный мусор, то эта ОС ненадежна по определению. ОС должна быть гарантом стабильности при присутствие нестабильных/небрежных програм.

    Так же верно. Это всё ресурсы заведомые субсистемами NTUSER/NTGDI (win32k.sys или win32kbase/full.sys на более современных версий Win10), и будет подметены этим драйвером при выходе юзерного процесса.
     
    hapr нравится это.
  7. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    comrade,

    Какие то проблемы со свопом меньшие из возможных. Так механизм фильтрации(хуки) глобальный в системе. При отказе его компоненты(части) ляжет весь юзер гуй, к примеру просто зависнет. Эта часть гуй механизма должна реализоваться ответственно, иначе это поломает ось.
     
  8. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    comrade,

    > означает что память иной программы (которая раньше занимала этот кусок оперативной памяти) должна быть прописана в pagefile (trim working set).

    У вас какая то каша в голове :)

    TrimWS" это сброс рабочего набора, локально для процесса или для всей системы, ядро экспортит нужный для этого апи. Впрочем не важно.)
     
  9. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Однозначно не ляжет изо обычных хукав - проверено на практике длительной.
    Плюс если изо этого система бы ложилась, то она так же ложилась бы каждый раз когда приложение убивалась через диспетчер задач.
    Да и проверок в осе много, в тех же хуках есть ограничение на время ответа превысил - отключает хук.
    Хоть само собой допускать до того что бы система принимала спец меры для подержания своего состояния не стоит.
     
  10. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Вот например меню - написано если не связано с окном приложения перед выходом должно явно быть удалено. Но если посмотреть в чужих исходниках то как у кого, кто удаляет а кто нет. В описании VirtualAlloc ничего не указано такого.
    Помниться где то кто то писал, что все хендлы хранятся в структуре процесса и при выходе с процесса система пробегает и все не освобождённые ресурсы освобождает.
    Я лично пришел к выводу, что "само правильно" то что является глобальным и влияет на другие приложения,что бы не было проблем нужно освобождать. А вот меню, курсоры, иконки и т.д. имеют влияние только в кругу одного процесса, поэтому система пусть сама освобождает занимаемую ими память при уничтожение процесса.
     
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    hapr,

    > то она так же ложилась бы каждый раз когда приложение убивалась через диспетчер задач.

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

    Далее под хранение некоторых обьектов используются ядерные пулы, работая с каким то механизмом вы можите не знать, что ядро накапливает данные. Так например можно посылать потоку запросы на apc, это будет накапливать ядро до исчерпания системной памяти. Если подобное не чистить(не освобождать ресурсы), то будут проблемы, особенно с тенью(гуй).

    В любом случае не вижу проблемы, зачем не освобождать ресурсы - лишь только в случае отказа это имеет смысл, внезапное падение апп.
     
  12. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    Вполне возможно я попутался терминами (из за каши в голове или нехватки образования :) ), но суть понятна: другие процессы страдают напрасно.
     
  13. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    Пока на теме, компонент заведующий всеми ресурсами интерфейса (Win32k) крайне нестабилен и допускает множество ошибок, от утечки памяти ядра (information disclosure/leak) до коррупции памятных блоков ядра (kernel pool corruption/memory corruption). Дефекты часто связаны с неправильным учётом ресурсов (пользуется ими кто нибудь ещё или нет, reference counting сломан) что часто эксплуатируется в виде type-confusion или use-after-free атак на ядро.

    Говорю об этом, потому-что если вы что-то найдёте, можно на этом поднять бабло: легальными способами (Microsoft Bug Bounty Program) и сомнительными (продажа эксплойтов на чёрном рынке, типа Zerodium).
     
  14. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Я использую WH_MOUSE_LL и WH_KEYBOARD_LL с ними в Windows 10 в случае их него зависания проблем нет. Насчет остальных загружающие dll в другие процессы не знаю.
    И само собой я понял, что все таки лучше по возможности их штатно завершать.

    Посыл понятен - лучше не надеяться на систему, что подчистит все за приложением. А помочь ей в этом деле.
    В описании MSDN есть "три категории" обьектов:
    Первая объекты в где четко указано при завершении приложения удали, например: hmenu т.д.
    Вторая объекты где четко указано при выходе из приложения они Windows их сама удалит например: hevent, hmenu - связанное с окном и т.д
    И третья есть объекты где не указано ни одно из двух "при завершении приложения удалите объект ", "при завершении приложения объект автоматически будет удален" . Это например: hfont, hwnd, выделенная память через VirtualAlloc и т.д.
    И что тогда делать с объектами из третей категории если в самом MSDN даже не указано, что с ними происходит при завершении приложения, хотя можно конечно при выходе из приложения все закрывать.
    Почему меня это интересует? - все просто хотелось бы четко определить для себя и само собой понять, как же лучше делать при выходе из приложения.
    Освобождать все ресурсы или полагаться на то что Windows освободит все сама, или может освобождать только те ресурсы где это явно указана, что надо делать при выходе?

    Может кто еще поделиться своим мнением, как сам делает в своих программах и почему так делает?
     
  15. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    hapr,
    а что если проверить самому? Например, для приложения только выводящего MessageBox на экран не нужен даже ExitProcess, достаточно обычного RETN. Попробуй запустить 1000000 раз MessageBox и выйти через RETN. Произойдет ли крах у твоей системы? Начнет ли она после этого работать медленнее? Кстати, ExitProcess это переходник к RtlExitUserProcess из ntdll.dll Может быть имеет смысл по окончанию приложения вызывать именно эту функцию? Попробуй создавать окошко, создавать меню и через пару секунд, не удаляя hMenu, закрывать приложение ― возможно, после миллионной попытки ничего и не произойдет? Или произойдет?
     
  16. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    По поводу обычного retn и RtlExitUserProcess в я уже прошел этот этап и успешна обмозговал). Конечно если убрать обёртки и использовать Rtl или Nt это круто ..., но оно того не стоит, так как официальна черно по белому написана, что гарантировано не изменяемость только функций обёрток, поэтому по моему мнению стоит избегать не документированных функций, кроме отдельных случаев.

    По поводу же освобождение ресурсов при выходе тут и дураку понятно, что ос по типу Windows в User mode будет убирать за приложением иначе она просто ляжет. Да и еще кучу проверок делать будет на валидность того что может по влиять на всю систему.

    Но все таки хотелось услышать, как кто что думает насчет уборки ресурсов.

    С MessageBox я задалбусь щелкать ok!
    А вот LoadMenu попробовал - 2500 хендлав она создала прежде чем лимит превысила.
    Но такой тест даже если 1 000 000 выполнить думаю не показательным будет, да и любая Windows в том или ином виде подвержена деградации при активном использовании ресурсов.
     
  17. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    А вот тут по-подробнее... handle вообще или только hMenu?
     
  18. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Не думал, что тут важны подробности, но вот они:

    Функция LoadMenu была вызвана 2500 успешна, после чего на 2501 появилась ошибка - превышен лимит на хендлы типа user.
     
  19. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    hapr,
    а почему, интересно, 2k44, а не, к примеру, 64k? нелогично :scratch_one-s_head:
     
  20. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    861