Skip to content
Permalink
Browse files

Revert 48f2c99 Debugging code for anim crashes

  • Loading branch information...
codenulls committed Aug 3, 2019
1 parent 5b8ddbd commit 4a1aadf6dff19fe3dfef28ef4bc4d92fdbca383a
@@ -50,6 +50,8 @@ unsigned long CMultiplayerSA::ADDR_GotFocus;

unsigned long CMultiplayerSA::FUNC_CPlayerInfoBase;

std::array<unsigned int, 3> CMultiplayerSA::arrGroupsToProtect = {{ANIM_GROUP_BBBAT_1, ANIM_GROUP_MUSCULAR, ANIM_GROUP_SWORD_1}};

#define HOOKPOS_FxManager_CreateFxSystem 0x4A9BE0
#define HOOKPOS_FxManager_DestroyFxSystem 0x4A9810

@@ -288,10 +288,11 @@ class CMultiplayerSA : public CMultiplayer
DWORD GetLastStaticAnimationID() { return m_dwLastStaticAnimID; }
DWORD GetLastAnimArrayAddress() { return m_dwLastAnimArrayAddress; }

CVector m_vecAkimboTarget;
bool m_bAkimboTargetUp;
static char* ms_PlayerImgCachePtr;
bool m_bBadDrivebyHitboxesDisabled;
CVector m_vecAkimboTarget;
bool m_bAkimboTargetUp;
static char* ms_PlayerImgCachePtr;
static std::array<unsigned int, 3> arrGroupsToProtect;
bool m_bBadDrivebyHitboxesDisabled;

private:
bool m_bSuspensionEnabled;
@@ -13,6 +13,7 @@
#include "../game_sa/CTasksSA.h"
#include "../game_sa/CAnimBlendSequenceSA.h"
#include "../game_sa/CAnimBlendHierarchySA.h"
#include "../game_sa/CAnimBlendAssocGroupSA.h"

void CPlayerPed__ProcessControl_Abort();

@@ -1463,10 +1464,10 @@ void OnMY_CAnimBlendNode_GetCurrentTranslation(CAnimBlendNodeSAInterface* pInter
// Crash will occur at offset 0xCFCD6
OnCrashAverted(32);
CAnimBlendAssociationSAInterface* pAnimAssoc = pInterface->pAnimBlendAssociation;
CAnimBlendSequenceSAInterface* pAnimSequence = pInterface->pAnimSequence;
CAnimBlendHierarchySAInterface* pAnimHierarchy = pAnimAssoc->pAnimHierarchy;
CAnimBlendSequenceSAInterface* pAnimSequence = pInterface->pAnimSequence;
CAnimBlendHierarchySAInterface* pAnimHierarchy = pAnimAssoc->pAnimHierarchy;

bool bSequenceExistsInHierarchy = false;
bool bSequenceExistsInHierarchy = false;
CAnimBlendSequenceSAInterface* pAnimHierSequence = pAnimHierarchy->pSequences;
for (int i = 0; i < pAnimHierarchy->usNumSequences; i++)
{
@@ -1479,13 +1480,12 @@ void OnMY_CAnimBlendNode_GetCurrentTranslation(CAnimBlendNodeSAInterface* pInter
}

LogEvent(588, "GetCurrentTranslation", "Incorrect endKeyFrameIndex",
SString("m_endKeyFrameId = %d | pAnimAssoc = %p | GroupID = %d | AnimID = %d | \
SString("m_endKeyFrameId = %d | pAnimAssoc = %p | GroupID = %d | AnimID = %d | \
pAnimSeq = %p | BoneID = %d | BoneHash = %u | \
pAnimHier = %p | HierHash = %u | SequenceExistsInHierarchy: %s",
pInterface->m_endKeyFrameId, pAnimAssoc, pAnimAssoc->sAnimGroup, pAnimAssoc->sAnimID,
pAnimSequence, pAnimSequence->m_boneId, pAnimSequence->m_hash, pAnimHierarchy,
pAnimHierarchy->uiHashKey, bSequenceExistsInHierarchy ? "Yes" : "No"), 588);

pInterface->m_endKeyFrameId, pAnimAssoc, pAnimAssoc->sAnimGroup, pAnimAssoc->sAnimID, pAnimSequence, pAnimSequence->m_boneId,
pAnimSequence->m_hash, pAnimHierarchy, pAnimHierarchy->uiHashKey, bSequenceExistsInHierarchy ? "Yes" : "No"),
588);
}

// Hook info
@@ -1521,6 +1521,67 @@ void _declspec(naked) HOOK_CAnimBlendNode_GetCurrentTranslation()
}
}

//////////////////////////////////////////////////////////////////////////////////////////
//
// CAnimManager_CreateAnimAssocGroups
//
// Protect `pAssociationsArray` member of specific anim groups (CAnimBlendAssocGroupSAInterface)
// from corruption by placing a WRITE operation breakpoint on its address.
//
//////////////////////////////////////////////////////////////////////////////////////////
void __cdecl OnMY_CAnimManager_CreateAnimAssocGroups_Protect(CAnimBlendAssocGroupSAInterface* pGroupInterface)
{
static std::set<unsigned int> setOfGroupBreakpointsAdded;

void* ppAssociationsArray = reinterpret_cast<void*>(&pGroupInterface->pAssociationsArray);
for (auto groupID : CMultiplayerSA::arrGroupsToProtect)
{
if (pGroupInterface->groupID == groupID && !MapContains(setOfGroupBreakpointsAdded, groupID))
{
HANDLE mainThread = OpenThread(THREAD_ALL_ACCESS, TRUE, SharedUtil::GetMainThreadId());
assert(mainThread != NULL);

SetHardwareBreakpoint(mainThread, HWBRK_TYPE_WRITE, HWBRK_SIZE_4, ppAssociationsArray);

CloseHandle(mainThread);

setOfGroupBreakpointsAdded.insert(groupID);

LogEvent(511, "Breakpoint", "Hardware Breakpoint set on WRITE access",
SString("groupID: %u | pGroupInterface: %#.8x, ppAssociationsArray = %#.8x | pAssociationsArray: %p", groupID, pGroupInterface,
ppAssociationsArray, pGroupInterface->pAssociationsArray),
511);
return;
}
}

LogEvent(512, "GroupLoaded", "Anim group loaded",
SString("groupID: %u | pGroupInterface: %#.8x, ppAssociationsArray = %#.8x | pAssociationsArray: %p", pGroupInterface->groupID, pGroupInterface,
ppAssociationsArray, pGroupInterface->pAssociationsArray),
512);
}

// Hook info
#define HOOKPOS_CAnimManager_CreateAnimAssocGroups_Protect 0x4D3DAD
#define HOOKSIZE_CAnimManager_CreateAnimAssocGroups_Protect 6
DWORD RETURN_CAnimManager_CreateAnimAssocGroups_Protect = 0x4D3DB3;
void _declspec(naked) HOOK_CAnimManager_CreateAnimAssocGroups_Protect()
{
_asm
{
pushad
add eax, esi
push eax
call OnMY_CAnimManager_CreateAnimAssocGroups_Protect
add esp, 0x4
popad

mov ecx, [esi + eax + 8]
xor edi, edi
jmp RETURN_CAnimManager_CreateAnimAssocGroups_Protect
}
}

//////////////////////////////////////////////////////////////////////////////////////////
//
// Setup hooks for CrashFixHacks
@@ -1566,6 +1627,7 @@ void CMultiplayerSA::InitHooks_CrashFixHacks()
EZHookInstallChecked(CVolumetricShadowMgr_Update);
EZHookInstallChecked(CAnimManager_CreateAnimAssocGroups);
EZHookInstall(CAnimBlendNode_GetCurrentTranslation);
EZHookInstall(CAnimManager_CreateAnimAssocGroups_Protect);
EZHookInstall(CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask);
EZHookInstallChecked(printf);
EZHookInstallChecked(RwMatrixMultiply);
@@ -547,6 +547,46 @@ void _declspec(naked) HOOK_CTaskSimpleRunNamedAnimDestructor()
}
}

void _cdecl OnCAnimBlendAssocGroupDestructor(CAnimBlendAssocGroupSAInterface* pGroupInterface)
{
for (auto groupID : CMultiplayerSA::arrGroupsToProtect)
{
if (pGroupInterface->groupID == groupID)
{
void* ppAssociationsArray = reinterpret_cast<void*>(&pGroupInterface->pAssociationsArray);
LogEvent(519, "groupUnload", "Unloading anim group",
SString("groupID: %u | pGroupInterface: %#.8x, ppAssociationsArray = %#.8x | pAssociationsArray: %p", groupID, pGroupInterface,
ppAssociationsArray, pGroupInterface->pAssociationsArray),
519);

// crash it to get the stack
void* pPointer = nullptr;
assert(pPointer != nullptr);
}
}
}

// Hook info
#define HOOKPOS_CAnimBlendAssocGroupDestructor 0x4CE1D0
#define HOOKSIZE_CAnimBlendAssocGroupDestructor 6
DWORD RETURN_CAnimBlendAssocGroupDestructor = 0x4CE1D6;
void _declspec(naked) HOOK_CAnimBlendAssocGroupDestructor()
{
_asm
{
pushad
push ecx
call OnCAnimBlendAssocGroupDestructor
add esp, 0x4
popad

push esi
mov esi, ecx
mov ecx, [esi + 0x4]
jmp RETURN_CAnimBlendAssocGroupDestructor
}
}

//////////////////////////////////////////////////////////////////////////////////////////
//
// Set handlers
@@ -594,6 +634,7 @@ void CMultiplayerSA::SetGameRunNamedAnimDestructorHandler(GameRunNamedAnimDestru
//////////////////////////////////////////////////////////////////////////////////////////
void CMultiplayerSA::InitHooks_HookDestructors()
{
EZHookInstall(CAnimBlendAssocGroupDestructor);
EZHookInstall(CTaskSimpleRunNamedAnimDestructor);
EZHookInstall(CObjectDestructor);
EZHookInstall(CVehicleDestructor);
@@ -39,6 +39,7 @@
#include "..\game_sa\CEntitySA.h"
#include "..\game_sa\CBuildingSA.h"
#include "..\game_sa\CPedSA.h"
#include "..\game_sa\CAnimBlendAssocGroupSA.h"
#include "..\game_sa\common.h"
#include "..\core\CCrashDumpWriter.h"

1 comment on commit 4a1aadf

@Dutchman101

This comment has been minimized.

Copy link
Contributor

commented on 4a1aadf Aug 5, 2019

Please note that these changes (4a1aadf and 9728a27) can make master unstable/degrade performance and are purely for temporary debugging (a couple of days until there were a couple of crashes that we're looking for), this kind of stuff is exactly why nightlies exist - it should be reverted before circulating any build beyond nightly or the release of 1.5.7

Actually, the commits were previously reverted to make a good timing of when nothing was scheduled near it that required them not to be in master (like the chance of update roll-outs)

EDIT: this no longer applies as from 2fdf9a4 - the debug code has been removed and the unloading modification has been made stable in 1e234b6 and 081ebdc

Please sign in to comment.
You can’t perform that action at this time.