Audiokinetic's Community Q&A is the forum where users can ask and answer questions within the Wwise and Strata communities. If you would like to get an answer from Audiokinetic's Technical support team, make sure you use the Support Tickets page.

+5 votes
We upgraded from 2019.2.2 to 2019.2.5 and now we crash in "FAkComponentCallbackManager::AkComponentCallback" because

"HandleAction" is sometimes called on packages that have been deleted.

 

"FAkComponentCallbackManager::UnregisterGameObject" is called first and deletes the package.

Later on, "FAkComponentCallbackManager::AkComponentCallback" is called for the deleted package and calls "HandleAction" on it.

 

In order to fix the issue, we check "pPackageSet" before checking "pPackage->uUserFlags" and calling "pPackage->HandleAction".

Not sure if there is any side effects.
in General Discussion by Filipe F. (190 points)
retagged by Filipe F.

2 Answers

0 votes
 
Best answer
Fix is quite easy. You need to first check if pPackageSet for in_pCallbackInfo->gameObjID is not nullptr and if pPackage is inside the pPackageSet then you can HandleAction.
by Karel B. (610 points)
selected by Filipe F.
Hi Karel, thanks for this. Could you please provide instructions on how to apply this fix?
+5 votes
I don't know if it is correct but it won't crash anymore. 我不知道是否正确,但至少不崩溃了。

if ((pPackage->uUserFlags & in_eType) != 0)

{

    PackageSet* pPackageSet = Instance->GameObjectToPackagesMap.Find(gameObjID);

    if (pPackageSet && (*pPackageSet).Contains(pPackage))

    {

        pPackage->HandleAction(in_eType, in_pCallbackInfo);

    }

}
by sun x. (240 points)
From what i have seen from the code, i think in order to access GameObjectToPackagesMap you have to lock "Instance->CriticalSection".
Also i am not confortable with checking "pPackage->uUserFlags" when "pPackage" has been deleted.

I created the post mainly to warn others of the issue.

This is the fix i am using since the first post :

auto pPackage = (IAkUserEventCallbackPackage*)in_pCallbackInfo->pCookie;

if (Instance && pPackage)
{
    const auto& gameObjID = in_pCallbackInfo->gameObjID;
    bool deletePackage = false;
//  begin edit
    bool allowHandleAction = true;
//  end edit
    {
    FScopeLock Lock(&Instance->CriticalSection);
    auto pPackageSet = Instance->GameObjectToPackagesMap.Find(gameObjID);
//  begin edit
    allowHandleAction = (pPackageSet != nullptr);
//  end edit
    if (pPackageSet && in_eType == AK_EndOfEvent)
    {
        Instance->RemovePackageFromSet(pPackageSet, pPackage, gameObjID);
        deletePackage = true;
    }
}

if (in_eType == AK_EndOfEvent)
{
    if (auto* Device = FAkAudioDevice::Get())
    {
        Device->RemovePlayingID(((AkEventCallbackInfo*)in_pCallbackInfo)->eventID, ((AkEventCallbackInfo*)in_pCallbackInfo)->playingID);
                Device->CleanPinnedObjects(((AkEventCallbackInfo*)in_pCallbackInfo)->playingID);
    }
}
//  begin edit
if (allowHandleAction && ((pPackage->uUserFlags & in_eType) != 0))
{
    pPackage->HandleAction(in_eType, in_pCallbackInfo);
}
//  end edit
I was having crashes (mostly on Android) from this issue but these fixes have worked for me so far.
was just getting ready to submit a bug-report including our fix that is pretty much exactly what Filipe did. I agree, this seems the correct way to handle it. The only question I have is that it's an indirect way to test whether the package is deleted. Is there any way the package can exist but not be in the GameObjectToPackagesMap?? For example, can there be a sound running with a callback that's not associated with a game object?  I don't think so, but if that can happen, it's going to miss its callback.
...