Jump to content
• Advertisement

GDB warning: RTTI symbol not found for class

This topic is 2685 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I use Eclipse with GDB. For any smart pointer class I have such as a MyString, I keep getting

warning: RTTI symbol not found for class MyString

And indeed, I can't see the value held by a smart pointer container:

MyString str = "test"; //can see "test" fine when examining variable value
MyStringPtr strPtr = &str; //can not see "test" contained by the container strPtr when examining variable value.

I figure the warning is the cause, that the pointer to "test" became a void pointer rather than a typed pointer of MyString. Nonetheless, this works:

int L = strPtr->length(); //correctly is 4
char c = strPtr->charAt(1); //correctly is 'e'.

So GDB seems to be handling things correctly, but not perfect so that I can't debug.

Figure would ask before posting else where.

Share this post

Share on other sites
Advertisement
Post your code for the faulting classes (both the string and smart pointers) as well as your complete compiler settings.

Share this post

Share on other sites
I should mention there is no problem when developing in Visual Studio. Problem only occurs for Eclipse with Cygwin g++.

Cygwin g++ compile options:
-O0 -g3 -Wall -c -fmessage-length=0

Below is a simplified sketch of relevant classes.

 class MyObjectPtr { protected: MyObject* pObj; public: MyObjectPtr(MyObject* p= 0); MyObjectPtr(const MyObjectPtr& r); ~MyObjectPtr(); protected: void set(MyObject* p) { if(p!=0) p->incrementReference(); if(pObj!=0) pObj->decreasetReference(); pObj= p; } void set(const char* chArray) { pObj= new MyString(chArray); if(pObj!=0) pObj->incrementReference(); } void assertError(const char* error); public: const MyObjectPtr& operator=(const MyObjectPtr& r) { set(r); return *this; } const MyObjectPtr& operator=(MyObject* p) { set(p); return *this; } MyObject* operator->() { if(pObj==null) assertError("MyObject"); return pObj; } operator MyObject*() const { return pObj; }; MyObjectPtr(const char* pch) { set(pch); }; const MyObjectPtr& operator=(const char* pch); }; class MyStringPtr : public MyObjectPtr { public: MyStringPtr(MyObject* p= 0) : MyObjectPtr(p) {} MyStringPtr(const int n) : MyObjectPtr() {} const MyStringPtr& operator=(MyObject* p) { set(p); return *this; } MyString* operator->() { if(pObj==null) assertError("MyString"); return (MyString*)pObj; }; MyStringPtr(const char* pch) { if( pch != NULL ) { set( new MyString(pch) ); } else set( NULL ); } //other MyString related }; class MyString : public MyObject { int length; char* data; void allocate(int iSize) { data= new char[iSize]; } DString(const char* dataIn) { if(dataIn==0) assertError("NullString"); length= strlen(dataIn); alloc(length+1); memcpy(data, dataIn, length+1); } }; class DFC_DLL DObject { int referenceCount; void incrementReference() { referenceCount++; } void decrementReference() { referenceCount--; } }; 

Share this post

Share on other sites
Your code has a number of serious flaws, ignoring the fact that you basically made it up on the fly and didn't post your real code. (There's all kinds of obvious mistakes in what you posted, beyond the deeper issues in the implementation, that make it pretty clear you just wrote that on the spot and it bears no real relation to your actual code. This is a very bad thing to do when asking for help. If my car broke down and I wanted you to help fix it, would it make sense for me to direct you to a bicycle in my garage to start investigating the problem? No. So don't do that.)

Look into RAII, exception safety, the rule of three, virtual destructors and why you need them, and memory leaks.

It looks to me like you might have some background in C# or even Java, and you're carrying over a lot of habits and assumptions from that language into C++. This is, in general, extremely dangerous and liable to produce a lot of very substandard code. Don't let the curly braces and semicolons fool you; C++ is a very different language and strictly demanding in many areas of discipline and attention to detail.

In this particular case it looks to me like your problem is a fairly straightforward beginner mistake in not understanding the way RTTI and type dispatches work in C++; I won't spoil it by giving you the answer, because then you'd be tempted to just add a couple minor tweaks to your code and move on without learning anything. Instead, I'll encourage you to do some research into the areas I listed above, and hopefully it should become clear after that what you're doing wrong.

Share this post

Share on other sites
Your intentions are good.

More importantly, do you mean GDB failing to know pointer type, as if the virtual function table doesn't exist, is due to 'not understanding the way RTTI and type dispatches work in C++'?

Might you have some hints on why without GDB the string memory is otherwise correctly accessible, albeit with leaks and other flaws?

How do you suggest I communicate better?
As often with software dev, the code is an inheritance. While needing improvement, I have no authority to post a direct copy of the code.

Moreover, to reach a wider audience, convoluted Mac/Windows defines, allocation alignments, hashing functions, macro expansions, and etc. had been removed to improve clarity.

Share this post

Share on other sites

More importantly, do you mean GDB failing to know pointer type, as if the virtual function table doesn't exist, is due to 'not understanding the way RTTI and type dispatches work in C++'?

Well, *cough*, do you have any virtual functions? Certainly you do not in the code you posted.

We can only guess vaguely if you only describe the problem vaguely. See if you can come up with a small compilable test program that produces the same behaviour.

Share this post

Share on other sites
Hidden

[quote name='rumble' timestamp='1302486090' post='4796900']
More importantly, do you mean GDB failing to know pointer type, as if the virtual function table doesn't exist, is due to 'not understanding the way RTTI and type dispatches work in C++'?

Well, *cough*, do you have any virtual functions? Certainly you do not in the code you posted.

We can only guess vaguely if you only describe the problem vaguely. See if you can come up with a small compilable test program that produces the same behaviour.
[/quote]

Ah they have been there. My mistake for not including the virtual destructors when simplifying the code.

Inspired from your comments, my problem can be illustrated with the following piece of code:

 class A { int Aint; public: virtual ~A(){} }; class B : public A { float Bfloat; public: virtual ~B(){} }; int main(int argc, char* argv[]) { A* pA; pA = new B(); delete pA; return 0; } 

In Eclipse with Cygwin g++ and gdb, mousing over pA I see member Aint. That's it.

In VS2008, mousing over pA I see member Aint. Additionally, I do see __vfptr, Bfloat.

Both IDE have default settings.

The former has compilation flag -O0 -g3 -Wall -c -fmessage-length=0. No "RTTI symbol not found for class" message is printed for this simple example.

Feel free to try.

Share this post

Link to post

[quote name='rumble' timestamp='1302486090' post='4796900']
More importantly, do you mean GDB failing to know pointer type, as if the virtual function table doesn't exist, is due to 'not understanding the way RTTI and type dispatches work in C++'?

Well, *cough*, do you have any virtual functions? Certainly you do not in the code you posted.

We can only guess vaguely if you only describe the problem vaguely. See if you can come up with a small compilable test program that produces the same behaviour.
[/quote]

Ah they have been there. My mistake for not including the virtual destructors when simplifying the code.

Inspired from your comments, my problem can be illustrated with the following piece of code:

 class A { int Aint; public: virtual ~A(){} }; class B : public A { float Bfloat; public: virtual ~B(){} }; int main(int argc, char* argv[]) { A* pA; pA = new B(); delete pA; return 0; } 

In Eclipse with Cygwin g++ and gdb, mousing over pA I see member Aint. That's it.

In VS2008, mousing over pA I see member Aint. Additionally, I do see __vfptr, Bfloat, and the B is derived from A relationship.

Both IDE have default settings.

The former has compilation flag -O0 -g3 -Wall -c -fmessage-length=0. No "RTTI symbol not found for class" message or any run time warning appears for this simple example.

Feel free to try.

Share this post

Share on other sites
The above code works for me, GDB says *pA = {_vptr.A = 0x89485ed18949ed31, Aint = -461158174},
and *(B*)pA = {<A> = {_vptr.A = 0x89485ed18949ed31, Aint = -461158174}, Bfloat = 869647}

My guess would be to use -ggdb3 rather than just -g3. I'm not really confident that'll fix your problem, but that's all I can think of.

Share this post

Share on other sites

• Advertisement
• Advertisement

• Popular Contributors

1. 1
2. 2
JoeJ
20
3. 3
frob
18
4. 4
5. 5
• Advertisement

• 10
• 10
• 12
• 13
• 9
• Forum Statistics

• Total Topics
632200
• Total Posts
3004740

×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!