Jump to content

Welcome to Geeks to Go - Register now for FREE

Geeks To Go is a helpful hub, where thousands of volunteer geeks quickly serve friendly answers and support. Check out the forums and get free advice from the experts. Register now to gain access to all of our features, it's FREE and only takes one minute. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more.

Create Account How it Works
Photo

Runtime Error R6025 - Pure Virtual Function Call


  • Please log in to reply

#1
Power Hungry

Power Hungry

    New Member

  • Member
  • Pip
  • 1 posts
Hey all...

This is not just a question, but also a possible solution for anyone who has run into this dreadful error when compiling in Visual C++. I hope it's helpful and I'll try to be as thorough as possible.

Internal test platforms:

* Dell Dimension D3000 (Main PC): P4-3.0GHz, 2G Ram, WinXP Pro SP2, VC++ 6.0 SP5
- Also on this machine, Virtual PC running Win98 SE and WinNT 3.51 to test applications.
* Dell Inspiron 1720: Core2 Duo T5550-1.83GHz, 3,0G Ram, Windows Vista Home Prem.
* Dell Latitude D505: Pentium-1.5GHz, 256M Ram, WinXP Pro SP2

Background:

I came across this error quite by chance after compiling and distributing the release of an application. The software would compile and run just fine on any of my test platforms (listed above), and even most of the customers that ran the software had no problems. However, I came across a customer that had a situation where the application would open fine but when he would go to open a document (MDI) the R6025 error would pop up and kill the program. After some investigation, I realized that I could easily recreate the issue on my test platforms by open new documents in rapid succession (ie. holding down the [Ctrl]+N for New Document). This was curious in that the documents would open up most of the time without incident (well over 100+ documents) and then I'd close the application, reopen, and then have the error occur after the 5th, 18th, 47th, or even 100th+ document. There was no definitive pattern to the error... at least on my platforms. On this particular customer, the error occurred every time a document was opened (either through New or Open).

Now here's where it really gets interesting.

Debugging:

I went through the normal debugging steps.

First, I hit the internet to see just what R6025 was and what information was available. Unfortunately, the bulk of the search responses came up as crap. Mostly, companies trying to sell "registry repair tools" or other such mundane crap. No help there.

Second, I did find some information under the Microsoft KB125749, but it was cryptic at best and really didn't provide me with any real solution. Still no help.

Third, I went back to my old tricks and just started stepping through the program.

Since the error occurred only during the creation of a new document, I started looking at my CMainFrame class and specifically at the routines where I created a new document. Set debuggers for stun! I managed to narrow it down to the calls to "CDocManager::OnFileNew" and "CDocManager::OnFileOpen" (in DOCMGR.CPP) or, more specifically, the "CMultiDocTemplate::OpenDocumentFile" class (in DOCMULTI.CPP). At some point in either the "CDocTemplate::CreateNewFrame" class or the "CDocTemplate::InitialUpdateFrame" classes (in DOCTEMPL.CPP), there would be an inadvertent pure virtual call and the whole thing would blow up. Now being that this is what I would consider "mature" code, I would think that this issue would have been fleshed out quite some time ago. But alas, here we are. After removing every bit of extraneous code from my classes, I ran again with only basic functions and found that I could, indeed, still create the problem. Now, to figure out a way to make the issue go away.

I switched to VS.NET, reloaded the project, and tried another build. No dice. Same error occurring at the same place. Dang! I then switched over to my Virtual PC/Win 98 platform and tried a build on that. Still busted. Double dang! Running out of ideas, I started poking around on the internet a little bit more. Some suggestions were to eliminate optimizations and other sundry items, all of which had no effect on the error. I finally tried one last thing, and LO AND BEHOLD... IT WORKED! My problem was immediately solved. What was this magical fix, you ask? Well let me tell you...

I changed the compiler Calling Convention (Settings, C/C++ Tab, Code Generation Category) from "__cdecl" to "__stdcall" and the problem was immediately resolved. Almost. I did run into another minor issue where all my thread management calls were a little boogered up, resulting in the error "error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (__stdcall *)(void *)'". However, that was fairly easily resolved by changing all the thread worker function declarations from "UINT function(LPVOID param)" to "UINT __cdecl function(LPVOID param)". Once that was done, the program ran perfectly, even on my customer's computer. So now, the real question is...

Why did changing from __cdecl to __stdcall fix the R6025 error? I've stepped through the code a hundred times and can't find a single good reason why changing the calling conventions would have any effect or cause the R6025 error, so at this point I am stumped. I'd really like to understand exactly what happened so I can avoid this in the future, so I defer to those more experienced in this sort of stuff than I am.

Here is a sample of the source that was used which shows the constructor and the template designations. It's all pretty straightforward as far as I can tell.

CMapeditApp::CMapeditApp()
{
  m_keydown_timeout=800;
  m_keyup_end_edit=TRUE;
}

CMapeditApp::~CMapeditApp()
{
}

BEGIN_MESSAGE_MAP(CMapeditApp, CWinApp)
//{{AFX_MSG_MAP(CMapeditApp)
// Standard file based document commands

  ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
  ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
  ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
END_MESSAGE_MAP()

BOOL CMapeditApp::InitInstance()
{
  AfxBeginThread(UpdateThread, &g_keyReg);
  
#ifdef _AFXDLL
  Enable3dControls();  // Call this when using MFC in a shared DLL
#else
  Enable3dControlsStatic();  // Call this when linking to MFC statically
#endif

  // Load standard INI file options (including MRU List)
  LoadStdProfileSettings(10);

  m_HelpMenu.LoadMenu(IDR_HELP);

  // Build the Main frame.
  CMainFrame* pMainFrame = new CMainFrame;   // create main MDI Frame window

  // Verify the Main frame has been constructed.
  if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
    return FALSE;

  // Append the "Help" menu to the Main frame.
  AppendHelpMenu(pMainFrame->m_hMenuDefault);

  // The main window has been initialized, so show and update it.
  pMainFrame->ShowWindow(m_nCmdShow);
  pMainFrame->UpdateWindow();

  // Register the application's document templates.  Document templates
  // serve as the connection between documents, frame windows and views.

  m_pDocTemplOverview = new CMultiDocTemplate(
    IDR_MAPEDITYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(COverviewView));

  // Load the Overview template into the template list.
  CWinApp::AddDocTemplate(m_pDocTemplOverview);

  m_pDocTemplParam=new CMultiDocTemplate(
    IDR_PARAMVIEWTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CParamView));

  m_pDocTemplMap=new CMultiDocTemplate(
    IDR_MAPVIEWTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CMapView));

  m_pDocTemplFunc=new CMultiDocTemplate(
    IDR_FUNCVIEWTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CFuncView));

  m_pDocTemplHex=new CMultiDocTemplate(
    IDR_HEXVIEWTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CHexView));

  m_pDocTemplChecksum=new CMultiDocTemplate(
    IDR_CHECKSUMVIEWTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CChecksumView));

  m_pDocTemplEmulator=new CMultiDocTemplate(
    IDR_EMULATORVIEWTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CEmulatorView));

  m_pDocTemplResHelp=new CMultiDocTemplate(
    IDR_RESHELPTYPE,
    RUNTIME_CLASS(CMapeditDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(CResHelpView));

  return TRUE;
}

Any ideas or explanations as to why this would throw a fit on the construction of the document?

Thanks in advance!
  • 0

Advertisements







Similar Topics

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

As Featured On:

Microsoft Yahoo BBC MSN PC Magazine Washington Post HP