能否将被lldb附加进程的stdout/stderr重定向至lldb控制台?
LLDB附加进程后捕获stdout/stderr到调试控制台
问题描述
测试代码如下:
#include <stdio.h> #include <unistd.h> void example() { printf("Hello, world!\n"); } int main() { sleep(1); sleep(1); sleep(1); }
编译并运行程序:
clang test.c -o test; ./test
在另一个终端通过以下命令将LLDB附加到该进程:
lldb -p $(pgrep -nx test)
在LLDB中执行表达式调用example()函数时:
expr (void) example()
输出会写入原程序的控制台,而非LLDB调试窗口。需要将被附加进程的stdout/stderr重定向到LLDB控制台,以实现用于进程内省的简易REPL工具。
解决方案
方法1:使用LLDB内置命令重定向IO
LLDB自带process redirect-stdio命令,可直接将被调试进程的标准IO重定向到LLDB控制台。附加进程后执行:
process redirect-stdio
执行后,目标进程的stdout/stderr会输出到LLDB控制台,stdin则从LLDB的输入读取。此时再调用expr (void) example(),输出就会显示在LLDB窗口中。
若需精细控制(比如仅重定向特定流),可指定参数:
process redirect-stdio --stdout /dev/tty --stderr /dev/tty
其中/dev/tty需替换为LLDB所在终端的实际路径(可在LLDB终端执行tty命令获取)。
方法2:手动通过代码重定向文件描述符
如果内置命令无法满足需求,可在LLDB中通过表达式调用系统函数,手动修改目标进程的文件描述符:
- 在LLDB所在终端执行
tty,获取终端路径(例如/dev/pts/2) - 在LLDB中依次执行以下表达式:
expr #include <fcntl.h> expr int fd = open("/dev/pts/2", O_WRONLY); dup2(fd, 1); dup2(fd, 2); close(fd);
完成后,目标进程的所有stdout/stderr输出都会转到LLDB控制台。
方法3:启动程序时提前重定向IO
若允许修改程序启动方式,可在运行时将输出重定向到临时文件,再在LLDB中查看:
./test > debug_output.log 2>&1 &
附加LLDB后,可通过LLDB的shell命令实时监控输出:
shell tail -f debug_output.log
这种方法适合需要保留输出日志的场景,但交互性不如前两种方法。
总结
实现进程内省REPL的最优方案是使用LLDB内置的process redirect-stdio命令,无需额外操作即可直接将目标进程的输出捕获到调试控制台,完全满足交互式调试的需求。
内容的提问来源于stack exchange,提问作者Kevin Ushey
相关产品推荐
相关产品推荐

