Как обнаружить нехватку памяти?

Как определить, вызван ли segfault нехваткой памяти?

У меня есть segfault, который не поддается диагностике с помощью valgrind и duma/efence, потому что он, кажется, приводит к сбою этих инструментов (Valgrind «случилось невозможное», duma: «mprotect() failed: Cannot allocate memory»)

Приложение (Gazebo) просто вылетает из-за segfault и трассировки стека, которая, кажется, не дает много подсказок, почему.

TLDR: Существует ли простой инструмент или метод для подтверждения или исключения того, что нехватка памяти является причиной сбоя сегментации?

(вверху не отображается чрезмерное использование памяти перед сбоем)


person Catskul    schedule 25.05.2011    source источник


Ответы (1)


В Linux состояние нехватки памяти может проявляться одним из двух способов:

  • Если overcommit отключен, вызов brk() или mmap() завершится ошибкой с ENOMEM. Вскоре после этого приложение пытается разыменовать указатель NULL, возвращенный из malloc(), и аварийно завершает работу.
  • Если overcommit включен, то срабатывает убийца OOM и уничтожает процесс с помощью SIGKILL. Сообщение оставлено в dmesg.

Таким образом, вы можете исключить OOM, проверив, что strace не показывает вызовы brk() или mmap() с ошибкой с ENOMEM, и убедившись, что в dmesg не появляются сообщения об уничтожении OOM.

person bdonlan    schedule 26.05.2011
comment
Так что, если я делаю strace -c и не вижу ошибок для brk или mmap, это на 100% не проблема с нехваткой памяти (при условии, что dmes не показывает информацию об убийцах OOM)? [править: исправление опечатки] - person Catskul; 26.05.2011
comment
strace не является системным. Но да, это и проверить dmesg - person bdonlan; 26.05.2011
comment
Вы можете использовать sysctl vm.overcommit_memory, чтобы узнать, какую политику overcommit использует ваше ядро. Вероятно, это 0, что трудно интерпретировать, но в любом случае стоит знать. Кроме того, проверьте в журнале strace() mremap(), которую glibc использует при увеличении стека. - person Nemo; 26.05.2011