Debugging Runtime Error

B

Bob Bamberg

Hello All,

I have been trying without luck to get some information on debugging
the Runtime Error R6025 - Pure Virtual Function Call. I am working in
C++ and have only one class that is derived from an Abstract class, I
do not believe that this class object is causing me my problem. Below
is that message I have posted before to other groups.

Question:

I am experiencing a Runtime Error R6025 - Pure Virtual Function Call
in an application I have written. I am trying to figure out what it
is that could be causing this error. I have searched Google Groups
for other posting that discuss the R6025 Error, and read many of them.

From what I can tell, this type of error is caused by an undefined or
unhandled virtual function call that a class object must define when
inheriting from an abstract class. Additionally I have read that this
error most offen occurrs during object construction due to a virtual
function being called before the object has been completely created.
This is not my error, I am 99.999% sure of that.

Rather than ask you all to read my own code to help me find my bug, I
was wondering if anyone could advise to me a good way of debugging
this type of error.

The most promising post I found on Google Groups for debugging such an
error discusses a process of redefining or linking with the function
"void __cdecl purecall(void)" from the C Runtime Library source file
PUREVIRT.C.

I first tried to define this function within my own project, and
putting a breakpoint inside my function definition which would allow
me to view the call stack. Unfortunately, this version of the
function in my own project never gets called. This makes me think
that the problem is somewhere else in Windows and not my own source.
Does this make sense to anyone?

I next attempted to add the line: #include "purevirt.c" in my source,
and adding the ..\VC98\CRT\SRC directory to my
Tools->Options->Directories->Include path of Visual Studio.
Attempting to build my project gives me the error "C2556 - Overloaded
function differs in return type".

Next I tried to add the PUREVIRT.C file directly to my project. This
gave me a host of linker errors including not being able to find my
main() function. Does anyone know what is it that I am doing wrong
trying to trap on the _purecall() to view the function stack? It
appears to me that this method is for use with standard C proramming
not C++, hence the undefined main() linker error.

If anyone follows my question and can give me advise on figuring out
where my error is occurring you would make my day. I have been going
batty trying to figure this out. Does my approach of trying to trap
the _purecall() function make sense since I am programming in C++? Is
there another way around debugging this type of error?

Any help is greatly appreciated, even if its just to tell me that I
have posted my message on the wrong message board. If this is true
however, please advise the best Google Group for answering this type
of question.

Thank You,

Bob Bamberg
 
V

Victor Bazarov

Bob Bamberg said:
I have been trying without luck to get some information on debugging
the Runtime Error R6025 - Pure Virtual Function Call. I am working in
C++ and have only one class that is derived from an Abstract class, I
do not believe that this class object is causing me my problem. Below
is that message I have posted before to other groups.
[...]

The easiest thing would be to _define_ the function that is allegedly
being called (instead of having it pure) and put a breakpoint in it.
You will see where it's called from.

Victor
 
L

lilburne

Bob said:
Any help is greatly appreciated, even if its just to tell me that I
have posted my message on the wrong message board. If this is true
however, please advise the best Google Group for answering this type
of question.

Make all exceptions stop in the debugger at the point of the
throw. You'll find that option under the debug menu.
 
B

Bob Bamberg

lilburne said:
Make all exceptions stop in the debugger at the point of the
throw. You'll find that option under the debug menu.

Thank you Victor and lilburne for your responses to my question.

Unfortunately Victor, I don't know which function is being called. If
I did, I would make sure it was defined. As far as I can see, I have
defined the only virtual function needed to be handled in the one
class I have which inherits from an abstract base class. This is why
I was trying to follow up on the idea of putting a breakpoint in the
purecall() function.

lilburne, I'm not sure what you mean by making all exceptions stop in
the debugger through the debug menu. I am using Visual Studio and
there does not appear to be a debug menu directly. Could you please
give additional information here. Also, I'm still not sure that this
method will solve my problem. I do not believe that a Pure Virtual
Function Call causes an exception, but just a runtime error. If you
could give more details on trying your suggestion I am happy to try it
though since I am currently stuck here.

Thanks,

Bob
 
L

lilburne

Bob said:
lilburne, I'm not sure what you mean by making all exceptions stop in
the debugger through the debug menu. I am using Visual Studio and
there does not appear to be a debug menu directly. Could you please
give additional information here. Also, I'm still not sure that this
method will solve my problem. I do not believe that a Pure Virtual
Function Call causes an exception, but just a runtime error. If you
could give more details on trying your suggestion I am happy to try it
though since I am currently stuck here.

Indication is that an exception is being thrown, which
results in the runtime error report:
http://dbforums.com/arch/89/2002/5/374760

Not having access to msdev I can't confirm that but you
could quickly put together a test see below.

When you run your application from within msdev the 'build'
menu changes to a 'debug' menu - at least with VC++6. Under
this menu there is an item 'exceptions' this raises a dialog
where you can highlight all the exception types and set them
to 'stop always' rather than 'stop if unhandled'. Using this
technique you'll get to break into the debugger when the
exception is first thrown, rather than where it is caught,
and thus have a decent stack trace.

Alternatively you can use the technique presented here:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q125749

but that presupposes that you know which virtual function is
being called. You do suggest though that you believe it is
some virtual in a class other than the one you are testing.

My suspicion would be that during construction of a base
class a pure virtual is being called, probably indirectly.
But without examining the code it is only a suspicion.

#include <iostream>

class A;

void f(A& a);

class A {
public:
A();
virtual void pure() = 0;
};

A::A()
{
f(*this);
}

class B : public A {
public:
virtual void pure();
};

void B::pure()
{
}

void f(A& a)
{
a.pure();
}

int main()
{
try {
B b;
}
catch (...) {
std::cout << "Caught exception" << std::endl;
}
return 0;
}
 
B

Bob Bamberg

lilburne said:
Indication is that an exception is being thrown, which
results in the runtime error report:
http://dbforums.com/arch/89/2002/5/374760

Not having access to msdev I can't confirm that but you
could quickly put together a test see below.

When you run your application from within msdev the 'build'
menu changes to a 'debug' menu - at least with VC++6. Under
this menu there is an item 'exceptions' this raises a dialog
where you can highlight all the exception types and set them
to 'stop always' rather than 'stop if unhandled'. Using this
technique you'll get to break into the debugger when the
exception is first thrown, rather than where it is caught,
and thus have a decent stack trace.

Alternatively you can use the technique presented here:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q125749

but that presupposes that you know which virtual function is
being called. You do suggest though that you believe it is
some virtual in a class other than the one you are testing.

My suspicion would be that during construction of a base
class a pure virtual is being called, probably indirectly.
But without examining the code it is only a suspicion.

#include <iostream>

class A;

void f(A& a);

class A {
public:
A();
virtual void pure() = 0;
};

A::A()
{
f(*this);
}

class B : public A {
public:
virtual void pure();
};

void B::pure()
{
}

void f(A& a)
{
a.pure();
}

int main()
{
try {
B b;
}
catch (...) {
std::cout << "Caught exception" << std::endl;
}
return 0;
}

Thanks for the additional information lilburne. I was able to
following your directions once my program was started in debug mode.
It appears as though my problem is occurring due to a Pure Virtual
function that I should not be required to provide. Specifically it is
a Media Service Provider's pure virtual function that is supposed to
be handled by TAPI 3.0. I am not supposed to be dealing with it at
all.

I think I have a handle on where things are going wrong. Thanks again
for your followup posting.

Bob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top