如何监控放入标准输出缓冲区的内容并在特定字符串存放在管道中时中断? [英] How can I monitor what's being put into the standard out buffer and break when a specific string is deposited in the pipe?
问题描述
在 Linux 中,使用 C/C++ 代码,使用 gdb,如何添加 gdb 断点来扫描传入的字符串以便在特定字符串上中断?
In Linux, with C/C++ code, using gdb, how can you add a gdb breakpoint to scan the incoming strings in order to break on a particular string?
我无权访问特定库的代码,但我想在该库将特定字符串发送到标准输出时立即中断,以便我可以返回堆栈并调查正在调用的代码部分图书馆.当然,我不想等到缓冲区刷新发生.这可以做到吗?可能是 libstdc++
中的例程?
I don't have access to a specific library's code, but I want to break as soon as that library sends a specific string to standard out so I can go back up the stack and investigate the part of my code that is calling the library. Of course I don't want to wait until a buffer flush occurs. Can this be done? Perhaps a routine in libstdc++
?
推荐答案
这个问题可能是一个很好的起点:如何在某物被打印到终端"上设置断点?在 gdb 中?
This question might be a good starting point: how can I put a breakpoint on "something is printed to the terminal" in gdb?
因此,您至少可以在将某些内容写入标准输出时中断.该方法主要涉及在 write
系统调用上设置断点,条件是第一个参数是 1
(即 STDOUT).在评论中,还有一个关于如何检查 write
调用的字符串参数的提示.
So you could at least break whenever something is written to stdout. The method basically involves setting a breakpoint on the write
syscall with a condition that the first argument is 1
(i.e. STDOUT). In the comments, there is also a hint as to how you could inspect the string parameter of the write
call as well.
我想出了以下内容并使用 gdb 7.0.1-debian 对其进行了测试.它似乎工作得很好.$esp + 8
包含一个指向传递给 write
的字符串的内存位置的指针,因此首先将其转换为整数,然后再转换为指向 char 的指针代码>.
$esp + 4
包含要写入的文件描述符(1 表示 STDOUT).
I came up with the following and tested it with gdb 7.0.1-debian. It seems to work quite well. $esp + 8
contains a pointer to the memory location of the string passed to write
, so first you cast it to an integral, then to a pointer to char
. $esp + 4
contains the file descriptor to write to (1 for STDOUT).
$ gdb break write if 1 == *(int*)($esp + 4) && strcmp((char*)*(int*)($esp + 8), "your string") == 0
x86 64 位模式
如果您的进程运行在 x86-64 模式下,则参数通过暂存器 %rdi
和 %rsi
$ gdb break write if 1 == $rdi && strcmp((char*)($rsi), "your string") == 0
请注意,由于我们使用的是暂存寄存器而不是堆栈上的变量,因此删除了一级间接.
strcmp
以外的函数可以用在上面的代码片段中:
Functions other than strcmp
can be used in the above snippets:
strncmp
is useful if you want match the firstn
number of characters of the string being writtenstrstr
can be used to find matches within a string, since you can't always be certain that the string you're looking for is at the beginning of string being written through thewrite
function.
我很喜欢这个问题并找到了后续答案.我决定写一篇关于它的博文.
I enjoyed this question and finding it's subsequent answer. I decided to do a blog post about it.
这篇关于如何监控放入标准输出缓冲区的内容并在特定字符串存放在管道中时中断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!