Wednesday, April 28, 2010

Pure Virtual Function Call (Destructor Madness)

Not the friendliest one to see, I bet, when you’re trying to make your way through a day without calling any pure virtual functions… Well, a pure virtual function call is not a rare thing to see in the C++ world, and there are numerous reasons for something like this to happen, not the least of which being calling a pure virtual method from the base class’ constructor. In this post we’re going to see something slightly less traditional. Let’s try to verify what’s going on here.

First, I captured a dump of the application at the moment this dialog was shown. On Vista and above it’s really easy using Task Manager; on earlier OS versions you can use cdb, ntsd, WinDbg, ADPlus—whatever suits you best.

Next, I opened the dump in my trusty old friend WinDbg. Just a couple of threads here:

0:000> ~*
.  0  Id: 1b40.c98 Suspend: 1 Teb: 7efdd000 Unfrozen
     Start: DestructorsAndVirtualMethods!ILT+420(_mainCRTStartup) (013b11a9)
     Priority: 0  Priority class: 32  Affinity: 3
  1  Id: 1b40.140c Suspend: 1 Teb: 7efda000 Unfrozen
     Start: DestructorsAndVirtualMethods!ILT+265(?thread_startthreadCGKPAXZ) (013b110e)
     Priority: 0  Priority class: 32  Affinity: 3

How about these two threads, then? Well, the main thread most certainly didn’t show me that nasty message box:

0:000> k
ChildEBP RetAddr
0020f9c8 757b0816 ntdll!NtWaitForSingleObject+0x15
0020fa34 76031184 KERNELBASE!WaitForSingleObjectEx+0x98
0020fa4c 76031138 kernel32!WaitForSingleObjectExImplementation+0x75
0020fa60 013b18ad kernel32!WaitForSingleObject+0x12
0020fb48 013b184b DestructorsAndVirtualMethods!thread::~thread+0x3d
0020fc28 013b15c5 DestructorsAndVirtualMethods!my_thread::~my_thread+0x2b
0020fd20 013b2c0f DestructorsAndVirtualMethods!main+0x65
0020fd70 013b2a3f DestructorsAndVirtualMethods!__tmainCRTStartup+0x1bf
0020fd78 76033677 DestructorsAndVirtualMethods!mainCRTStartup+0xf
0020fd84 77a19d72 kernel32!BaseThreadInitThunk+0xe
0020fdc4 77a19d45 ntdll!__RtlUserThreadStart+0x70
0020fddc 00000000 ntdll!_RtlUserThreadStart+0x1b

(It’s in the middle of my_thread’s destructor, which called thread’s destructor, which is waiting for something.)

Read more: All Your Base Are Belong To Us

Posted via email from jasper22's posterous