Получение трассировки стека из Perl Ошибка «Недостаточно памяти» - PullRequest
5 голосов
/ 14 июня 2011

tl; dr: Как вывести трассировку стека perl, когда процессу Perl httpd не хватает памяти.

У нас есть сервер mod_perl 2, Perl 5.8.8, RHEL 5.6, Linux 2.6.18.

Очень иногда и непредсказуемо дочерний процесс httpd начинает использовать всю доступную память с угрожающей скоростью.Мы по крайней мере использовали BSD :: Resource :: setrlimit (RLIMIT_VMEM, ...), так что процесс умирает с «Недостаточно памяти» перед тем, как отключить сервер.

Мы не знаем, гдев коде это происходит, и его трудно воспроизвести без часов нагрузочного тестирования.

Что нам действительно нужно, так это способ получить трассировку стека Perl непосредственно перед запуском процессане хватает памяти, поэтому мы знаем, какой код вызывает это.К сожалению, «Недостаточно памяти» - это необратимая ошибка .

Вот варианты, которые я рассматриваю, каждый со своими недостатками:

1) Используйте $ ^ M пул аварийной памяти .Требует от нас перекомпиляции perl с -DPERL_EMERGENCY_SBRK и -Dusemymalloc.

2) Положите тонны операторов журнала, затем проанализируйте журналы, чтобы увидеть, где процесс останавливается.

3) Написатьвнешний сценарий, который постоянно сканирует пул процессов httpd и, если он видит один, использующий много памяти, отправляет ему сигнал USR2 (который мы организовали для вывода следа стека).

4) Как-топроцесс непрерывно контролирует собственную память и выводит трассировку стека, когда объем памяти увеличивается, но до появления ошибки «Недостаточно памяти».

Спасибо!

Джон

Ответы [ 3 ]

3 голосов
/ 14 июня 2011

Вы можете получить обратную трассировку с помощью mod_backtrace, см. Введение Энди Миллара . Обратный след находится на уровне C, поэтому вам нужно либо

  • немного внутренних знаний Perl для вывода стека Perl, просто взглянув на обратную трассировку или
  • для запуска gdb, установите точку останова в функции crashy и проверьте стек Perl и лексические переменные с помощью макросов gdb из книги mod_perl.
2 голосов
/ 14 июня 2011

Вы можете попробовать использовать LD_PRELOAD для загрузки пользовательской версии malloc / free.Не должно быть необходимости связывать или перекомпилировать что-либо.Просто установите для LD_PRELOAD .so, который имеет тот же интерфейс, что и malloc, и эта предварительно загруженная версия malloc будет загружена вместо обычной системной malloc при запуске вашего исполняемого файла.Например, это общая стратегия для обнаружения ошибок памяти с efence .

Я не думаю, что efence будет работать для вас здесь, поскольку это для обнаружения перезаписи памяти, а не отладки из памяти (я не знаю, что она делает в OOM)Я думаю, что вы можете проверить failmalloc .Я никогда не использовал этот, но похоже, что он может делать то, что вы хотите (я только просмотрел первую полосу).

0 голосов
/ 16 мая 2018
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...