控制终端和 GDB

标签 c linux terminal gdb pty

我有一个 Linux 进程在后台运行。我想通过 SSH 接管它的 stdin/out/err,同时也是终端 Controller 。 “原始”文件描述符也是伪终端。 我试过 Reptyr 和 dupx . Reptyr 在 vfork 周围失败,但 dupx 工作得很好。它生成的 GDB 脚本:

attach 123
set $fd=open("/dev/pts/14", 0)
set $xd=dup(0)
call dup2($fd, 0)
call close($fd)
call close($xd)
set $fd=open("/dev/pts/14", 1089)
set $xd=dup(1)
call dup2($fd, 1)
call close($fd)
call write($xd, "Remaining standard output of 123 is redirected to /dev/pts/14\n", 62)
call close($xd)
set $fd=open("/dev/pts/14", 1089)
set $xd=dup(2)
call dup2($fd, 2)
call close($fd)
call write($xd, "Remaining standard error of 123 is redircted to /dev/pts/14\n", 60)
call close($xd)

dupx 命令一完成,shell 就不会返回,目标应用会立即收到我的输入(通过 pts/14)。

现在我想使用我的独立二进制应用程序实现相同的结果。我移植了相同的系统调用(dup/dup2/close 等),这些系统调用由 dupx 驱动的脚本由 gdb 执行:

int fd; int xd;
char* s = "Remaining standard output is redirected to new terminal\n";

fd = open(argv[1], O_RDONLY);
xd = dup( STDIN_FILENO);
dup2(fd,  STDIN_FILENO );
close(fd);
close(xd);

fd = open(argv[1], O_WRONLY|O_CREAT|O_APPEND);
xd = dup( STDOUT_FILENO);
dup2(fd,  STDOUT_FILENO);
close(fd);
write(xd, s, strlen(s));
close(xd);

fd = open(argv[1], O_WRONLY|O_CREAT|O_APPEND);
xd = dup( STDERR_FILENO);
dup2(fd,  STDERR_FILENO);
close(fd);
write(xd, s, strlen(s));
close(xd); 

运行上面的代码片段是通过 sigstop/ptrace attach/dlopen/etc(使用类似于热补丁的工具)将共享库注入(inject)远程进程来完成的。让我们认为这部分问题是安全且工作可靠的:在完成所有这些之后,目标进程的文件描述符已按我的意愿更改。我可以通过简单地检查/proc/pidof target/fd 来验证它。

但是,shell 返回并且它仍然接收我的所有输入,而不是目标应用程序。

我注意到如果我在这一点之后简单地使用 gdb 附加/分离(= fds 被注入(inject)的 C 代码更改)而没有实际更改任何东西,所需的行为就完成了(意味着:shell 没有返回但目标应用程序开始接收我的输入)。命令是:

gdb --pid=`pidof target` --batch --ex=quit

现在我的问题是:如何?后台发生了什么?没有gdb我怎么能做同样的事情?我试过 stracing gdb 来获得一些提示,也试过使用 tty ioctl API,但没有任何运气。

请注意,通过 Reptyr 使用的 fork/setsid 方式获取终端 Controller 状态(如果这是这个问题的关键)对我来说是 Not Acceptable :我想避免 fork 。 此外,我无法控制启动目标,所以“你为什么不在屏幕上运行它”在这里没有答案。

最佳答案

I've ssh access, thats where pts/14 was coming from. Shell and the target app might be competing, but I've never experienced such behaviour; dupx alwaysed did what I wanted in this scenario.

好吧,坐着想知道为什么这个已知问题在过去偶然没有出现并不能解决问题,即使这一点得到澄清。要走的路是让它通过设计而不是偶然地工作。为此,您的独立二进制应用程序有必要在输入应该转到目标应用程序.
见 e。 G。还有 Redirect input from one terminal to another , Why does tapping a TTY device only capture every other character?

关于控制终端和 GDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30687224/

相关文章:

Eclipse 终端不更新/行为奇怪

ios - 如何从 OSX 终端将文件推送到未越狱的 iPad/iPhone?

c++ - 在 C++ 程序中使用 scanf() 比使用 cin 更快?

c - 如何使用 c 程序关闭窗口,用户在其中输入时间

php 文件加载不正确显示空白页

linux - 编写将文件复制到子文件夹的脚本

linux - & 和 | 有什么区别在Linux中?

c - 写入.txt 文件?

自 Windows 10 1809 以来,通过 USB HID 设备创建文件失败并出现访问被拒绝 (5)

java - 通过 Java GUI 运行 Linux 命令