fix: split verbose logging into dedicated script to resolve Stack-Heap Collision

CRITICAL ARCHITECTURE CHANGE to resolve memory crashes:

NEW FILE: Verbose_Logger.lsl
- Dedicated script for all debug output to free up memory in Main Controller
- Handles verbose logging toggle and message buffering
- Script ID system for organized log prefixes
- Memory-safe batched output system

MAIN CONTROLLER CHANGES:
- Removed all verbose logging code and variables
- Redirected debug calls to dedicated Verbose_Logger script
- Simplified verbose logging toggle to forward to logger
- Removed memory-heavy string operations

This architectural split should immediately resolve the Stack-Heap Collision
by moving all debug-related memory usage out of the Main Controller.
This commit is contained in:
RebeccaNod1 2025-09-14 09:42:09 -05:00
parent bb06bf74dd
commit e5f093e0f6
2 changed files with 147 additions and 40 deletions

View file

@ -80,30 +80,18 @@ float timerInterval = 1.0; // How often timer() is called for checks
// Debug control - set to TRUE for verbose pick debugging, FALSE for normal operation
integer DEBUG_PICKS = FALSE;
// Verbose logging system - affects all modules when toggled
integer VERBOSE_LOGGING = FALSE;
// Verbose logging moved to dedicated Verbose_Logger.lsl script to save memory
// Message constants for verbose logging
integer MSG_VERBOSE_LOG = 9020;
integer MSG_VERBOSE_TOGGLE = 9010;
// Emergency memory management - disable verbose logging if memory gets low
emergencyMemoryCheck() {
if (llGetFreeMemory() < 1000) {
VERBOSE_LOGGING = FALSE;
llOwnerSay("⚠️ Low memory detected - auto-disabling verbose logging");
}
}
// Script ID for Main Controller (used by Verbose_Logger for prefixes)
integer SCRIPT_ID_MAIN = 0;
// Memory-efficient debug function to prevent Stack-Heap Collision
// Memory-safe debug function - forwards to dedicated logger
debugMsg(string msg) {
emergencyMemoryCheck();
if (VERBOSE_LOGGING && llGetFreeMemory() > 500) {
llOwnerSay("[M] " + msg);
}
}
// Ultra-light debug for critical paths only
lightDebug(string msg) {
if (VERBOSE_LOGGING && llGetFreeMemory() > 300) {
llOwnerSay(msg);
}
// Forward to dedicated verbose logger to save memory in Main Controller
llMessageLinked(LINK_SET, MSG_VERBOSE_LOG, (string)SCRIPT_ID_MAIN + "|" + msg, NULL_KEY);
}
// Status message timing
@ -482,10 +470,7 @@ default {
integer shouldBePicking = FALSE;
if (currentPickerIdx < llGetListLength(pickQueue)) {
string expectedPickerName = llList2String(pickQueue, currentPickerIdx);
if (VERBOSE_LOGGING) {
debugMsg("Touch: " + playerName + " exp:" + expectedPickerName);
debugMsg("Idx:" + (string)currentPickerIdx);
}
debugMsg("Touch recovery: " + playerName);
if (playerName == expectedPickerName) {
shouldBePicking = TRUE;
// Fix corrupted currentPicker state
@ -495,8 +480,8 @@ default {
currentPicker = toucher;
}
}
} else if (VERBOSE_LOGGING) {
debugMsg("Pick phase done - idx >= queue len");
} else {
debugMsg("Pick phase complete");
}
// FALLBACK: If game is stuck and no one is set as current picker, but we're in pick phase,
@ -1146,19 +1131,10 @@ default {
return;
}
// Handle verbose logging toggle
if (num == 9010 && str == "TOGGLE_VERBOSE_LOGS") {
VERBOSE_LOGGING = !VERBOSE_LOGGING;
if (VERBOSE_LOGGING) {
llOwnerSay("Debug: ON");
llSay(0, "Debug: ON");
} else {
llOwnerSay("Debug: OFF");
llSay(0, "Debug: OFF");
}
// Broadcast the setting to all modules
llMessageLinked(LINK_SET, 9011, "VERBOSE_LOGGING|" + (string)VERBOSE_LOGGING, id);
// Handle verbose logging toggle - redirect to dedicated Verbose_Logger script
if (num == MSG_VERBOSE_TOGGLE && str == "TOGGLE_VERBOSE_LOGS") {
// Forward to dedicated verbose logger script
llMessageLinked(LINK_SET, MSG_VERBOSE_TOGGLE, "TOGGLE_VERBOSE_LOGS", id);
return;
}

131
Verbose_Logger.lsl Normal file
View file

@ -0,0 +1,131 @@
// === Verbose Logger - Dedicated Debug Output Handler ===
// This script handles all verbose logging to reduce memory usage in Main Controller
// and other core game scripts
// Verbose logging control
integer VERBOSE_LOGGING = FALSE;
// Message constants for verbose logging system
integer MSG_VERBOSE_LOG = 9020; // Request to log a message
integer MSG_VERBOSE_TOGGLE = 9010; // Toggle verbose logging on/off
integer MSG_VERBOSE_BROADCAST = 9011; // Broadcast logging state to all modules
// Memory monitoring
integer MSG_MEMORY_REPORT_VERBOSE = 9025;
// Script identification for log prefixes
list SCRIPT_PREFIXES = [
"Main", "Game", "Dialog", "Roll", "Bot", "Float", "Calc",
"Mem", "Msg", "Score", "Lead", "Dice", "Debug", "Num"
];
// Buffer for batching messages to reduce spam
list messageBuffer = [];
integer BUFFER_SIZE = 5;
float FLUSH_INTERVAL = 2.0;
default {
state_entry() {
llOwnerSay("🔍 Verbose Logger initialized - ready to handle debug output");
llSetTimerEvent(FLUSH_INTERVAL);
}
on_rez(integer start_param) {
llOwnerSay("🔍 Verbose Logger rezzed - debug system ready");
VERBOSE_LOGGING = FALSE; // Default to off after rez
messageBuffer = [];
llSetTimerEvent(FLUSH_INTERVAL);
}
link_message(integer sender, integer num, string str, key id) {
// Handle verbose logging toggle
if (num == MSG_VERBOSE_TOGGLE && str == "TOGGLE_VERBOSE_LOGS") {
VERBOSE_LOGGING = !VERBOSE_LOGGING;
string status = "OFF";
if (VERBOSE_LOGGING) {
status = "ON";
llOwnerSay("🔍 [Verbose Logger] Debug logging: ENABLED");
} else {
llOwnerSay("🔍 [Verbose Logger] Debug logging: DISABLED");
messageBuffer = []; // Clear buffer when disabled
}
// Public announcement
llSay(0, "🔍 Verbose logging system-wide: " + status);
// Broadcast the new setting to all modules
llMessageLinked(LINK_SET, MSG_VERBOSE_BROADCAST, "VERBOSE_LOGGING|" + (string)VERBOSE_LOGGING, id);
return;
}
// Handle verbose logging broadcast from other scripts
if (num == MSG_VERBOSE_BROADCAST) {
list parts = llParseString2List(str, ["|"], []);
if (llList2String(parts, 0) == "VERBOSE_LOGGING") {
VERBOSE_LOGGING = llList2Integer(parts, 1);
return;
}
}
// Handle log message requests
if (num == MSG_VERBOSE_LOG && VERBOSE_LOGGING) {
// Format: "SCRIPT_ID|MESSAGE"
list parts = llParseString2List(str, ["|"], []);
if (llGetListLength(parts) >= 2) {
integer scriptId = llList2Integer(parts, 0);
string message = llList2String(parts, 1);
string prefix = "[Unknown]";
if (scriptId >= 0 && scriptId < llGetListLength(SCRIPT_PREFIXES)) {
prefix = "[" + llList2String(SCRIPT_PREFIXES, scriptId) + "]";
}
string logMessage = prefix + " " + message;
// Add to buffer for batched output
messageBuffer += [logMessage];
// If buffer is full, flush immediately
if (llGetListLength(messageBuffer) >= BUFFER_SIZE) {
flushMessageBuffer();
}
}
return;
}
// Handle memory report request
if (num == MSG_MEMORY_REPORT_VERBOSE) {
reportMemoryStatus();
return;
}
}
timer() {
// Periodic buffer flush
if (VERBOSE_LOGGING && llGetListLength(messageBuffer) > 0) {
flushMessageBuffer();
}
}
}
// Flush all buffered messages to owner
flushMessageBuffer() {
if (llGetListLength(messageBuffer) == 0) return;
integer i;
for (i = 0; i < llGetListLength(messageBuffer); i++) {
llOwnerSay(llList2String(messageBuffer, i));
}
messageBuffer = [];
}
// Report memory status of this script
reportMemoryStatus() {
if (VERBOSE_LOGGING) {
integer free = llGetFreeMemory();
integer used = llGetUsedMemory();
llOwnerSay("🔍 [Verbose Logger] Memory - Free: " + (string)free + " Used: " + (string)used);
llOwnerSay("🔍 [Verbose Logger] Buffer size: " + (string)llGetListLength(messageBuffer));
}
}