从Perl获取堆栈跟踪“内存不足”错误

问题描述

| tl; dr:当Perl httpd进程内存不足时,如何转储perl堆栈跟踪。 我们有一个mod_perl 2服务器,Perl 5.8.8,RHEL 5.6,Linux 2.6.18。 非常偶然且不可预测的是,子httpd进程开始以惊人的速度耗尽所有可用内存。我们至少使用了BSD :: Resource :: setrlimit(RLIMIT_VMEM,...),以便在关闭服务器之前,该进程以\“ Out of memory \”终止。 我们不知道代码在哪里发生,并且如果不进行数小时的负载测试就很难重现。 我们真正想要的是一种在进程内存耗尽之前获取Perl堆栈跟踪的方法,因此我们知道是什么代码导致了这一点。不幸的是,“内存不足”是无法捕获的错误。 这是我正在考虑的选项,每个选项都有其缺点: 1)使用$ ^ M紧急存储池。要求我们使用-DPERL_EMERGENCY_SBRK和-Dusemymalloc重新编译perl。 2)输入大量的日志语句,然后分析日志以查看该进程在何处停止。 3)编写一个外部脚本,该脚本不断扫描httpd进程池,如果发现其中一个使用大量内存,则向其发送USR2信号(我们已安排该信号转储堆栈跟踪)。 4)以某种方式让进程连续监视自己的内存,并在内存变高但在“内存不足”错误之前转储堆栈跟踪。 谢谢! 乔恩     

解决方法

        您可以尝试使用LD_PRELOAD加载自定义版本的malloc / free。不必重新链接或重新编译任何内容。只需将LD_PRELOAD设置为具有与.so具有相同接口的.so,在运行可执行文件时,将加载此预加载版本的malloc,而不是常规系统malloc。例如,这是一种有效检测内存错误的常用策略。 我认为efence在这里不适合您,因为这是用于检测内存覆盖,而不是调试内存不足(我不知道它对OOM的作用)。我认为您可能想检查一下failmalloc。我从来没有使用过它,但听起来它可能可以满足您的要求(我只浏览了首页)。     ,        您可以通过
mod_backtrace
得到回溯,请参阅Andy Millar的介绍。回溯在C级别上,因此您要么需要 一点点Perl内部知识,只需查看回溯或 要运行gdb,请在crashy函数处设置一个断点,并使用mod_perl书中的gdb宏检查Perl堆栈和词法变量。     ,        根据实用mod_perl的说法,在您的代码中添加
Apache::Debug level => 4;
将导致其分配$ ^ M紧急池并调用
Carp::confess()
。 https://books.google.co.vi/books?id=i3Ww_7a2Ff4C&pg=PT699&lpg=PT699&dq=how+do+i+get+a+stack+trace+when+perl+dies+with+an+out+of+ memory + error&source = bl&ots = Id7ll9Gng2&sig = r8SpZ4jvFfjzfM2eSmoV2DjWLnY&hl = zh-CN&sa = X&ved = 0ahUKEwiwqNitporbAhXow1kKHZo9CRoQ6AEIODAC#v = onepage&q = how%20 %% 20 %% 20 %% 20%20%20%20%20%20%20%20 %% 20do20%20%20%20%20%20%20%20%20%20%20%有20%的球友20错误&f = false     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...