Всем привет! Допустим, имеем процесс А, запущенный от пользователя входящего в группу администраторов. Так же, имеем процесс Б, в группу администраторов не входящий. Процесс А должен быть всегда запущен. Предположим, что процесс Б, начинает выделять память в цикле до полного исчерпания ресурса. В связи с этим, на стороне процесса А будут возникать ошибки при попытках выделения памяти. Вопрос. Как вести себя процессу А в такой ситуации? Поразмыслив, пришел к тому, что есть два пути: 1) Отлавливать соответствующие ошибки и корректировать алгоритм программы в случае обнаружения нехватки ресурсов. Недостаток такого подхода в сложности реализации. Ладно WinAPI. Сфэйлила, допустим, VirtualAlloc. Если код ошибки говорит нам, что нет физической памяти, то проверяем карту памяти нашего процесса. Если утечка не у нас, тогда пытаемся выделить память позже (как вариант). Но ведь есть сторонние библиотеки. Их код мы так не контролируем. Тут, видимо, придется ставить хуки внутри своего процесса на ряд соответствующих функций и разруливать ситуацию внутри обработчиков этих хуков. Кстати, некоторые WinAPI могут бросать исключения в ситуации нехватки ресурсов. InitializeCriticalSection например. 2) Устанавливать квоты для пользователей. При таком подходе, мы предполагаем, что нехватки ресурсов быть не может. Если та же VirtualAlloc сфэйлила с соответствующим кодом, то можно считать, что утечка у нас. Снимаем дамп и завершаемся. Тут возникают следующие вопросы. Какие есть средства (может какие-нибудь WinAPI) для установки квот в Windows XP - 10? Есть ли сторонний софт, для решения подобных задач? Вот, к примеру, нагуглил: Terminal Services and Windows System Resource Manager. Пока сильно не изучал, но вроде то что нужно. Но как быть без локальной сети?
Andrey333, В общем случае такие утечки не решаемы, так как память часто выделяется в ядерном пуле(рабочий набор апп не изменен). Зацикли QueueUserApc() вся память системы будет исчерпана, если конечно лимит не ввели в 10-ке на длину очереди. Можно и в гуй сообщение послать до исчерпания памяти..
Снять дамп, записать лог и завершить выполнение программы, других вариантов нет. Утечки ловить на стадии тестирования.
hiddy, Если при вызове каждого сервиса мониторить память, то это тоже ничего не даст. Будет видна только юзер память. Как получить инфу про ядерный аллок в пуле.. кто его знает. Единственный вариант и плохой - хардкодить все сервисы. Но даже если память потекла, даже в юзермод, то как узнать что это утечка, а не штатная аллокация ? В принципе если есть аллокация, то должно быть и освобождение памяти. Тогда можно было бы обнаружить дисбаланс или невалид указатель. А если в системе не хватает памяти, запрос будет отклонён, это не значит что утечка. Странная задача, проще в частном случае отладчиком глянуть, врядле можно найти общее решение.
Потестил пока на XP. Да, действительно, ресурс разделяется между всеми пользователями. И не важно, админские учетки или нет. Для всех одинаково. Но вот что интересно. Для SYSTEM, когда ресурс уже иссяк, можно вызвать QueueUserApc() еще примерно 18000 раз. И такое же поведение наблюдается если создавать kernel-объекты (например циклить CreateEvent()). Т.е. SYSTEM учетка в некоторой степени защищена, но с памятью увы такого нет. --- Сообщение объединено, 22 мар 2020 --- Но это ведь уязвимость! Нам специально исчерпают память.
Andrey333, Врядле есть какая то зависимость от прав. Зачем вам это вообще нужно ? Есть ведь инструменты для диагностики, утечек и дедлоков. Я их никогда не юзал, так как толку от них даже в теории никакого. Единственно полезный механизм это стековый лог, тогда можно понять в какой последовательности функций косяк, причём если он заранее известен. > Нам специально исчерпают память. Если у меня не открывается большой pdf, то это не уязвимость, а память отобрали браузер ида и варя
Тесты показывают, что она есть. Для SYSTEM можно чуть больше ресурсов потребить (кроме физ. памяти). Очевидно, это сделано для того, чтобы система оставалась работоспособной в таких ситуациях. Опишу задачу конкретнее. Есть служба работающая под SYSTEM. Если, в системе нехватка памяти, служба падать не должна. Но, в то же время, если утечка у меня в программе, тогда нужно упасть и снять дамп. Т.к. продолжать работать при утечке - это закапывать ошибку. Представьте себе ситуацию, какая-то программа сожрала всю память (злонамеренно, а может и нет). Это не должно ронять мою службу. Сейчас, я склоняюсь к тому, чтобы похучить VirtualAlloc в процессе службы. В хуках анализировать карту памяти и принимать решение - падать или продолжать работу.
Andrey333, > это сделано для того, чтобы система оставалась работоспособной в таких ситуациях. Интересно каким образом. Пул же общий, может есть какие то теневые механизмы.. > В хуках анализировать карту памяти и принимать решение - падать или продолжать работу. Для начала нужно сформулировать критерий, определяющий что есть утечка и далее как это обнаружить.
Подпишись на уведомления о заканчивающейся памяти: https://docs.microsoft.com/en-us/wi...nf-memoryapi-creatememoryresourcenotification Наверняка у тебя есть какие-то предположения о том, сколько может потреблять сервис. Если обычно он ест десять мегабайт, а съел пару гигабайт - да, явно где-то утечка, можно делать дамп, даже не дожидаясь, пока у системы кончатся ресурсы - проверяй по таймеру. Почему это уязвимость? При отсутствии проверок аллокаций максимум что получишь - Null pointer exception при попытке обратиться к памяти и сервис упадёт. Здесь ничего не "уязвляется". Зарегистрируй VEH и при возникновении таких эксепшнов делай дамп. Или дай сервису упасть и создай ещё один процесс-watchdog с константным потреблением памяти, который будет следить за твоим сервисом и при необходимости дампить\перезапускать.