具有C ++虚函数的GDB不完整类型 [英] GDB incomplete type when having C++ virtual function

查看:1137
本文介绍了具有C ++虚函数的GDB不完整类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚注意到有些奇怪的事情,当我在我的类中添加virtual keyword(除构造函数之外的任何函数)时,我无法在GDB中显示我的对象的内容。 GDB说不完整的类型



这是代码:



///////// /////// reco.h /////////////

  #ifndef RECO_H 
#define RECO_H

#include< iostream>
#include< string>

class reco {
public:
reco(float weight);
〜reco(void);

float getWeight();

私人:
浮动重量;
};

#endif

/////////// ////// reco.cpp /////////////

  #include< iostream> 
#include< string>

#includereco.h

using namespace std;

reco :: reco(float weight){
weight = weight;
}

reco ::〜reco(void){
cout<< 析构器回收<终点
}

float reco :: getWeight(){
return weight;
}

////////////// main。 cpp /////////////

  #include< iostream> 
#include< string>

#includereco.h

using namespace std;


int main(){
reco * s = new reco(5.0);
cout<<< s-> getWeight()<<终点

删除s;

return 0;
}

然后用GDB:

  gdb main.exe 
breakpoint main.cpp:11< ----(cout)
run
print * s
$ 1 = {weight = 5}

然后,如果我做了一个虚拟 ,并重试打印我的 * s 指针与GDB,它说:
不完整类型



看起来VTABLE有一些事情,就像virtual关键字隐藏了我的Reco类的实现一样。我知道编译器晚期绑定,然后,VTABLE查找是在运行时完成的,但程序已经在运行,而GDB正在调试,对吧?



设置打印vtbl设置在开。



如果我使用 ptype s ,我得到<不完全类型> 消息。



如果我用 x / 540f80 ,它说无法访问内存



我不知道为什么添加这个关键字使我的对象的类型不完整?



非常感谢您的帮助!



最后一件事我注意到:



WITH VIRTUAL:

  reco.cpp  - > g0和main.cpp  - > g =不完整的类型
reco.cpp - > g和main.cpp - > g = ok

无虚拟

  reco.cpp  - > g0和main.cpp  - > g = ok 
reco.cpp - > g和main.cpp - > g = ok


解决方案


reco.cpp - > g和main.cpp - > g = ok


假设由 > g 您的意思是您使用 -g 标记编译 reco.cpp em> do ,和不要这样做:

  g ++ -c -g0 reco.cpp 

你发现是GCC可以优化调试信息的数量如果知道您有关键方法,则必须发出



没有 virtual ,没有关键的方法,GCC必须发出冗余将信息调试到每个编辑单元。这使得您的对象文件更大(对最终的可执行文件应该几乎没有影响),但是即使只有一些对象文件使用调试信息进行编译,也允许调试。


I have just noticed something weird, when I add the "virtual keyword" in my class (any function except the constructor), I can't display the content of my object in GDB. GDB says "incomplete type"

Here is the code :

//////////////// reco.h /////////////

#ifndef RECO_H
#define RECO_H

#include <iostream>
#include <string>

class reco {
    public:
        reco(float weight);
        ~reco(void);

        float getWeight();

    private:
        float weight;
};

#endif

///////////////// reco.cpp /////////////

#include <iostream>
#include <string>

#include "reco.h"

using namespace std;

reco::reco(float weight) {
    weight = weight;
}

reco::~reco(void) {
    cout << "destructor reco" << endl;
}

float reco::getWeight() {
    return weight;
}

////////////// main.cpp /////////////

#include <iostream>
#include <string>

#include "reco.h"

using namespace std;


int main() {
    reco* s = new reco(5.0);
    cout << s->getWeight() << endl;

    delete s;

    return 0;
}

Then with GDB :

gdb main.exe
breakpoint main.cpp:11 <---- (cout)
run
print *s
$1 = { weight = 5 }

And then, if I make one of the functions "virtual", and I retry to print my *s pointer with GDB, it says: "incomplete type"

It looks like there is something happening with the VTABLE, as if the "virtual" keyword was hiding the implementation of my Reco class. I know that the compiler does late binding and then, the VTABLE lookup is done at runtime, but the program is already running while GDB is debugging it, right ?

The "set print vtbl" setting in "on".

If I use ptype s, I get the <incomplete type> message again.

If I examine the address with x/540f80, it says "cannot access memory"

I don't know why just adding this keyword makes my object's type incomplete ?

Thanks a lot for your help !

One last thing that I notice :

WITH VIRTUAL:

 reco.cpp -> g0 and main.cpp -> g = incomplete type
 reco.cpp -> g and main.cpp ->g = ok

WITHOUT VIRTUAL

 reco.cpp -> g0 and main.cpp -> g = ok
 reco.cpp -> g and main.cpp ->g = ok

解决方案

reco.cpp -> g and main.cpp ->g = ok

Assuming by -> g you mean that you compile reco.cpp with the -g flag, yes do that, and don't do this:

g++ -c -g0 reco.cpp

What you've discovered that is that GCC can optimize the amount on debug info it must emit if it knows that you have a key method.

Without virtual, there is no key method, and GCC must emit redundant debug info into every compilation unit. That makes your object files larger (it should have little or no effect on the final executable), but allows you to debug even when only some of your object files are compiled with debug info.

这篇关于具有C ++虚函数的GDB不完整类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆