Tum*_*oid 7 linux embedded memory-leaks init upstart
我在Upstart init进程(pid 1)中有内存泄漏,我在调试时有哪些选项?
编辑:建议我一些真正的工具,手动输入printfs或手动计算内存分配不会削减它.同时转储init核心并探索它并不是一个真正的选择.
UPD1: valgrind不起作用.使用正确的valgrind + init magic替换内核命令行上的/ sbin/init似乎不是一个选项,因为它尝试访问/ proc for self for smaps,但是在init运行之前它们不可用.
UPD2: dmalloc也不起作用(不在ARM上编译).
一个穷人的解决办法是只要登录每一个电话malloc和free,然后通过日志梳理和寻找模式.
ld 提供了一个可以在这里提供帮助的惊人功
--wrap=symbol使用符号包装函数.任何未定义的符号引用都将解析为"__wrap_symbol".对"__real_symbol"的任何未定义引用都将解析为符号.
这可用于为系统功能提供包装器.包装函数应该被称为"__wrap_symbol".如果它想调用系统函数,它应该调用"__real_symbol".
这是一个简单的例子:
Run Code Online (Sandbox Code Playgroud)void * __wrap_malloc (size_t c) { printf ("malloc called with %zu\n", 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>, <bt-symbol-2>, .. */
__real_free(addr);
}
Run Code Online (Sandbox Code Playgroud)
用调试符号(-g)重新编译upstart,这样你就可以获得一些不错的回溯.-O2/-O3如果您愿意,您仍然可以优化()代码.
Link Upstart与额外的LD_FLAGS --wrap=malloc,--wrap=free.
现在任何Upstart调用malloc符号都将神奇地解析为您的新符号__wrap_malloc.精美的这对于编译代码来说是透明的,因为它发生在链接时.
这就像填补或检测任何混乱.
像往常一样运行重新编译的Upstart,直到您确定已发生泄漏.
查看日志中的不匹配malloceds和addrs.
几个笔记:
--wrap=symbol功能不适用于实际为宏的函数名称.所以要小心#define malloc nih_malloc.在这libnih做什么,你就需要使用--wrap=nih_malloc和__wrap_nih_malloc替代.| 归档时间: |
|
| 查看次数: |
2758 次 |
| 最近记录: |