Skip to content

実行中プロセスの標準出力を切り替える

This content is a draft and will not be included in production builds.

コンソールから切れたプロセスを標準出力につなげなおすで、gdb を使って標準出力と標準エラー出力を切り替える方法が示されていた。

Terminal window
(gdb) p close(1)
$1 = 0
(gdb) p open("/dev/pts/5", 1)
$2 = 1
(gdb) p close(2)
$3 = 0
(gdb) p open("/dev/pts/5", 1)
$4 = 2
(gdb) detach

gdb で実現できるならシステムコールまたは類似の仕組みがありそうだなと思っていたところ、retty(1)というコマンドが似たようなことを実現していて、これは ptrace(2)で実装していた。

ptrace(PTRACE_ATTACH, pid, 0, 0);
waitpid(pid, NULL, 0);
ptrace(PTRACE_GETREGS, pid, 0, &regs);
memcpy(&oldregs, &regs, sizeof(oldregs));
read_mem(pid, &text_backup, nelem(attach_code), oldregs.PC_REG);
regs.SP_REG -= sizeof(long);
ptrace(PTRACE_POKEDATA, pid, regs.SP_REG, regs.PC_REG);
write_mem(pid, &attach_code, nelem(attach_code), regs.PC_REG);
regs.SP_REG -= n*sizeof(long);
ptsnameaddr = regs.SP_REG;
write_mem(pid, ptsname, n, regs.SP_REG);
regs.SP_REG -= sizeof(long);
ptrace(PTRACE_POKEDATA, pid, regs.SP_REG, ptsnameaddr);
regs.PC_REG += 8;
ptrace(PTRACE_SETREGS, pid, 0, &regs);
ptrace(PTRACE_CONT, pid, 0, (void*) SIGSTOP);

ソースコードの該当箇所はretry.c:192,197あたり。