Chinaunix首页 | 论坛 | 博客
  • 博客访问: 210315
  • 博文数量: 145
  • 博客积分: 3000
  • 博客等级: 中校
  • 技术积分: 1720
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-14 18:42
文章分类

全部博文(145)

文章存档

2011年(1)

2009年(144)

我的朋友

分类: LINUX

2009-07-22 19:12:49

by tangke 2009-06-08
 
 
源程序如下:
详见 http://blog.chinaunix.net/u/30686/showart_262547.html
#include
#include
int main(void)
{
    char *p=(char*)malloc(20);
    strcpy(p,"hello,world!\n");
    printf("%s",p);
    return 0;
}
>strace  hello
输出如下,我将一行一行的进行分析
execve("/home/e11963/szw/hello/hello", ["/home/e11963/szw/hello/hello"], [/* 27 vars */]) = 0
uname({sys="Linux", node="e11963-lnx", ...}) = 0
brk(0)                                  = 0x9a2f000
//该行主要目的是返回当前堆的虚拟地址。
open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
//运行程序时,要分为两步,linker and loader。猜测这行是将linker加载到内存,注意返回值3,在下面做old_mmap时将用到
fstat64(3, {st_mode=S_IFREG|0644, st_size=61838, ...}) = 0
old_mmap(NULL, 61838, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb75e6000
//检查了一下/etc/ld.so.cache的大小,果真为61838,具体参数的意思,大家可以参见mmap的说明。
close(3)                                = 0
open("/lib/i686/libc.so.6", O_RDONLY)   = 3
//开始加载库函数
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0p\\\1\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1560180, ...}) = 0
//1560180为该文件大小。
old_mmap(NULL, 1283620, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x8d8000
//1283620要比该文件小,鉴于内存属性为READ和EXEC,估计是加载code段。
old_mmap(0xa0c000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x134000) = 0xa0c000
old_mmap(0xa0f000, 9764, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xa0f000
//该段内存可写,估计是data段,MAP_ANONYMOUS的含义不清楚。
close(3)                                = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75e5000
//这块内存,不知道什么用处。
munmap(0xb75e6000, 61838)               = 0
//这时候linker已经没有用了,从内存中释放掉。
brk(0)                                  = 0x9a2f000
brk(0x9a50000)                          = 0x9a50000
//对应malloc(20),brk最少申请一个页,glibc再在堆内存上进行管理。
brk(0)                                  = 0x9a50000
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
//makedev(136,1)  136为字符终端设备,开始准备打印
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75f5000
//为字符终端申请内存
write(1, "hello,world!\n", 13hello,world!
)          = 13
munmap(0xb75f5000, 4096)                = 0
//将为字符终端申请的内存释放掉。
exit_group(0)                           = ?
Process 4078 detached
 
int main(void)
{
    return 0;
}
结果
execve("/home/e11963/szw/hello/hello", ["/home/e11963/szw/hello/hello"], [/* 27 vars */]) = 0
uname({sys="Linux", node="e11963-lnx", ...}) = 0
brk(0)                                  = 0x8413000
open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=61838, ...}) = 0
old_mmap(NULL, 61838, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb75e9000
close(3)                                = 0
open("/lib/i686/libc.so.6", O_RDONLY)   = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0p\\\1\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1560180, ...}) = 0
old_mmap(NULL, 1283620, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x645000
old_mmap(0x779000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x134000) = 0x779000
old_mmap(0x77c000, 9764, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x77c000
close(3)                                = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75e8000
munmap(0xb75e9000, 61838)               = 0
exit_group(0)                           = ?
Process 4347 detached
//即使程序什么都不做,也会加载ld和libc函数库。
 
源程序
#include
int main(void)
{
    char *p=(char*)malloc(10);
    malloc(10);
    free(p);
    return 0;
}
结果
。。。。。。。。
munmap(0xb75ea000, 61838)               = 0
brk(0)                                  = 0x8645000
brk(0x8666000)                          = 0x8666000
brk(0)                                  = 0x8666000
exit_group(0)                           = ?
Process 4383 detached
虽然malloc了两次,但只做了brk一次,说明glibc在上面做了堆管理。
并且free并没有做系统调用,将内存直接返回给内核。
关于glibc如何做的堆管理还有待研究。
阅读(182) | 评论(0) | 转发(0) |
0

上一篇:commands:常见问题

下一篇:oprofile 龙芯调试

给主人留下些什么吧!~~