Chinaunix首页 | 论坛 | 博客
  • 博客访问: 192594
  • 博文数量: 73
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 1160
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-23 15:53
文章分类

全部博文(73)

文章存档

2011年(1)

2009年(72)

我的朋友

分类: LINUX

2009-04-23 16:47:05

Hello world的系统调用分析

源程序如下:

详见 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
要比该文件小,鉴于内存属性为READEXEC,估计是加载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
//
对应malloc20,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

//即使程序什么都不做,也会加载ldlibc函数库。

 

 

 

 

源程序

#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如何做的堆管理还有待研究。

阅读(512) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~