哪里执行了我的API?
在Linux端开发服务端程序,经常能遇到某个API被执行了,但是只看到执行后的效果,却不能明确是哪个线程执行的,更不清楚其执行路径。
如果是自己实现的API,那调试起来还好说,加些打印,加些日志,也能糊弄过去。但如果是系统调用,STL容器操作,那操作起来就有点麻烦了,也许你会想到GDB调试。
attach上去后,打好断点,然后等着复现,但是最大的问题是,灵活度受限,在必现的问题面前还好,但在偶现的问题面前,就显的力不从心。
下面介绍几种在Linux下,我经常用到的Hook技术,来协助我们定位问题。
偷梁换柱
1. GDB
GDB 不仅是一个调试工具,还可以用来编写脚本进行代码注入和修改。
set breakpoint pending on
set pagination off
set print pretty
set logging file gdb.out
set logging on
define FuncGdbHook
set scheduler-locking on
shell date '+%Y-%m-%d %H:%M:%S'
printf "\n===== %s BEGIN =====\n", $arg0
finish
printf "\n===== %s END =====\n", $arg0
backtrace
info locals
set scheduler-locking off
continue
end
break fopen
commands $bpnum
FuncGdbHook "FOPEN"
end
break fclose
commands $bpnum
FuncGdbHook "FCLOSE"
end
run
- 使用
gdb -x mygdb.script a.out --args ...
- gdb attach后,
source mygdb.script
- 测试
/***************************************************************
@file : gdb_hook.cpp
@brief :
@details :
@author : AisinGioroBanana
@version : 1.0.0.0
@date : 2024-10-28 17:58:07
***************************************************************/
#include <bits/stdc++.h>
using namespace std;
int main()
{
auto file = fopen("gdb_hook", "r");
if (file == NULL)
{
perror("fopen");
exit(EXIT_FAILURE);
}
printf("File opened successfully.\n");
if (fclose(file) != 0)
{
perror("fclose");
exit(EXIT_FAILURE);
}
printf("File closed successfully.\n");
return 0;
}
g++ gdb_hook.cpp -g