在输出中可以看到,已经调用了 fcntl() 函数,它要在一个文件上设置锁。在这里,这个函数会一直等待到成功地设置锁,然后才继续运行。不幸的是,另一个进程已经锁住了这个文件,所以第二个应用程序必须等待第一个应用程序使用完文件并释放锁。
对于这种情况,truss 有点儿局限性:它无法指出要锁住哪个文件,也无法指出当前锁住了哪个文件,从而阻碍了第二个程序的执行。这是因为跟踪过程是在已经调用了打开文件的函数之后启动的。truss 和 strace 只跟踪在它们执行期间调用的函数;它们无法查明已经调用的函数。
获取堆栈跟踪
可以看出,truss 对于监视整个程序很有用,但是对于监视已经启动的程序可能有点儿局限性。如果使用基于 SVR4 的 Unix,比如 Solaris 或 AIX,那么 pstack 命令可能有帮助。
pstack 命令实际上属于一组进程检查命令,这些命令输出正在运行的进程的相关信息。其他工具包括 pfiles(输出进程使用的文件的列表)和 psig(显示信号和信号处理函数的列表)。
在使用这些命令时,需要指定进程的 PID。pstack 命令输出一个正在运行的进程的调用堆栈,显示在进程到达当前函数之前调用的函数。例如,对正在等待被锁住的文件的进程使用 pstack,会产生清单 8 中的输出。
清单 8. 对正在等待被锁住的文件的进程使用 pstack
$ pstack 15828
15828: ./errlock
feef0877 fcntl (3, 7, 8047ac4)
feedcd49 fcntl (3, 7, 8047ac4, 8050e74) + 91
08050f10 main (1, 8047b24, 8047b2c) + d8
08050cdc _start (1, 8047c08, 0, 8047c12, 8047c7d, 8047c8e) + 80
标签: