Sign in to follow this  
rumble

GDB warning: RTTI symbol not found for class

Recommended Posts

rumble    118
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


Link to post
Share on other sites
rumble    118
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.

[code]

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--;
}
};

[/code]

Share this post


Link to post
Share on other sites
ApochPiQ    23059
Your code has a number of serious flaws, [i]ignoring[/i] 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 [i]very bad thing to do[/i] 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 [i]lot[/i] 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


Link to post
Share on other sites
rumble    118
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


Link to post
Share on other sites
Bregma    9214
[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++'?
[/quote]
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


Link to post
Share on other sites
rumble    118
Hidden
[quote name='Bregma' timestamp='1302491280' post='4796919']
[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++'?
[/quote]
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:

[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;
}
[/code]

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
rumble    118
[quote name='Bregma' timestamp='1302491280' post='4796919']
[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++'?
[/quote]
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:

[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;
}
[/code]

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


Link to post
Share on other sites
smart_idiot    1298
The above code works for me, GDB says [i]*pA = {_vptr.A = 0x89485ed18949ed31, Aint = -461158174}[/i],
and [i]*(B*)pA = {<A> = {_vptr.A = 0x89485ed18949ed31, Aint = -461158174}, Bfloat = 869647}[/i]


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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this