电脑技术学习

跟踪 UNIX 应用程序的解决方案

dn001

  在这两个输出中,每个输出行对应于应用程序执行的一个函数调用,其中显示函数的参数和函数调用的返回值。与调试示例不同,列出的每个函数调用都是系统或系统库中的函数,因此表示调用的函数的更低层接口。例如,在应用程序中可能使用 C 或 C++ 中的 fpopen() 函数打开文件,但是这个函数实际上是更低层的 open() 函数的包装器。

  了解应用程序正在执行的操作并不需要了解每个函数的情况。输出中的许多行与操作系统为装载和执行程序所做的初始化相关。这两个跟踪输出的基本结构是相同的:

  调用 execve() 函数以启动一个新程序。

  装载程序所需的库。在 Solaris 输出中,首先使用 resolvepath() 寻找库,然后使用 open() 打开库。对于 Linux,使用 stat() 检查库是否存在,然后使用 open() 打开它。

  为进程保留和分配一些内存。其中一部分内存是为应用程序保留的堆栈空间,一部分用来保存程序,其他内存保存程序使用的变量。

  最后,执行程序,调用 write() 函数输出年龄和生日信息。

  如果执行跟踪并希望了解每个步骤的具体情况,可以使用 man 命令访问每个函数的手册页。

  识别应用程序启动问题

  在启动应用程序时的一个典型问题是,程序无法正确地初始化,但是在终止时给出一个不完整或导致误解的消息。对应用程序运行跟踪常常可以揭示这个问题的根源。例如,清单 5 显示一个测试应用程序运行失败了。

  清单 5. 应用程序失败

$ ./errnoacc 
ERROR: Application failed to initialize 

  错误消息并没有提供关于应用程序为什么会启动失败的具体信息。在这里,问题是故意引入的,但是您使用的任何命令或应用程序都可能出现相同的问题,而错误消息没什么帮助,有时候甚至没有错误消息。

标签: