当我启动GDB时,目标进程会打印大量数据,因此我想将其重定向到NULL,直到某个时间点。
到目前为止我发现的唯一两种方法是:
运行>文件名
tty filename
没有“tty默认”或“默认tty”
谢谢,
伊泰
答案 0 :(得分:3)
我无法找到一种方法将下级的stdout恢复正常
以下是如何做到这一点:
Reading symbols from /tmp/./a.out...done.
(gdb) list main
1 #include <stdio.h>
2
3 int main() {
4 int i;
5
6 for (i = 0; i < 1000; ++i) {
7 printf("A line we don't care about: %d\n", i);
8 }
9 printf("An important line\n");
10 return 0;
11 }
(gdb) b 9
Breakpoint 1 at 0x400579: file t.c, line 9.
(gdb) run > /dev/null
Starting program: /tmp/./a.out > /dev/null
Breakpoint 1, main () at t.c:9
9 printf("An important line\n");
(gdb) call fflush(0)
$1 = 0
由于我们即将切换输出,我们希望确保刷新任何缓冲数据。
接下来我们致电open("/dev/tty", O_WRONLY)
。您可以在O_WRONLY
中通过grep
ping找到/usr/include
的值。
(gdb) shell grep WRONLY /usr/include/bits/*.h
/usr/include/bits/fcntl.h:#define O_WRONLY 01
(gdb) p open("/dev/tty", 1)
$2 = 3
所以我们现在有了一个新的文件描述符3
,它将输出到当前终端。最后,我们将STDOUT_FILENO
切换到它,就像这样:
(gdb) call dup2(3, 1)
$3 = 1
(gdb) c
Continuing.
An important line
[Inferior 1 (process 22625) exited normally]
Voilà:终端上印有“重要的一条线”。
答案 1 :(得分:0)
详细阐述了使用俄语的解决方案,我已经编写了一个独立的GDB-python脚本,可以切换到stdout和活动终端(TTY)的重定向。如果程序输出没有重定向到以(run > /dev/null
)开头,则脚本无效。
要激活脚本,请使用source
命令:
(gdb) b 10
Breakpoint 1 at 0x5555555547a8: file gdbtest.c, line 10.
(gdb) run > /dev/null
Starting program: /home/gdbtest > /dev/null
Breakpoint 1, main () at gdbtest.c:10
10 printf("An important line\n");
(gdb) list
5
6 setbuf(stdout, NULL);
7 for (i = 0; i < 1000; ++i) {
8 printf("A line we don't care about: %d\n", i);
9 }
10 printf("An important line\n");
11 for (i = 0; i < 1000; ++i) {
12 printf("A line we don't care about: %d\n", i);
13 }
14 //fflush(stdout);
(gdb) source redir-stdout.py
(gdb) redir-stdout
Inferior PID: 20749
Redirecting stdout (fd:4) to TTY (fd:3)
(gdb) n
An important line
11 for (i = 0; i < 1000; ++i) {
(gdb) n
12 printf("A line we don't care about: %d\n", i);
(gdb) n
A line we don't care about: 0
11 for (i = 0; i < 1000; ++i) {
(gdb) redir-stdout
Inferior PID: 20749
Redirecting TTY (fd:3) back to stdout (fd:4)
(gdb) n
12 printf("A line we don't care about: %d\n", i);
(gdb) n
11 for (i = 0; i < 1000; ++i) {
(gdb) n
12 printf("A line we don't care about: %d\n", i);
(gdb)
这是脚本(我将其命名为redir-stdout.py):
import gdb
class RedirectStdout(gdb.Command):
def __init__(self):
super(RedirectStdout, self).__init__("redir-stdout", gdb.COMMAND_USER)
self.tty = None
self.stdout = None
self.redir = False
gdb.events.exited.connect(self.exit_handler)
def invoke(self, arg, from_tty):
print("Inferior PID: %s" % gdb.selected_inferior().pid)
if(gdb.selected_inferior().pid == 0):
raise gdb.GdbError ("Error: must have an active debuggee")
out = gdb.execute("call fflush(0)", to_string=True)
if(self.tty is None):
# or just /dev/tty, as shown (the 1 means WRONLY)
out = gdb.execute("p open(\"/dev/tty\", 1)", to_string=True)
self.tty = out.split('=')[-1].strip()
if(self.stdout is None):
out = gdb.execute("p open(\"/proc/self/fd/1\", 1)", to_string=True)
self.stdout = out.split('=')[-1].strip()
if(not self.redir):
print("Redirecting stdout (fd:{}) to TTY (fd:{})".format(self.stdout, self.tty))
out = gdb.execute("call dup2({}, 1)".format(self.tty), to_string=True)
ret = out.split('=')[-1].strip()
#print("dup2 returns: " + ret)
self.redir = True
else:
print("Redirecting TTY (fd:{}) back to stdout (fd:{})".format(self.tty, self.stdout))
out = gdb.execute("call dup2({}, 1)".format(self.stdout), to_string=True)
ret = out.split('=')[-1].strip()
#print("dup2 returns: " + ret)
self.redir = False
def exit_handler(self, event):
self.tty = None
self.stdout = None
self.redir = False
instance = RedirectStdout()
def exit_handler (event):
print("Exit event received")
instance.exit_handler(event)
注意:脚本可以从当前目录中的本地.gdbinit或主目录中轻松获取。