文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>linux 下利用gdb + bash 实现类似gflags的功能

linux 下利用gdb + bash 实现类似gflags的功能

时间:2010-05-28  来源:slimzhao

在真实的程序执行环境下, 一个进程可能不能通过gdb filename的方式来调试, 原因:
1. 父进程为它准备了socket
2. 你进程打开了一些文件.

所有父进程为它进行的积累, 在直接运行程序时不会出现.

所以, 需要有一种方法, 在另一程序fork / execl一个新程序时, 有机会在该程序的最开始比如main断住.

假设程序为test2,
mv test2 test2.real
cat > test2 <<END
#!/bin/bash

while [ -z "$GDB_READY" ] ; do
        echo sleep 1 second...
        export FORCE_REFRESH_ENV=1
        sleep 1
        export -n FORCE_REFRESH_ENV
done

exec ./test2.real "$@"
END

这段脚本偷梁换柱取代了原来的ELF格式可执行文件, 在它被执行时, 不停地循环, 循环的条件是检测一个叫
GDB_READY的环境变量.

这样, 在该程序被调用时, 相当于阻塞在了exec调用上, 原因是该环境变量不存在.

在另一终端中, 用ps ax | grep test2 找到PID,
gdb -p PID
调试该bash 进程. 通过
p setenv("GDB_READY", "1")

为该进程设置环境变量, 从而退出上面的while循环, 在设置之后, 先不能急于continue, 因为断点还没设置.

symbol-file ./test2.real -readnow
可以在尚未load该进程时, 提前告之gdb,
然后可以:
b test2.c:main

continue

会在该进程的main处断住.

bash脚本中FORCE_REFRESH_ENV 是最让人迷惑的地方, 如果没有export + export -n, 整个方案就不行, 这是因为bash会对环境变量作一个cache, 这两个动作保证能引发它刷新该cache, 这样下一次循环时才能判断出变量GDB_READY 是否真正设置了.

bash对 $GDB_READY的实现并不是直接调用 getenv, 而是在一个内部的hash中去找.
相关阅读 更多 +
排行榜 更多 +
火柴人战争血腥打击

火柴人战争血腥打击

飞行射击 下载
沉浸式射击比赛

沉浸式射击比赛

飞行射击 下载
银河世界

银河世界

飞行射击 下载