本文详细介绍在嵌入式设备中使用Malloc Hook的试验
在嵌入式设备中,计划使用malloc hook来进行内存跟踪,以便测试程序的内存使用。
试验1:
在程序开始,增加了mtrace函数,定义环境变量MALLOC_TRACE。
发现了两个问题:1、程序运行很慢 2、日志文件大小上升的很快,在嵌入式设备中,这样基本不可用。
考虑变通方法,能否将mtrace的环境变量 MALLOC_TRACE定义为stdout,这样既不用写内存,又不会占用磁盘空间,输出可以通过telnet客户端来进行记录。
解决方法:
通过glibc的源代码可以看到,glibc通过fopen打开MALLOC_TRACE对应的文件。
将MALLOC_TRACE=/dev/stdout,这样mtrace的所记录的日志,就全部打印在终端上。
在有些嵌入式linux中,没有stdout。可以发现,/dev/stdout为一个连接文件,其真实指向是/proc/self/fd/1。我们将MALLOC_TRACE=/proc/self/fd/1也是可以的。
试验2:
在MALLOC_TRACE=/proc/self/fd/1后,运行测试程序。
问题还是速度慢,看来速度的瓶颈不在于写磁盘。通过查看glibc的源代码,速度的瓶颈,主要在于
if (_dl_addr (caller, &info, NULL, NULL))
{
char *buf = (char *) "";
if (info.dli_sname != NULL)
{
size_t len = strlen (info.dli_sname);
buf = alloca (len + 6 + 2 * sizeof (void *));
buf[0] = '(';
__stpcpy (_fitoa (caller >= (const __ptr_t) info.dli_saddr
? caller - (const __ptr_t) info.dli_saddr
: (const __ptr_t) info.dli_saddr - caller,
__stpcpy (__mempcpy (buf + 1, info.dli_sname,
len),
caller >= (__ptr_t) info.dli_saddr
? "+0x" : "-0x"),
16, 0),
")");
}
fprintf (mallstream, "@ %s%s%s[%p] ",
info.dli_fname ?: "", info.dli_fname ? ":" : "",
buf, caller);
}立刻解析对应的代码。
那么我们可以考虑,在程序运行的时候,不去做相应的解析,只是记录下当时的指针,事后再通过其他软件对数据解析。
那么只能自己来写hook函数。
#include <malloc.h>
static void* (* old_malloc_hook) (size_t,const void *);
static void (* old_free_hook)(void *,const void *);
static void my_init_hook(void);
static void* my_malloc_hook(size_t,const void*);
static void my_free_hook(void*,const void *);
void(*__malloc_initialize_hook)(void) = my_init_hook;
static void my_init_hook(void)
{
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
static void* my_malloc_hook(size_t size,const void *caller)
{
void *result;
__malloc_hook = old_malloc_hook;
result = malloc(size);
old_malloc_hook = __malloc_hook;
printf("@%p + %p %#lx
",caller,result,(unsigned long int)size);
__malloc_hook = my_malloc_hook;
return result;
}
static void my_free_hook(void *ptr,const void *caller)
{
__free_hook = old_free_hook;
free(ptr);
old_free_hook = __free_hook;
printf("@%p - %p
",caller,ptr);
__free_hook = my_free_hook;
}测试成功,对于速度影响不大,接下来的问题,便是如何解析log的内容。
其实在日志中,如果分配和释放指针能够对应上,那么我们就没有必要关心对应的代码,剩余少量的对应不上的内存操作,我们才需要。因此通过指针找到对应代码的运算量应该不大。
根据内存分配的日志,我们可以看到有哪些内存泄漏,可以看到最后堆的地址,从而判断堆所占用的物理内存空间。
责编:豆豆技术应用
- Linux/Unix新闻
- Linux/Unix入门
- Linux/Unix命令
- Linux/Unix安装
- Linux/Unix编程
- Linux/Unix管理
- Linux/Unix桌面
- Linux/Unix内核
- Linux/Unix软件
- Linux/Unix发行版
- redhat/Fedora
- Ubuntu Linux
- IBM AIX
- FreeBSD
- Solaris
- NetBSD
- SCO Unix
- find基本用法
- ldd命令原理及用法例子
- su和sudo命令的区别与使用技巧
- Linux操作系统下的dd命令技巧
- 关于Top命令的参数详解
- 关于Tar命令的使用
- SSH实用技巧及常用命令使用
- Linux后台执行命令
- VI命令使用技巧集锦
- Vmstat命令列出的属性详解
- 如何查看及修改文件读写权限
- 最大可存储的单文件容量
- ext2/ext3文件系统介绍
- 常用压缩格式的压缩解压方法
- Linux系统的引导过程详细解析
- Configure参数解释说明
- Linux下硬盘和分区的命名方法
- 硬链接与软链接的区别
- 权限和所有权模型
- 存储设备的两种表示方法