Link to home
Start Free TrialLog in
Avatar of lsmgms
lsmgms

asked on

How to debug "pure virtual function call"

Hi,

I am using mpatrol to debug memory corruption and it reported this error:

Runtime Error!
  Program: ...\pwlib\lib\asnparser.exe
  R6025
  - pure virtual function call

This message does not provide any info for me to debug.
Unfortunately I cannot run under debugger(mpatrol will complain this: HEAP[asnparser.exe]: Invalid Address specified to RtlSizeHeap( b90000, ba1c40 )).

Any idea?

Thanks

Avatar of vbk_bgm
vbk_bgm

Provide the pure virtual function a body in the absolute base class and put an assert statement. Code below:
class Base //abstract base class
{
   Base();
   virtual ~Base();
   virtual BOOL PureVirtualCall(void) = 0;
};

class Derived : public Base
{
   Derived();
   ~Derived();
   BOOL PureVirtualCall(void)
   {
     cout << "I am in Derived class here";
   }
};

//in cpp file
BOOL Base::PureVirtualCall(void)
{
  //if this is called implies a pure virtual function has been called
   cout << "Unexpected pure virtual function called";
   assert(0);
   return TRUE;
}


P.S. You may have to put such statements at all pure virtual functions body to get to the call that is causing the problem
If its a 3rd party thing than it means its a bug in their code and u can do nothing about it.
If its yours, see the above comment as a possible solution or use try-catch to fetch the error...
Avatar of lsmgms

ASKER

Hi vbk_bgm,

This method does not work. The pointer does not in vtable although it has implementation.  I use the following codes to test:

#include <iostream>
using namespace std;

typedef void(*Fun)();

class Base {
public:
  Base() {
    cout << "In Base" << endl;
    cout << "Virtual Pointer = " 
         << (int*)this << endl;
    cout << "Address of Vtable = " 
         << (int*)*(int*)this << endl;
    cout << "Value at Vtable 1st entry = " 
         << (int*)*((int*)*(int*)this+0) << endl;
    cout << "Value at Vtable 2nd entry = " 
         << (int*)*((int*)*(int*)this+1) << endl;
   
    // try to execute first virtual function
    Fun pFun = (Fun)*((int*)*(int*)this+0);
    pFun();

    cout << endl;
  }
  virtual void f1() = 0;
  virtual void f2() = 0;
};

void Base::f1()
{
     cout << "Base::f1()" << endl;
}

void Base::f2()
{
     cout << "Base::f2()" << endl;
}


class Drive : public Base {
public:
  Drive() {
    cout << "In Drive" << endl;
    cout << "Virtual Pointer = " 
         << (int*)this << endl;
    cout << "Address of Vtable = " 
         << (int*)*(int*)this << endl;
    cout << "Value at Vtable 1st entry = " 
         << (int*)*((int*)*(int*)this+0) << endl;
    cout << "Value at Vtable 2nd entry = " 
         << (int*)*((int*)*(int*)this+1) << endl;
    cout << endl;
  }
  virtual void f1() { cout << "Drive::f1" << endl; }
  virtual void f2() { cout << "Drive::f2" << endl; }
};


int main() {
  Drive d;

  return 0;
}

Avatar of lsmgms

ASKER

By the way, I have found up the way to debug it.  When the run-time error message box appears, run WinDbg and attach to the process, and then select call stack.  The WinDbg will keep waiting until message box is closed.  The call stack will then show the stacks.

Regards
This question didn't show any activity for more than 21 days. I will ask Community Support to close it unless you finalize it yourself within 7 days.
You can always request to keep this question open. But remember, experts can only help if you provide feedback to their comments.
Unless there is objection or further activity,  I will suggest to

    "refund the points and delete this question"

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
========
Werner
ASKER CERTIFIED SOLUTION
Avatar of SpideyMod
SpideyMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial