getcwd("/root", 1013)= 0
resolvepath("/root/ageindays", "/root/ageindays", 1023) = 15
xstat(2, "/root/ageindays", 0x08047880) = 0
open("/var/ld/ld.config", O_RDONLY) = 3
fxstat(2, 3, 0x08047760)= 0
mmap(0x00000000, 144, PROT_READ, MAP_SHARED, 3, 0) = 0xFEFA0000
close(3)= 0
sysconfig(_CONFIG_PAGESIZE) = 4096
xstat(2, "/usr/lib/libc.so.1", 0x08046FA0) = 0
resolvepath("/usr/lib/libc.so.1", "/lib/libc.so.1", 1023) = 14
open("/usr/lib/libc.so.1", O_RDONLY)= 3
mmap(0x00010000, 32768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_ALIGN, 3, 0)
= 0xFEF90000
mmap(0x00010000, 1413120, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, -1, 0)
= 0xFEE30000
mmap(0xFEE30000, 1302809, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_TEXT, 3, 0)
= 0xFEE30000
mmap(0xFEF7F000, 30862, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|
MAP_INITDATA, 3, 1306624) = 0xFEF7F000
mmap(0xFEF87000, 4776, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANON,
-1, 0) = 0xFEF87000
munmap(0xFEF6F000, 65536)= 0
memcntl(0xFEE30000, 187632, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
close(3)= 0
mmap(0x00010000, 24576, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON|MAP_ALIGN,
-1, 0)
= 0xFEE20000
munmap(0xFEF90000, 32768)= 0
getcontext(0x080475D0)
getrlimit(RLIMIT_STACK, 0x080475C8) = 0
getpid()= 15691 [15690]
lwp_private(0, 1, 0xFEE22A00)= 0x000001C3
setustack(0xFEE22A60)
sysi86(SI86FPSTART, 0xFEF879BC, 0x0000133F, 0x00001F80) = 0x00000001
ioctl(1, TCGETA, 0x08046C20)= 0
fstat64(1, 0x08046B80) = 0
You have been alive 10654 days
write(1, " Y o uh a v eb e e".., 31) = 31
You were born on 24/1/1980 which is a Thursday
write(1, " Y o uw e r eb o r".., 47) = 47
_exit(134511508)
在这两个输出中,每个输出行对应于应用程序执行的一个函数调用,其中显示函数的参数和函数调用的返回值 。与调试示例不同,列出的每个函数调用都是系统或系统库中的函数,因此表示调用的函数的更低层接口 。例如,在应用程序中可能使用 C 或 C中的 fpopen() 函数打开文件,但是这个函数实际上是更低层的 open() 函数的包装器 。
了解应用程序正在执行的操作并不需要了解每个函数的情况 。输出中的许多行与操作系统为装载和执行程序所做的初始化相关 。这两个跟踪输出的基本结构是相同的:
调用 execve() 函数以启动一个新程序 。
装载程序所需的库 。在 Solaris 输出中,首先使用 resolvepath() 寻找库,然后使用 open() 打开库 。对于 Linux,使用 stat() 检查库是否存在,然后使用 open() 打开它 。
为进程保留和分配一些内存 。其中一部分内存是为应用程序保留的堆栈空间,一部分用来保存程序,其他内存保存程序使用的变量 。
最后,执行程序,调用 write() 函数输出年龄和生日信息 。
如果执行跟踪并希望了解每个步骤的具体情况,可以使用 man 命令访问每个函数的手册页 。
识别应用程序启动问题
在启动应用程序时的一个典型问题是,程序无法正确地初始化,但是在终止时给出一个不完整或导致误解的消息 。对应用程序运行跟踪常常可以揭示这个问题的根源 。例如,清单 5 显示一个测试应用程序运行失败了 。
清单 5. 应用程序失败
$ ./errnoacc
推荐阅读
- UNIX操作系统复杂的关机过程
- Unix文件名与Windows文件名的差异
- Unix中利用转义和引用来管理元字符
- 自动杀死Unix僵死的进程
- Unix操作系统中处理字符串问题的简单方式
- SCO unix三种安装BTLD的方式
- UNIX及SYBASE的安装
- 在Sco Unix下拨号上网
- 如何自动杀死UNIX僵死的进程
- 下 HP 服务器安装 SCOUNIX 5.0.4/5
