Skip to content

Commit

Permalink
Fix debugger
Browse files Browse the repository at this point in the history
It is enabled by default for now
  • Loading branch information
RusJJ committed Apr 4, 2024
1 parent 6d0baa2 commit befb1ac
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 38 deletions.
7 changes: 4 additions & 3 deletions cleo4opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ std::set<FILE*> gFilesMap;

// Game Vars
uint8_t* ScriptSpace;
GTAScript **pActiveScripts;
GTAScript **pActiveScripts, **pIdleScripts;
uint8_t* LocalVariablesForCurrentMission;
int* ScriptParams;
uintptr_t gMobileMenu;
Expand Down Expand Up @@ -220,7 +220,7 @@ CLEO_Fn(GET_THIS_SCRIPT_STRUCT)
CLEO_Fn(GOSUB_IF_FALSE)
{
int offset = cleo->ReadParam(handle)->i;
bool condition = *(bool*)((uintptr_t)handle + ValueForGame(120, 121, 229, 525, 521));
bool condition = GetCond(handle);
if(!condition)
{
PushStack(handle);
Expand Down Expand Up @@ -321,7 +321,7 @@ CLEO_Fn(CLEO_CALL)
char buf[MAX_STR_LEN];
static int arguments[40];
int maxParams = ValueForSA(40, 16);
int* scope = (int*)((uintptr_t)handle + ValueForGame(48, 48, 60, 96, 520));
int* scope = GetLocalVars(handle);
if(*nGameIdent == GTASA && IsMissionScript(handle)) scope = (int*)LocalVariablesForCurrentMission;
int* scopeEnd = scope + maxParams;
int* storedLocals = scmFunc->savedTls;
Expand Down Expand Up @@ -1464,6 +1464,7 @@ void Init4Opcodes()
SET_TO(ScriptSpace, cleo->GetMainLibrarySymbol("_ZN11CTheScripts11ScriptSpaceE"));
SET_TO(UpdateCompareFlag, cleo->GetMainLibrarySymbol("_ZN14CRunningScript17UpdateCompareFlagEh"));
SET_TO(pActiveScripts, cleo->GetMainLibrarySymbol("_ZN11CTheScripts14pActiveScriptsE"));
SET_TO(pIdleScripts, cleo->GetMainLibrarySymbol("_ZN11CTheScripts12pIdleScriptsE"));
SET_TO(ScriptParams, cleo->GetMainLibrarySymbol("ScriptParams"));
SET_TO(GetPedFromRef, cleo->GetMainLibrarySymbol("_ZN6CPools6GetPedEi"));
SET_TO(GetVehicleFromRef, cleo->GetMainLibrarySymbol("_ZN6CPools10GetVehicleEi"));
Expand Down
42 changes: 40 additions & 2 deletions cleohelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ inline uint16_t& GetStackDepth(void* handle)
}
inline bool& GetCond(void* handle)
{
return *(bool*)((uintptr_t)handle + ValueForGame(121, 121, 229));
return *(bool*)((uintptr_t)handle + ValueForGame(121, 121, 229, 525, 521));
}
inline bool& GetNotFlag(void* handle)
{
Expand Down Expand Up @@ -855,6 +855,44 @@ inline const char* GetVarTypeName(eScriptParameterType type)
return "UNKNOWN";
}

extern GTAScript **pActiveScripts, **pIdleScripts;
inline bool IsInActiveScripts(void* handle)
{
for (GTAScript* script = *pActiveScripts; script != NULL; script = script->next)
{
if (script == handle)
{
return true;
}
}
return false;
}
inline bool IsInPausedScripts(void* handle)
{
for (GTAScript* script = *pIdleScripts; script != NULL; script = script->next)
{
if (script == handle)
{
return true;
}
}
return false;
}
inline bool IsInCLEOScripts(void* handle)
{
int len = GetScriptsStorageSize();
for(int i = 0; i < len; ++i)
{
int storageItem = *(int*)(*pScriptsStorage + i * 4);
if(*(void**)(storageItem + 28) == handle) return true;
}
return false;
}
inline bool IsValidScriptHandle(void* handle)
{
return IsInActiveScripts(handle) || IsInPausedScripts(handle) || IsInCLEOScripts(handle);
}

// CLEO5
struct PausedScriptInfo
{
Expand All @@ -863,4 +901,4 @@ struct PausedScriptInfo
PausedScriptInfo(GTAScript* ptr, const char* msg) : ptr(ptr), msg(msg) {}
PausedScriptInfo(void* ptr, const char* msg) : ptr((GTAScript*)ptr), msg(msg) {}
};
extern std::deque<PausedScriptInfo> pausedScripts;
extern std::deque<PausedScriptInfo> pausedScripts;
92 changes: 59 additions & 33 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ void** (*LookupForOpcodeFunc)(void* storage, uint16_t& opcode);
extern unsigned char cleoData[100160];

// CLEO crashlogging
#define SCRIPTS_LOG_COUNT 16
void *lastScriptHandle[SCRIPTS_LOG_COUNT] = {NULL};
uint8_t *lastScriptPC[SCRIPTS_LOG_COUNT] = {NULL};
#define SCRIPTS_LOG_COUNT 32
bool scriptDebugger = true;
void *lastScriptHandle[SCRIPTS_LOG_COUNT] = { NULL };
uint8_t *lastScriptPC[SCRIPTS_LOG_COUNT] = { NULL };
uint16_t lastScriptOp[SCRIPTS_LOG_COUNT] = { 0x0000 };

// Config-functions
const char* pLocations[] =
Expand All @@ -113,8 +115,6 @@ void OnRedArrowChanged(int oldVal, int newVal, void* userdata)
cfg->Save();
}



extern "C" __attribute__((target("thumb-mode"))) __attribute__((naked)) void Opcode0DD2_inject()
{
//see https://github.com/XMDS/OP_0DD2FixAsm_call.git (cleo verison)
Expand Down Expand Up @@ -195,16 +195,18 @@ DECL_HOOKb(CLEO_OnOpcodeCall, void *storageItem, uint16_t opcode)
void* g_pForceInterrupt = NULL;
DECL_HOOK(int8_t, ProcessOneCommand, void* handle)
{
for(int i = SCRIPTS_LOG_COUNT-2; i >= 0; --i)
if(scriptDebugger)
{
lastScriptHandle[i + 1] = lastScriptHandle[i];
lastScriptPC[i + 1] = lastScriptPC[i];
for(int i = SCRIPTS_LOG_COUNT-2; i >= 0; --i)
{
lastScriptHandle[i + 1] = lastScriptHandle[i];
lastScriptPC[i + 1] = lastScriptPC[i];
lastScriptOp[i + 1] = lastScriptOp[i];
}
lastScriptHandle[0] = handle;
lastScriptPC[0] = GetPC(handle);
lastScriptOp[0] = Read2Bytes_NoSkip(handle);
}
lastScriptHandle[0] = handle;
lastScriptPC[0] = GetPC(handle);

// no lastScriptOpcode here for optimisations!
// its inside lastScriptPC at this stage! :p

int siz = pausedScripts.size();
for (size_t i = 0; i < siz; ++i)
Expand Down Expand Up @@ -563,31 +565,55 @@ extern "C" void OnAllModsLoaded()
}
}


extern "C" void OnGameCrash(const char* szLibName, int sig, int code, uintptr_t libaddr, mcontext_t* mcontext)
{
// Print lastScript* data to the cleo logging!
if(!cleo) return;
cleo->PrintToCleoLog("[ The game crashed ]");
cleo->PrintToCleoLog("Callstack:");

char buf[512];
int callNum = 0;
for(int i = SCRIPTS_LOG_COUNT-1; i >= 0; ++i)
if(scriptDebugger)
{
if(!lastScriptHandle[i] || !lastScriptPC[i]) continue;

// Check if this script handle is still correct
// If it is, we have a name, filename, a complete script code and more!
if(false) return;
uint8_t *backupPC = GetPC(lastScriptHandle[i]);
GetPC(lastScriptHandle[i]) = lastScriptPC[i];

uint16_t lastScriptOpcode = Read2Bytes(lastScriptHandle[i]);
bool isCustom = GetAddonInfo(lastScriptHandle[i]).isCustom;
const char* scrName = isCustom ? CLEO_GetScriptFilename(lastScriptHandle[i]) : ((GTAScript*)lastScriptHandle[i])->name;
snprintf(buf, sizeof(buf), "Call #%d, opcode %04X, script %s", callNum++, lastScriptOpcode, scrName);
cleo->PrintToCleoLog(buf);
char buf[512], defName[8], custName[128];
int callNum = 0;

cleo->PrintToCleoLog("The data below is not guaranteed to be correct!");
cleo->PrintToCleoLog("Calling history:");
for(int i = SCRIPTS_LOG_COUNT-1; i >= 0; --i)
{
if(!lastScriptHandle[i] || !lastScriptPC[i]) continue;

// Check if this script handle is still correct
// If it is, we have a name, filename, a complete script code and more!
if(!IsValidScriptHandle(lastScriptHandle[i]))
{
// It does not contain a valid data anymore: was deleted or something like that.
snprintf(buf, sizeof(buf), "CALL #%d, Unknown Script 0x%08X, OpCode %04X", ++callNum, (uintptr_t)lastScriptHandle[i], lastScriptOp[i]);
cleo->PrintToCleoLog(buf);
continue;
}

uint8_t *backupPC = GetPC(lastScriptHandle[i]);
GetPC(lastScriptHandle[i]) = lastScriptPC[i];

bool isCustom = GetAddonInfo(lastScriptHandle[i]).isCustom;
uint16_t lastScriptOpcode = Read2Bytes(lastScriptHandle[i]);
strncpy(defName, ((GTAScript*)lastScriptHandle[i])->name, sizeof(defName)); defName[sizeof(defName)-1] = 0;
custName[0] = 0;
if(isCustom)
{
const char* filename = CLEO_GetScriptFilename(lastScriptHandle[i]);
if(filename) strncpy(custName, filename, sizeof(custName)); custName[sizeof(custName)-1] = 0;
}

snprintf(buf, sizeof(buf), "CALL #%d, %s Script '%s', OpCode %04X", ++callNum, isCustom ? "CLEO" : "Game", custName[0] != 0 ? custName : defName, lastScriptOpcode);
cleo->PrintToCleoLog(buf);

GetPC(lastScriptHandle[i]) = backupPC;
}
cleo->PrintToCleoLog("[ Crashlog Ending ]");
}
cleo->PrintToCleoLog("[ Crashlog ending ]");
}
else
{
cleo->PrintToCleoLog("[ Script debugging was not enabled ]");
}
}

0 comments on commit befb1ac

Please sign in to comment.