GDB中用set logging on可记录所有交互内容,需先set logging file指定日志路径再set logging on;gdbserver不记录调试细节,仅-v显示连接信息;程序输出需重定向其stdout/stderr。

gdb 里用 set logging on 启动日志捕获
远程调试时想留痕,最直接的方式不是靠 shell 重定向,而是用 GDB 自带的 set logging on。它会把所有你在 (gdb) 提示符下输入的命令、GDB 的输出(包括断点命中、变量值、栈回溯等)原样记入文件,不受 target remote 连接方式影响。
操作很简单:
- 启动 GDB 后先执行
set logging file gdb.log(可选,不设则默认为gdb.txt) - 再执行
set logging on - 接着做常规远程连接:
target remote 192.168.1.100:2345、break main、run等,全部会被记录 - 退出前用
set logging off停止写入,避免后续调试混入无关内容
注意:日志只记录交互内容,不包含程序 stdout/stderr 输出——那是被调试进程自己的行为,得另想办法捕获。
gdbserver 不输出调试日志,但可加 -v 查看连接状态
gdbserver 本身没有“保存调试日志”的功能,它默认静默运行。你看到的 Remote debugging from host 192.168.1.1 这类提示,仅在标准错误(stderr)输出,且只在连接建立/断开时打印一次,不会持续记录。
如果想确认连接是否成功、有没有被拒绝,启动时加 -v 参数:
-
gdbserver -v :2345 ./program—— 会显示监听地址、协议版本、线程模型等信息 - 若出现
Connection refused,说明本地 GDB 没连上,问题一定出在防火墙、端口占用或 gdbserver 未运行,而不是日志没开
别指望靠 gdbserver 日志查断点触发细节——它不记录那些。
想同时捕获被调试程序的 printf 输出?得重定向它的 stdout/stderr
很多人误以为 set logging on 能记下 printf("count=%d\n", count) 的内容,其实不能。那些是目标进程的输出,和 GDB 交互日志是两回事。
要保留程序自身的打印,必须在启动 gdbserver 时重定向:
-
gdbserver :2345 ./program > program.log 2>&1—— 把 stdout 和 stderr 都写进文件 - 或者用
nohup防止终端关闭导致中断:nohup gdbserver :2345 ./program > program.log 2>&1 & - 注意:如果程序用了行缓冲(比如通过
printf打印但没换行),可能需要手动fflush(stdout),否则日志延迟出现甚至丢失
容易忽略的路径与权限问题
日志文件默认写在 GDB 当前工作目录,不是源码目录,也不是 gdbserver 所在目录。如果你在 /home/user 启动 GDB,日志就生成在那儿;而 gdbserver 在嵌入式设备上运行,它写的 program.log 就在它启动时的工作目录下——很可能不是 /tmp,也未必有写权限。
常见踩坑点:
-
gdbserver启动用户无权写目标路径,日志文件为空或根本创建失败 - 路径含中文或空格,导致重定向失效(用引号包住整个重定向部分也不总可靠)
- 嵌入式设备磁盘空间小,
program.log暴涨撑爆根分区 -
set logging file指定的路径不存在,GDB 不报错但写入失败,日志静默丢失
最稳妥的做法:始终用绝对路径,且提前确认读写权限,尤其是跨设备调试时——别假设路径存在或可写。











