C++ gdb:在打开新文件或创建流实例时设置断点

C++ gdb:在打开新文件或创建流实例时设置断点,c++,gdb,C++,Gdb,我有一个很大的代码,当它创建输出文件时并不明显。在gdb中有没有一种方法可以在创建流的新时设置断点?或者当文件被写入时 我试过这样的方法 (gdb) b ofstream Function "ofstream" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b std::ofstream Function "std::ofstream" not defined. Mak

我有一个很大的代码,当它创建输出文件时并不明显。在gdb中有没有一种方法可以在创建流的新
时设置断点?或者当文件被写入时

我试过这样的方法

(gdb) b ofstream
Function "ofstream" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b std::ofstream
Function "std::ofstream" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
我想这样做,这样我可以得到一个回溯,以找出哪些函数正在创建这个文件

我也试过了

(gdb) catch syscall write
这是可行的,除了它还捕获到屏幕上的输出(并且
stdout
的输出是详细的),当我真的想要捕获到文件的输出时

编辑:下面是一个简单的工作示例

#include <iostream>
#include <fstream>
using namespace std;

int main () {
  cout << "hello world\n" ;
  ofstream myfile;
  myfile.open ("example.txt");
  myfile << "Writing this to a file.\n";
  myfile.close();
  return 0;
}
#包括
#包括
使用名称空间std;
int main(){

cout不幸的是,您必须提供完整的函数原型。但是gdb可以给您提供可用方法和函数的列表。如果您键入(注意单引号)

(gdb)break'std::

您可以使用制表器调用自动完成。这将返回命名空间std下所有gdb已知方法和函数的列表。在您的情况下(ofstream),您将在列表中找到以下条目:

std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(char const*, std::_Ios_Openmode)```
std::basic_of stream::basic_of stream(char const*,std:_Ios_Openmode)```
现在只需使用以下命令设置断点:

(gdb) break std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(char const*, std::_Ios_Openmode)
(gdb)中断std::basic_of stream::basic_of stream(char const*,std:_Ios\u Openmode)

运行它,它应该可以按预期工作。

不幸的是,您必须提供完整的函数原型。但是gdb可以为您提供可用方法和函数的列表。如果您键入(请注意单引号)

(gdb)break'std::

您可以使用制表器调用自动完成。这将返回命名空间std下所有gdb已知方法和函数的列表。在您的情况下(ofstream),您将在列表中找到以下条目:

std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(char const*, std::_Ios_Openmode)```
std::basic_of stream::basic_of stream(char const*,std:_Ios_Openmode)```
现在只需使用以下命令设置断点:

(gdb) break std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(char const*, std::_Ios_Openmode)
(gdb)中断std::basic_of stream::basic_of stream(char const*,std:_Ios\u Openmode)
运行它,它应该按预期工作

这可以工作,但它也可以捕捉到屏幕上的输出

您可以使用条件断点排除对标准输出的输出。在x86_64上,这可以通过比较标准输出寄存器与标准输出寄存器1来实现:

(gdb) catch syscall write
Catchpoint 1 (syscall 'write' [1])
(gdb) condition 1 $rdi!=1
(gdb) i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "write" 
    stop only if $rdi!=1
(gdb) 
您还可以在所需的确切文件描述符上设置条件断点。请参阅如何在Linux上将文件名映射到文件描述符

这可以工作,但它也可以捕捉到屏幕上的输出

您可以使用条件断点排除对标准输出的输出。在x86_64上,这可以通过比较标准输出寄存器与标准输出寄存器1来实现:

(gdb) catch syscall write
Catchpoint 1 (syscall 'write' [1])
(gdb) condition 1 $rdi!=1
(gdb) i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "write" 
    stop only if $rdi!=1
(gdb) 

您还可以在所需的确切文件描述符上设置条件断点。请参阅如何在Linux上将文件名映射到文件描述符。

您的建议似乎不适用于我刚才添加到问题中的MWE。只需尝试MWE(使用g3调试标志编译)即可。您选择了正确的构造函数吗(std::basic_of stream::basic_of stream())并使用适当的标志进行编译?使用
g++-g3-c test.cpp-o test.o
g++test.o-o test
在CentOS 6.6上使用gcc 4.9.2,它不起作用。我复制并粘贴了上面的最后一行代码(不包括
(gdb)
)。似乎您在错误的调用上设置了断点。std::basic_of stream::basic_of stream()是正确的(默认的流构造函数)。我在回答中提到的构造函数是一个非默认构造函数,它需要两个参数(我想我写答案时MWE不在那里,所以我以一个为例)。您的建议似乎不适用于我刚才添加到问题中的MWE。仅尝试了MWE(使用g3调试标志编译)就可以了。您是否选择了正确的构造函数(std::basic_of stream::basic_of stream())并使用适当的标志进行编译?在CentOS 6.6上使用gcc 4.9.2使用
g++-g3-c test.cpp-o test.o
g++test.o-o test
,它不起作用。我复制并粘贴了上面的最后一行代码(不包括
(gdb)
)。似乎您在错误的调用上设置了断点。std::basic_of stream::basic_of stream()是正确的一个(默认的流构造函数)。我在回答中提到的构造函数是一个非默认构造函数,它需要两个参数(我认为我写答案时MWE不在那里,所以我以一个为例)。