已复制
全屏展示
复制代码

gdb在线修改程序的打印日志路径


· 2 min read

一. 场景再现

当你的某个程序正在线上跑着,突然出现了 bug(不一定是 bug,也可能只是想查看下日志),这时你想查询程序输出的日志,由于之前你把日志重定向到 /dev/null 下,所以想要查看日志的话,需要重新修改日志打印路径,重启程序。有没有一种办法可以不重启程序呢,当热有,就是使用 gdb 和 running 着的进程通信,把日志路径修改一下,查看完日志后又修改回去。

二. 实践操作

准备一个程序 test.sh 当做你的线上程序,它的标准输出、标准错误都打到了 /dev/null

  • test.sh
#!/bin/bash
while true
do
    echo "hello at $(date)"
    sleep 1
done
  • console 前台运行程序
bash test.sh >/dev/null 2>&1
  • 新开一个 console 修改打印日志路径
# 查看进程 id,这里是 6080
ps aux | grep test.sh
hdfs      6080  0.0  0.0 113288  1420 pts/1    S+   20:59   0:00 bash test.sh

# 查看已经打开的文件描述符
ll /proc/6080/fd
total 0
lrwx------ 1 hdfs hdfs 64 Jun 13 21:01 0 -> /dev/pts/1
l-wx------ 1 hdfs hdfs 64 Jun 13 21:01 1 -> /dev/null
l-wx------ 1 hdfs hdfs 64 Jun 13 20:59 2 -> /dev/null
lr-x------ 1 hdfs hdfs 64 Jun 13 21:01 255 -> /home/yzy/test.sh

# 使用 gdb 进入刚刚启动的进程
gdb -p 6080
...
(gdb) 

# 关掉文件描述符1,也就是标准输出
(gdb) p close(1)

# 创建新文件,由于刚刚关闭了一个文件描述符,空出一个数字就直接给新创建的文件了
(gdb) p creat("/tmp/test.log", 0600)

# 退出 gdb
(gdb) q
A debugging session is active.

        Inferior 1 [process 6080] will be detached.

Quit anyway? (y or n) y

# 查看进程现在的文件描述符
ll /proc/6080/fd
total 0
lrwx------ 1 hdfs hdfs 64 Jun 13 21:01 0 -> /dev/pts/1
l-wx------ 1 hdfs hdfs 64 Jun 13 21:01 1 -> /tmp/test.log
l-wx------ 1 hdfs hdfs 64 Jun 13 20:59 2 -> /dev/null
lr-x------ 1 hdfs hdfs 64 Jun 13 21:01 255 -> /home/yzy/test.sh

# 查看日志
tail -f /tmp/test.log
hello at Tue Jun 13 21:06:51 JST 2023
hello at Tue Jun 13 21:06:52 JST 2023
hello at Tue Jun 13 21:06:53 JST 2023
hello at Tue Jun 13 21:06:54 JST 2023
hello at Tue Jun 13 21:06:55 JST 2023
  • 当不再需要查看日志时,关闭打印日志
gdb -p 6080
(gdb) 
(gdb) p close(1)
(gdb) p creat("/dev/null", 0600)
(gdb) q


文章推荐