[英]How to redirect std::cin to a Linux terminal when debugging with GDB?
In Linux, GDB doesn't allow set new-console on
and in stead uses something called tty . 在Linux中,GDB不允许在其中
set new-console on
而是使用名为tty的东西。 With 同
set inferior-tty /dev/pts/[number of an active console]
, set inferior-tty /dev/pts/[number of an active console]
,
in a .gdbinit file (requires editing the number every time) it redirects std::cout
, but std::cin
isn't working properly. 在.gdbinit文件中(每次都需要编辑数字),它重定向
std::cout
,但std::cin
无法正常工作。 It just interprets my input as if I'm sending a bash command and reports an error, and my program continues to wait for input. 它只是将我的输入解释为好像我正在发送bash命令并报告错误,并且我的程序继续等待输入。 I can no longer type in the console after that, so I assume
std::cin
is being redirected, but doesn't work properly. 之后,我将无法再在控制台中键入内容,因此我认为
std::cin
已被重定向,但无法正常工作。
I tried looking up how to launch a terminal from the application itself. 我尝试查找如何从应用程序本身启动终端。 I could only find this answer , which also mentions a bug that it doesn't redirect input.
我只能找到这个答案 ,其中还提到了一个不重定向输入的错误。
Is there any way to fix this issue and redirect std::cin
(and std::cout
) to a Linux terminal properly when debugging? 有什么方法可以解决此问题,并在调试时将
std::cin
(和std::cout
)正确重定向到Linux终端?
Background info: What I'm trying to do should be simple. 背景信息:我想要做的应该很简单。 Print a
>
in front of user input before using std::cin. 使用std :: cin之前,请在用户输入前打印
>
。 I have simple code in place that prints the >
, flushes cout and then calls getline()
. 我有简单的代码来打印
>
,刷新cout然后调用getline()
。 It works when just running the program normally. 当正常运行程序时,它可以工作。 But sadly, GDB refuses to flush the stream when there isn't a newline, so it doesn't print the
>
, ignores the first character of the user input and then does prints the >
, immediately followed by the error message that my program sends because of the mutilated input string. 但可悲的是,GDB拒绝刷新流时,没有一个换行符,所以它不打印
>
,忽略用户输入的第一个字符,然后它打印>
,紧接着是错误消息我的计划由于输入字符串残缺而发送。
In Windows, I've solved it by making a .gdbinit file with set new-console on
. 在Windows中,我通过在.gdbinit文件上
set new-console on
来解决此问题。 This causes GDB to use a Windows console in stead of its own and that works as intended. 这导致GDB代替自己的Windows控制台使用Windows控制台,并且按预期方式工作。
If you need to start the debugging after the program has a chance to pause, just run the program in a terminal, and then gdb - your-program-pid
in another terminal. 如果您需要在程序有机会暂停后开始调试,只需在终端中运行该程序,然后在另一个终端中运行
gdb - your-program-pid
。 Otherwise there's a sequence of steps which is faster to do than to describe. 否则,有一系列步骤比描述要快。
ps
should tell you. ps
应该告诉你。 In the other terminal, use these commands 在另一个终端中,使用以下命令
$ gdb - pid-of-the-other-shell (gdb) br main (gdb) c
Now you have gdb attached to your shell in another terminal. 现在,您已将gdb附加到另一个终端上的shell中。 Not very useful.
不太有用。
In the first terminal, type at the shell prompt 在第一个终端中,在shell提示符下键入
$ exec your-program
Now you have one terminal running gdb
and another terminal running your program under gdb
, stopped at main
. 现在,您有一个运行
gdb
终端,另一个在gdb
下运行程序的终端,该终端在main
停止。 Bear in mind that when the program exits, its terminal window will close. 请记住,程序退出时,其终端窗口将关闭。 If you don't want this, start a second level shell in the first terminal and attach
gdb
to it. 如果您不希望这样做,请在第一个终端中启动第二层Shell,然后将
gdb
附加到它。
You can also use set inferior-tty
command, but you must make sure the other tty exists and no other program attempts to read from it. 您也可以使用
set inferior-tty
命令,但是必须确保另一个tty存在并且没有其他程序尝试从中读取。 The easiest way is to run a shell in another terminal and give it a while true; do sleep 1000; done
最简单的方法是在另一个终端中运行一个shell并给它一段
while true; do sleep 1000; done
while true; do sleep 1000; done
while true; do sleep 1000; done
command. while true; do sleep 1000; done
命令。 Note that you may get warning: GDB: Failed to set controlling terminal: Operation not permitted
messages. 请注意,您可能会收到
warning: GDB: Failed to set controlling terminal: Operation not permitted
消息。 They are harmless. 他们是无害的。
You can use gdb's multiprocess debugging feature and a terminal emulator like xterm
to do this. 您可以使用gdb的多进程调试功能和类似
xterm
的终端仿真器来执行此操作。 ( gnome-terminal
won't work so well as explained later) (
gnome-terminal
不能像后面解释的那样很好地工作)
prompt.c prompt.c
#include <stdio.h>
int main()
{
enum {
N = 100,
};
char name[N];
printf("> ");
scanf("%s", name);
printf("Hi, %s\n", name);
return 0;
}
xterm.gdb xterm.gdb
set detach-on-fork off set target-async on set pagination off set non-stop on file /usr/bin/xterm # -ut tells xterm not to write a utmp log record # which involves root privileges set args -ut -e ./prompt catch exec run
Sample Session 样品会议
$ gdb -q -x xterm.gdb
Catchpoint 1 (exec)
<...>
[New process 7073]
<...>
Thread 0x7ffff7fb2780 (LWP 7073) is executing new program: /home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt
Reading symbols from /home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt...done.
Catchpoint 1 (exec'd /home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt), 0x0000003d832011f0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) inferior 2
[Switching to inferior 2 [process 7073] (/home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt)]
[Switching to thread 2 (Thread 0x7ffff7fb2780 (LWP 7073))]
#0 0x0000003d832011f0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) break prompt.c:11
Breakpoint 2 at 0x4004b4: file prompt.c, line 11.
(gdb) continue &
Continuing.
(gdb)
Breakpoint 2, main () at prompt.c:11
11 printf("> ");
next
12 scanf("%s", name);
(gdb) next
13 printf("Hi, %s\n", name);
A new xterm
window will appear after executing gdb -q -x xterm.gdb
and you can interact with prompt
inside it without interfering with GDB. 在执行
gdb -q -x xterm.gdb
后,将出现一个新的xterm
窗口,您可以与其中的prompt
进行交互而不会干扰GDB。
Related GDB commands: 相关的GDB命令:
inferior 2
switches the process GDB's debugging much like the thread
command switches threads. inferior 2
切换进程GDB的调试非常类似于thread
命令切换线程。 ( GDB: Debugging Multiple Inferiors and Programs ) continue &
means to continue executing in the background. continue &
表示在后台继续执行。 ( GDB: Background Execution ) I used xterm
because gnome-terminal
uses dbus-launch
to ask another process to launch the new terminal outside of the parent-child process relationship that GDB relies on. 我使用
xterm
是因为gnome-terminal
使用dbus-launch
来要求另一个进程在GDB依赖的父子进程关系之外启动新的终端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.