首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Upstart在内存泄漏,您如何调试它?

Upstart在内存泄漏,您如何调试它?
EN

Stack Overflow用户
提问于 2010-10-08 04:34:59
回答 5查看 3.1K关注 0票数 7

我在Upstart init进程(pid 1)中有一个内存泄漏,我在调试它时有哪些选项?

编辑:建议我使用一些真正的工具,手动放置printfs或手工计算内存分配不会减少它。此外,抛出init核心并在其周围穿插并不是一个真正的选择。

UPD1: valgrind不起作用。将内核命令行上的/sbin/init替换为适当的val差使+ init魔术似乎不是一个选项,因为它试图访问smaps的/proc,但在运行init之前这些选项是不可用的。

UPD2: dmalloc也不工作(在ARM上不编译)。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-10-11 16:51:14

穷人的解决方案是只记录每一个调用mallocfree,然后梳理日志并寻找模式。

ld提供了一个非常棒的特性,可以在这里提供帮助。

--wrap=symbol 对符号使用包装函数。对符号的任何未定义的引用将被解析为"__wrap_symbol“。对"__real_symbol“的任何未定义的引用都将被解析为符号。 这可用于为系统功能提供包装器。包装器函数应该称为"__wrap_symbol“。如果希望调用系统函数,则应该调用"__real_symbol“。 下面是一个简单的例子: void * __wrap_malloc (size_t c) { printf ("malloc与%zu\n调用“,c);返回__real_malloc (c);} 如果使用--包装malloc将其他代码链接到此文件,那么所有对"malloc“的调用都将调用函数"__wrap_malloc”。调用"__real_malloc“中的"__wrap_malloc”将调用真正的"malloc“函数。 您可能也希望提供一个"__real_malloc“函数,这样没有-wrap选项的链接就会成功。如果这样做,则不应该将"__real_malloc“的定义与”__wrap_malloc“放在同一个文件中;如果这样做,汇编程序可能会在链接器有机会将其包装为"malloc”之前解析调用。

更新

只是为了弄清楚这是如何有用的。

  • 向Upstart的构建中添加一个自定义文件。

如下所示:

代码语言:javascript
复制
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);
}
  • 用调试符号(-g)重新编译upstart,这样您就可以得到一些不错的回溯。如果您愿意,仍然可以优化(-O2/-O3)代码。
  • 将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的地方。
  • 使用gcc的内建回溯特性。
  • 所有这些更改只影响重新编译的Upstart可执行文件。
  • 您可以将日志转储到sqlite而不是make,这样可以更容易地找到不匹配的错配错误和释放。
  • 您可以让日志格式化SQL语句,然后将它们插入数据库的后期分析以进行进一步的分析。
票数 8
EN

Stack Overflow用户

发布于 2010-10-11 10:32:37

您可以通过连接malloc/free调用,并计算分配的字节数和每次释放的字节数来自行检测内存分配。

票数 2
EN

Stack Overflow用户

发布于 2010-10-11 10:52:32

您也可以不作修改地使用init,但是可以创建一个包装器,它将MALLOC_CHECK环境变量设置为1或更高。这将让您看到一些内存分配诊断。

一个变化是稍微修改init源代码,以便在使用malloc之前尽早设置环境变量本身。

您还可以按照AmineK的建议,将调试代码添加到init源代码本身。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3887723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档