我在Upstart init进程(pid 1)中有内存泄漏,我有什么选项来debugging它?
编辑:build议我一些真正的工具,手动将printfs或手动计算内存分配不会削减它。 也倾销初始核心和捅周围是不是一个真正的select。
UPD1: valgrind不起作用。 在内核命令行上用适当的valgrind + init魔术replace/ sbin / init似乎不是一个选项,因为它试图访问smaps的/ proc,但是在init运行之前,这些不可用。
UPD2: dmalloc也不能正常工作(不能在ARM上编译)。
检测C ++ / windows中的内存泄漏
内存泄漏时使用DnsGetCacheDataTable
audiodg.exe不断增长与我调用每个哔声()函数。 系统不释放内存
屏蔽图书馆泄漏的应用程序
为什么保留的虚拟内存增长,而目前使用的虚拟内存不增长?
这个valgrind错误是什么意思?
如何在命令行上使用红门ant分析器
boost ::线程导致小事件处理泄漏?
如何在Win32中查找资源泄漏?
如何用C库在Python程序中刷新内存?
一个穷人的解决办法是只记录每个呼叫malloc和free ,然后梳理日志和寻找模式。
--wrap=symbol
使用符号的包装函数。 任何未定义的符号引用将被解析为“__wrap_symbol”。 对“__real_symbol”的任何未定义的引用将被解析为符号。
这可以用来为系统功能提供包装。 包装函数应该被称为“__wrap_symbol”。 如果它希望调用系统函数,它应该调用“__real_symbol”。
这是一个微不足道的例子:
void * __wrap_malloc (size_t c) { printf ("malloc called with %zun",c); return __real_malloc (c); }
如果使用–wrap malloc链接其他代码,则所有对“malloc”的调用将调用函数“__wrap_malloc”。 在“__wrap_malloc”中对“__real_malloc”的调用将调用真正的“malloc”函数。
你也可以提供一个“__real_malloc”函数,这样没有–wrap选项的链接将会成功。 如果你这样做,你不应该把“__real_malloc”的定义放在与“__wrap_malloc”相同的文件中; 如果这样做,汇编程序可能会在链接器有机会将其包装到“malloc”之前解析调用。
更新
只是要清楚这是如何有用的。
喜欢这个:
void*__wrap_malloc( size_t c ) { void *malloced = __real_malloc(c); /* log malloced with its associated backtrace*/ /* something like: <malloced>: <bt-symbol-1>,<bt-symbol-2>,.. */ return malloced } void __wrap_free( void* addr ) { /* log addr with its associated backtrace*/ /* something like: <addr>: <bt-symbol-1>,.. */ __real_free(addr); }
用调试符号( -g )重新编译新手,这样你可以得到一些不错的回溯。 如果您愿意,您仍然可以优化( -O2/-O3 )代码。
用额外的LD_FLAGS链接Upstart --wrap=malloc ,– --wrap=free 。
现在任何地方Upstart调用malloc的符号将神奇地解决你的新符号__wrap_malloc 。 精美地说,这对编译后的代码来说是透明的,因为它发生在链接时。
这就像填补或摆脱任何混乱。
像往常一样运行重新编译的Upstart,直到确定发生了泄漏。
通过日志查找不匹配的malloced s和addr s。
几个注意事项:
--wrap=symbol功能不适用于实际为宏的函数名称。 所以请注意#define malloc nih_malloc 。 这就是你需要使用的--wrap=nih_malloc和__wrap_nih_malloc 。
使用gcc的内置追溯功能。
所有这些更改只影响重新编译的Upstart可执行文件。
你可以转储日志到一个sqlite数据库,而可能会更容易找到不匹配的malloc和释放。
你可以使你的日志格式成为一个sql插入语句,然后将它们插入到数据库中进行进一步的分析。
你也可以不改变地使用init,但是创建一个包装器,将MALLOC_CHECK环境变量设置为1或者更高 。 这会让你看到一些内存分配的诊断。
一个变化是稍微改变init源代码,以便在开始使用malloc之前尽早设置这个环境变量。
您也可以像AmineK建议的那样,将调试代码添加到init源代码本身。
你可以通过hook malloc / free调用你自己的内存分配,并计算你分配的字节数,每次释放。
你可以试试把你的新贵与Google的tcmalloc联系起来 。 它配有一个内置堆检查器 。
堆检查器可以通过两种方式启用:
将环境变量HEAPCHECK设置为{normal |中的一个 严格| 严酷的}。
将HEAPCHECK设置为local并使用HeapProfileLeakChecker对象手动检查代码。
但是我不知道如何为init设置一个环境变量。
如何在进程中运行pmap并检查哪些内存段正在增长。 这可能会给你一些什么饮食记忆的想法。 一个小脚本可以使这个过程几乎自动**。
**在过去的一段时间里,我实际上写了一个脚本,这个脚本会把一组正在运行的进程的pmap快照分隔开来。 这个输出被输入到一个perl脚本中,用来识别改变它们大小的段。 我用它来定位一些商业代码中的一些内存泄漏。 [我会分享这些脚本,但是这些脚本属于以前雇主的知识产权(版权)。]
约翰
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。