挂在 std::cout 上的 GDB 调试器
Posted
技术标签:
【中文标题】挂在 std::cout 上的 GDB 调试器【英文标题】:GDB debugger hanging on std::cout 【发布时间】:2016-06-27 21:21:21 【问题描述】:由于我的学习,我已经编写 C 和 C++ 代码有一段时间了。我们曾经在学校的编码课程中使用 Visual Studio 作为 IDE。
我现在正在尝试学习使用 GNU 编译器工具和调试器。我使用的是 CodeLite IDE 版本 9.1.8,带有 TDM-GCC-64 5.1.0 编译器。
我的具体问题是 GDB 调试器。我对它的用法有些熟悉(Step into、Step over 等)。每次我尝试调试自己的任何代码时,调试器都会在断点处正常停止并让我从那里继续。
但是,每次我用调试器点击“cout”时,它都拒绝进入下一行。当遇到带有“cout”的行时,我按“F10”转到下一行,但调试器不会从那里继续。它总是冻结,不响应任何命令,我必须强制关闭调试器。其他所有可以想象的陈述都可以,但不是任何形式的“cout”。
熟悉 CodeLite 的人可能都知道调试时文本编辑器窗口左边缘的绿色箭头。当箭头击中“cout”并且我按“F10”进入下一行时,箭头闪烁。当我再次按下“F10”时,箭头再次闪烁。在箭头从左侧边栏中完全消失并且调试器挂在那里之前,这可以完成大约 3-4 次。
Starting debugger
Debugger hanging and arrow disappeared
这是一个示例代码。它是芬兰语,所以你可能不明白我要打印的内容,但这并不重要。
“Henkilo”类包含两个私有变量,字符串代表姓名,int 代表年龄。还有<<
操作符被重载了,可以让cout直接打印对象。这段代码的赋值是为了演示复制构造函数的使用。
#include <iostream>
#include "Henkilo.h"
int main()
Henkilo henkilo1;
henkilo1.setName("Jaakko");
henkilo1.setAge(24);
Henkilo henkilo2(henkilo1);
std::cout << "\nLuotiin henkil\2241, jonka tiedot ovat: " << std::endl << henkilo1 << std::endl;
std::cout << "Kopioitiin henkil\2241 objektiin henkil\2242. Henkil\224n 2 tiedot ovat: " << henkilo2 << std::endl;
return 0;
请原谅我在发布此内容时可能犯的任何错误,这是我第一次。
编辑:
@KennyOstrom
是的,我可以进入该功能,现在我已经对其进行了测试。它似乎也挂在那里。
std::ostream& operator<< (std::ostream& os, const Henkilo& obj)
os << "\nNimi : " << obj.name<< std::endl << "Ik\204 : " << obj.age << std::endl;
return os;
它似乎挂在您将字符串文字插入“os”对象的行。
编辑:
@PaulMcKenzie
抱歉,根本没有考虑这一点。这是该类的实现。这是一个人的基本类,具有姓名和年龄字段。
Henkilo.h
#include <string>
#include <iostream>
class Henkilo
private:
std::string name;
int age;
public:
Henkilo();
Henkilo(std::string initName, int initAge);
Henkilo(const Henkilo& henkilo);
void setName(std::string newName);
std::string getName();
void setAge(int newAge);
int getAge();
friend std::ostream& operator<< (std::ostream& os, const Henkilo& obj);
~Henkilo();
;
Henkilo.cpp
#include "Henkilo.h"
Henkilo::Henkilo() : name(""), age(0) ;
Henkilo::Henkilo(std::string initName, int initAge) : name(initName), age(initAge) ;
Henkilo::Henkilo(const Henkilo& henkilo) : name(henkilo.name), age(henkilo.age) ;
void Henkilo::setName(std::string newName) name = newName; ;
std::string Henkilo::getName() return name; ;
void Henkilo::setAge(int newAge) age = newAge; ;
int Henkilo::getAge() return age; ;
std::ostream& operator<< (std::ostream& os, const Henkilo& obj)
os << "\nNimi : " << obj.name<< std::endl << "Ik\204 : " << obj.age << std::endl;
return os;
Henkilo::~Henkilo() ;
【问题讨论】:
如果你只尝试一个空字符串std::cout << "" << std::endl;
,它允许你跳过它吗?这可能是工具中的错误报告,而不是代码中存在的错误。
不,它仍然挂起。但是,它确实会在其后打印空字符串和换行符。这个问题也是 Dev-C++ 和 Code::Blocks IDE 的问题。
你能进入处理操作符
对这个离题很抱歉。有人刚刚编辑了我的帖子,我不小心删除了更改:D 请随时将其编辑为更好的形式。
@JoonasOnatsu 你真的应该发一个minimal reproducible example。您说它是调试器,但是您发布的内容中存在未知数。 Henkilo
类和你在里面做什么是未知的。它可能会破坏内存,从而破坏输出流的工作方式。也许Henkilo
的operator <<
有问题,您处于无限循环中。你也有这个:Henkilo henkilo2(henkilo1);
调用复制构造函数,我们不知道它是如何实现的。您应该将我们都可以复制/粘贴/运行的代码发布到代码编辑器中,编译并运行应用程序。
【参考方案1】:
看起来您的输出流运算符重载并没有返回任何内容。你在第一行之后有你的 return 语句,它后面什么都没有。试试这个:
std::ostream& operator<< (std::ostream& os, const Henkilo& obj)
os << "\nNimi : " << obj.name<< std::endl << "Ik\204 : " << obj.age << std::endl;
return os;
【讨论】:
FFS。对不起,我糟糕的 *** 使用技能:D 原始复制粘贴的代码包含正确的返回语句。 是这个问题吗? 不,我的原始代码和你的一样。我只是碰巧搞砸了我粘贴的代码。以上是关于挂在 std::cout 上的 GDB 调试器的主要内容,如果未能解决你的问题,请参考以下文章
gdb调试Alpine Linux上的OpenJDK java失败了“线程接收信号?,未知信号”