Potential Crash: Display Group RootSelection item callbacks; Seen in Purify.
Gnats 5002 -- Phil Weinstein, CADSWES, 01-04-2010.
Display Groups make use of CallbackReceiver as a base class to mark the group as "invalidated" when any members within their RootSelections are deleted. (This applies to both "terminal" RootSelection members and "non-terminal" RootSelection members). Account and Supply (Display) Groups both depend on the special "CallbackReceiver" support using the SIMOBJ_ACCOUNT_DELETED callback type in this SimObj method (in Sim/SimObj.Acct.cpp). (And these and the other Display Group classes depend on this sort of support using other callback types, in other places).
bool
SimObj::deleteAccount (const QString &aname, QString &error)
... ... ...
// Tell the
CallbackReceiverMgr about this as well.
// We do this with an explicit call so that we don't
// have to allocate a callback struct on every object, which
// is inevitably what would happen because so many root selections
// will be on "all" objects.
//
callbackReceiverMgr.invoke (acct,
SIMOBJ_ACCOUNT_DELETED,
(CallbackData
*)(acct));
... The first parameter ('acct' -- an Account pointer) is incorrect. This caused the (amazingly complicated) callback maintenance machinery in the CallbackReceiverMgr and CallbackReceiver classes to not recognize this notification, and not (eventually) remove the Account from the RootSelection before the CallbackReceiver is deleted -- when all callbacks are deleted. In the process of deleting the callback on a SimObj for an Account that had previously been deleted, an invalid pointer to that Account is dereferenced. That memory error is reported in Purify, and could certainly, potentially cause a crash.
The first parameter passed into callbackReceiverMgr.invoke (to generate the SIMOBJ_ACCOUNT_DELETED notification) needed to be a pointer to the SimObj itself, like this:
callbackReceiverMgr.invoke
(this, SIMOBJ_ACCOUNT_DELETED,
(CallbackData
*)(acct));
Note: This CallbackReceiverMgr method is declared as:
void invoke (const Root* object, CallbackType typ, CallbackData* data);
The two memory errors detected by Purify -- one for Account Groups and one for Supply Groups -- see this Purify Output excerpt (purify-2011jan04c.txt) -- are partially illustrated (for Account Groups) in this output trace information:
In the "bug" trace (#1), notice the first "Account dtor" (destrurctor) line for "Big Bear". That's from the deletion of an Account from the workspace. The lines following that line are a result of exiting RiverWare. In both the 6th and the 10th lines following deletion of that Account, you can see the CallbackReceiver attempting to remove callbacks from that Account (i.e. by noticing its address: 16023020, and the a really bad address for the Account's SimObj: "dddddddd".
The "fix" trace (#2) shows that the CallbackReceiver doesn't attempt to delete callbacks (in this way) for the already deleted Account.
---