刚学习Qt不久。最近学习了几个简单的实例,于是想实现网络通信,在GUI下,对一些大牛来说很简单了,别笑我哦,。
废话不说了,程序遇到了问题。
经过几次编译(一直有错误)修改,最终成功。
执行。
出现了Segment fault.
麻烦了,一直没有调试过Qt的,emacs下编译的咋调试涅,装了qt-creator.设置断点,debug。如图
把汇编贴出来
0x003b5053 mov %es,(%eax)
0x003b5055 add %al,(%eax)
0x003b5057 mov 0x8(%ebp),%eax
0x003b505a mov 0xc(%ebp),%esi
0x003b505d mov %eax,(%esp)
0x003b5060 call 0x3b2c10 <_ZNK7QLayout12parentWidgetEv>
0x003b5065 mov %eax,%ecx
0x003b5067 mov 0x4(%esi),%eax //程序是在这里,有个黄色的箭头,说实话看不太懂,
0x003b506a mov 0x8(%eax),%edi
0x003b506d test %edi,%edi
0x003b506f je 0x3b51b0 <_ZN7QLayout14addChildWidgetEP7QWidget+368>
0x003b5075 mov 0x10(%esi),%eax
0x003b5078 cmpb $0x0,0x4(%eax)
0x003b507c js 0x3b51e0 <_ZN7QLayout14addChildWidgetEP7QWidget+416>
0x003b5082 test %ecx,%ecx
0x003b5084 setne %dl
0x003b5087 je 0x3b51b5 <_ZN7QLayout14addChildWidgetEP7QWidget+373>
0x003b508d cmp %edi,%ecx
0x003b508f mov $0x1,%edx
0x003b5094 setne %al
0x003b5097 movzbl %al,%edi
0x003b509a sub $0x1,%edi
0x003b509d and %ecx,%edi
0x003b509f mov 0x10(%ecx),%eax
0x003b50a2 cmpw $0x0,0x4(%eax)
0x003b50a7 js 0x3b5228 <_ZN7QLayout14addChildWidgetEP7QWidget+488>
0x003b50ad movb $0x0,-0x19(%ebp)
0x003b50b1 test %edi,%edi
0x003b50b3 je 0x3b5208 <_ZN7QLayout14addChildWidgetEP7QWidget+456>
0x003b50b9 movl $0x1,0x8(%esp)
0x003b50c1 movl $0x7,0x4(%esp)
0x003b50c9 mov %esi,(%esp)
类最先调用的是构造函数,进入构造函数吧,set breakpoint ,还是直接跳段错误。(是不是不能跟踪到构造函数?)
图形化调试工具就在这里了。
到论坛提问了,只有单线程姐回我的帖子,感动。
改用我的C法宝吧,printf,没输出阿。。。仔细回想以前见过qDebug不过当时不知道什么意思,baidu了,ok,就用它试试,成功了,哈哈。可以输出内容。
接下来就找到了问题的根结:是头文件中声明的变量,在源文件中没有实例化!
抓住机会学习下qDebug相关知识。
对于qDebug是用来调试信息提示的,输出到控制台。还有其他的函数qWarning(),qFatal(),等
下面的例子是把调试信息输出到文件的例子(不过要自己实现消息句柄并注册事件,不是特别熟悉)
#include
#include
#include
void customMessageHandler(QtMsgType type, const char *msg)
{
QString txt;
switch (type) {
case QtDebugMsg:
txt = QString("Debug: %1").arg(msg);
break;
case QtWarningMsg:
txt = QString("Warning: %1").arg(msg);
break;
case QtCriticalMsg:
txt = QString("Critical: %1").arg(msg);
break;
case QtFatalMsg:
txt = QString("Fatal: %1").arg(msg);
abort();
}
QFile outFile("debuglog.txt");
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
ts << txt << endl;
}
int main( int argc, char * argv[] )
{
QApplication app( argc, argv );
//Lets register our custom handler, before we start
qInstallMsgHandler(customMessageHandler);
...
return app.exec();
}
顺便看了下qdebug.h源码,里面内容繁杂,用到了模板,主要的是运算符重载,毕竟要转化输出到控制台嘛。
http://www.oschina.net/code/explore/qt-4.7.1/src/corelib/io/qdebug.h
inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); }
096 inline QDebug &operator<<(QBool t) { stream->ts << (bool(t != 0) ? "true" : "false"); return maybeSpace(); }
097 inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
098 inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
099 inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); }
100 inline QDebug &operator<<(unsigned short t) { stream->ts << t; return maybeSpace(); }
101 inline QDebug &operator<<(signed int t) { stream->ts << t; return maybeSpace(); }
102 inline QDebug &operator<<(unsigned int t) { stream->ts << t; return maybeSpace(); }
103 inline QDebug &operator<<(signed long t) { stream->ts << t; return maybeSpace(); }
104 inline QDebug &operator<<(unsigned long t) { stream->ts << t; return maybeSpace(); }
105 inline QDebug &operator<<(qint64 t)
106 { stream->ts << QString::number(t); return maybeSpace(); }
107 inline QDebug &operator<<(quint64 t)
108 { stream->ts << QString::number(t); return maybeSpace(); }
109 inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); }
110 inline QDebug &operator<<(double t) { stream->ts << t; return maybeSpace(); }
111 inline QDebug &operator<<(const char* t) { stream->ts << QString::fromAscii(t); return maybeSpace(); }
112 inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
113 inline QDebug &operator<<(const QStringRef & t) { return operator<<(t.toString()); }
114 inline QDebug &operator<<(const QLatin1String &t) { stream->ts << '\"' << t.latin1() << '\"'; return maybeSpace(); }
115 inline QDebug &operator<<(const QByteArray & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
116 inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); }
117 inline QDebug &operator<<(QTextStreamFunction f) {
118 stream->ts << f;
是问题就有解决方法,不管你信不信,我是信了。当然世界难题就算了,qDebug好东西。明天我的暑期实习就结束了,GoodBye ,My last summer holiday.
New World, Just Like One Piece,哈哈