ltrace —— 追踪进程的共享库调用(strace 的库级补充)
这个工具是做什么的
strace 追踪的是系统调用(进入内核),ltrace 追踪的是用户态共享库函数调用(如 malloc、strlen、pthread_mutex_lock、read 的 libc 包装)。当问题在用户态库层(内存分配频繁、字符串处理、库函数报错)而系统调用看不出名堂时,用 ltrace 看库函数级调用。
可以回答什么问题
| 问题 | 怎么用 |
|---|---|
| 进程在频繁调用哪些库函数? | ltrace -c -p <PID> 汇总统计 |
| malloc/free 调用得多频繁(用户态分配热点)? | ltrace -e malloc,free -c ./prog |
| 某个库函数返回了什么错误? | ltrace -e *libc.so* ./prog 看返回值 |
| 多线程里锁函数调用情况? | ltrace -e pthread_mutex_* -c ./prog |
| 想只跟踪某个库(如 libssl)? | ltrace -e '*libssl*' ./prog |
数据来源
- 来源接口:同样基于
ptrace,在进程每次进入和退出动态库函数时拦截(通过 PLT/GOT 表跳转注入断点)。 - 采集方式:逐次拦截库函数调用,输出函数名、参数、返回值。
- 由此决定的特性:只对动态链接的库函数有效——静态链接的程序、内联展开的函数、以及由汇编直接调用的系统调用(不经 libc 包装)都看不到;开销与 strace 同级(每个调用多两次上下文切换),同样只适合短时诊断。
⚠️ 局限:只跟踪动态库函数;静态链接/内联的看不到。开销大,别在生产热路径长时间挂。
一、启动参数
bash
ltrace ./prog # 启动并跟踪新进程
ltrace -p <PID> # 附加到运行中的进程
ltrace -f -p <PID> # -f 跟踪子进程/线程
ltrace -c ./prog # 汇总统计(最有用,类比 strace -c)
ltrace -e malloc,free ./prog # 只跟踪指定函数
ltrace -e '*libssl*' ./prog # 只跟踪某库内的函数(通配符)
ltrace -e @./list.txt ./prog # 从文件读函数列表
ltrace -o trace.log ./prog # 输出到文件
ltrace -S ./prog # -S 同时显示系统调用(混合模式)二、输出样例
bash
$ ltrace -c ./cpu_demo
% time seconds usecs/call calls function
------ ----------- ----------- --------- --------------------
57.42 0.152471 152471 1 memcpy
21.05 0.055893 1863 30 malloc
12.33 0.032741 1637 20 free
9.20 0.024428 1221 20 strlen
------ ----------- ----------- --------- --------------------
100.00 0.265533 71 total三、判断口诀
| 现象 | 判读 |
|---|---|
malloc/free 调用次数暴多 | 用户态内存分配热点,考虑对象池/减少小对象分配 |
memcpy 单次耗时极高 | 大块内存拷贝,可能有超大 buffer 或零散大块移动 |
pthread_mutex_lock 频繁 | 锁竞争在用户态层面,配合 perf lock 深入 |
库函数返回 NULL/错误码 | 定位用户态函数级错误根源 |
一句话总结:strace 看"进内核干了啥",ltrace 看"在库层干了啥"——用户态分配/字符串/锁这类热点用 ltrace,系统调用类用 strace,两者互补。