Debugger

¿Qué es un Debugger?

Herramienta de desarrollo que permite ejecutar código paso a paso, inspeccionar variables y analizar el flujo de ejecución para identificar y resolver errores.

Funcionamiento Básico

  • Ejecución Controlada: Pausa la ejecución en puntos específicos
  • Inspección de Estado: Acceso a variables y memoria en tiempo de ejecución
  • Análisis de Flujo: Seguimiento del camino de ejecución del programa

Componentes del Debugger

Call Stack

  • Seguimiento de Llamadas: Muestra la pila de ejecución de funciones/métodos
  • Navegación Jerárquica: Permite ver qué función llamó a la actual
  • Contexto de Ejecución: Cada frame muestra variables locales y parámetros

Breakpoints

  • Puntos de Interrupción: Marcadores que pausan la ejecución
  • Condicionales: Se activan solo cuando se cumple una condición específica
  • Temporales: Se eliminan automáticamente después de activarse

Inspección de Variables

  • Variables Locales: Valores en el contexto actual de ejecución
  • Variables Globales: Estado del ámbito global
  • Watch Expressions: Expresiones personalizadas para monitorear

Step Through

  • Step Into: Entra en la función/método actual
  • Step Over: Ejecuta la línea actual sin entrar en funciones
  • Step Out: Sale de la función actual y continúa
  • Continue: Reanuda la ejecución hasta el próximo breakpoint

Debugging en JavaScript

Herramientas Específicas

// Console debugging
console.log('Variable value:', variable);
console.table(arrayOfObjects);
console.trace('Execution trace');

// Debugger statement
function problematicFunction() {
    debugger; // Pausa la ejecución si el debugger está abierto
    // código problemático
}

Chrome DevTools

// Breakpoints avanzados
// - Line breakpoints
// - Conditional breakpoints  
// - DOM breakpoints
// - Event listener breakpoints
// - XHR/fetch breakpoints

// Ejemplo de watch expressions
const user = { name: 'John', age: 30 };
// Watch: user.name
// Watch: JSON.stringify(user)

Node.js Debugging

# Iniciar con inspector
node --inspect app.js
node --inspect-brk app.js # Pausa al inicio

# Con nodemon para desarrollo
nodemon --inspect app.js

Diferencias entre Lenguajes

JavaScript vs Java

// Java debugging - más estructurado
public class DebugExample {
    public static void main(String[] args) {
        int result = calculate(5, 3);
        System.out.println("Result: " + result);
    }
    public static int calculate(int a, int b) {
        // Punto de interrupción tradicional
        int sum = a + b;
        return sum * 2;
    }
}

Características Comparativas

  • JavaScript: Dinámico, tipado débil, debugging en navegador y Node.js
  • Java: Tipado fuerte, debugging con IDEs robustas (IntelliJ, Eclipse)
  • Python: Debugging interactivo, tipado dinámico
  • C++: Debugging a nivel de memoria, pointers, más complejo

Técnicas Avanzadas de Debugging

Conditional Breakpoints

// Solo se activa cuando se cumple la condición
function processUsers(users) {
    for (let user of users) {
        // Breakpoint condicional: user.age > 65
        if (user.age > 65) {
            processSenior(user);
        }
    }
}

Watch Expressions Avanzadas

const data = {
    users: [
        { id: 1, active: true },
        { id: 2, active: false }
    ]
};

// Watch expressions útiles:
// data.users.filter(u => u.active).length
// data.users.map(u => u.id)
// JSON.stringify(data, null, 2)

Call Stack Analysis

function a() {
    b();
}

function b() {
    c();
}

function c() {
    console.trace(); // Muestra call stack completo
    throw new Error('Debug this!');
}

a();

Debugging en Diferentes Entornos

Frontend (Browser)

  • Chrome DevTools: Console, Sources, Network tabs
  • Firefox Developer Tools: Similar funcionalidad
  • Browser Extensions: React DevTools, Vue DevTools

Backend (Node.js)

// Debugging remoto
const inspector = require('inspector');
inspector.open(9229, '0.0.0.0', true);

// Logging estructurado
const debug = require('debug')('app:server');
debug('Server started on port %d', 3000);

IDEs y Editores

  • VS Code: Integrated debugger, launch configurations
  • WebStorm: Debugger avanzado para JavaScript
  • Eclipse/IntelliJ: Para Java y otros lenguajes

Configuraciones de Debugging

VS Code Launch Configuration

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": ["<node_internals>/**"],
            "program": "${workspaceFolder}/app.js",
            "env": {
                "NODE_ENV": "development"
            }
        }
    ]
}

Chrome DevTools Snippets

// Snippets para debugging común
// 1. Monitor de eventos
function monitorEvents(element, events) {
    events.forEach(event => {
        element.addEventListener(event, e => {
            console.log(`Event: ${event}`, e);
        });
    });
}

// 2. Performance measurement
function measurePerf(fn, label = 'Function') {
    console.time(label);
    const result = fn();
    console.timeEnd(label);
    return result;
}

Estrategias de Debugging Efectivo

Metodología Sistemática

  1. Reproducir el Error: Condiciones consistentes
  2. Aislar el Problema: Divide y vencerás
  3. Hipótesis y Verificación: Plantea teorías y compruébalas
  4. Solución y Validación: Corrige y verifica la solución

Herramientas de Apoyo

  • Source Maps: Debugging de código minificado/compilado
  • Network Analysis: Debugging de peticiones HTTP
  • Memory Profiling: Detección de memory leaks
  • Performance Profiling: Identificación de cuellos de botella

Debugging Avanzado

Async/Await Debugging

async function fetchUserData(userId) {
    try {
        // Breakpoint aquí para ver el flujo async
        const response = await fetch(`/users/${userId}`);
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Fetch failed:', error);
        debugger; // Pausa en errores async
    }
}

Promise Debugging

function debugPromise(promise, label) {
    return promise
        .then(result => {
            console.log(`✅ ${label}:`, result);
            return result;
        })
        .catch(error => {
            console.error(`❌ ${label}:`, error);
            debugger;
            throw error;
        });
}

Error Tracking

// Global error handler para debugging
window.addEventListener('error', (event) => {
    console.error('Global error:', event.error);
    console.log('Stack trace:', event.error.stack);
    // Enviar a servicio de tracking
});

Integración con Testing

Debugging en Tests

// Jest debugging
describe('User Service', () => {
    test('should create user', async () => {
        const user = { name: 'Test', email: 'test@example.com' };
        debugger; // Pausa durante test execution
        const result = await userService.create(user);
        expect(result.id).toBeDefined();
    });
});

Browser Automation Debugging

// Puppeteer/Playwright debugging
await page.pause(); // Pausa la ejecución del test
await page.evaluate(() => {
    debugger; // Pausa en contexto del navegador
});

debugging en mas areas con ejemplos de codigo

Debugging de Memoria

Memory Leaks Detection

// Monitor memory usage
function monitorMemory() {
    const used = process.memoryUsage();
    console.log('Memory usage:');
    for (let key in used) {
        console.log(`${key}: ${Math.round(used[key] / 1024 / 1024)} MB`);
    }
}

// Force garbage collection for testing
if (global.gc) {
    global.gc();
}

Heap Snapshots Analysis

// Take heap snapshot in Node.js
const heapdump = require('heapdump');

function takeHeapSnapshot() {
    heapdump.writeSnapshot('/tmp/' + Date.now() + '.heapsnapshot');
}

// Chrome DevTools heap profiling
console.profile('Memory Analysis');
// ... suspicious code
console.profileEnd('Memory Analysis');

Debugging de Performance

Performance Profiling

// High-resolution timing
function measurePerformance(fn, iterations = 1000) {
    const start = performance.now();
    for (let i = 0; i < iterations; i++) {
        fn();
    }
    const end = performance.now();
    console.log(`Average time: ${(end - start) / iterations}ms`);
}

// Function timing wrapper
function withTiming(fn, label = 'Function') {
    return function(...args) {
        console.time(label);
        const result = fn.apply(this, args);
        console.timeEnd(label);
        return result;
    };
}

CPU Profiling

// CPU profiling in Node.js
const profiler = require('v8-profiler-next');
const fs = require('fs');

const profile = profiler.startProfiling('CPU Profile');
setTimeout(() => {
    profile.end().then(profile => {
        fs.writeFileSync('profile.cpuprofile', 
            JSON.stringify(profile));
    });
}, 5000);

Debugging de Red y APIs

Network Request Debugging

// Intercept fetch requests
const originalFetch = window.fetch;
window.fetch = function(...args) {
    console.log('Fetch request:', args);
    return originalFetch.apply(this, args)
        .then(response => {
            console.log('Fetch response:', response);
            return response;
        });
};

// Monitor XMLHttpRequest
const originalXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
    this.addEventListener('load', function() {
        console.log(`XHR ${method} ${url}:`, this.response);
    });
    originalXHROpen.apply(this, arguments);
};

API Response Inspection

// Debug API responses with detailed info
async function debugApiCall(url, options = {}) {
    console.group(`API Call: ${url}`);
    console.log('Request options:', options);
    try {
        const startTime = Date.now();
        const response = await fetch(url, options);
        const duration = Date.now() - startTime;
        console.log(`Status: ${response.status}`);
        console.log(`Duration: ${duration}ms`);
        console.log('Headers:', Object.fromEntries(response.headers));
        const data = await response.json();
        console.log('Response data:', data);
        console.groupEnd();
        return data;
    } catch (error) {
        console.error('API Call failed:', error);
        console.groupEnd();
        throw error;
    }
}

Debugging de Estado de Aplicación

State Management Debugging

// Redux-like state debugging
function createDebuggableStore(reducer, initialState) {
    let state = initialState;
    return {
        getState: () => state,
        dispatch: (action) => {
            console.group('Dispatching:', action.type);
            console.log('Previous state:', state);
            state = reducer(state, action);
            console.log('Next state:', state);
            console.groupEnd();
            return action;
        }
    };
}

// React state debugging
function useDebugState(initialState, label = 'State') {
    const [state, setState] = useState(initialState);
    const debugSetState = useCallback((newState) => {
        console.group(`State update: ${label}`);
        console.log('Previous:', state);
        console.log('Next:', newState);
        console.groupEnd();
        setState(newState);
    }, [state, label]);
    return [state, debugSetState];
}

Debugging de Bases de Datos

Query Debugging

// SQL query debugging with timing
async function debugQuery(query, params = []) {
    console.log('Executing query:', query);
    console.log('With parameters:', params);
    const startTime = Date.now();
    try {
        const result = await database.query(query, params);
        const duration = Date.now() - startTime;
        console.log(`Query completed in ${duration}ms`);
        console.log('Result:', result.rows);
        return result;
    } catch (error) {
        console.error('Query failed:', error);
        throw error;
    }
}

// MongoDB query debugging
function debugMongoQuery(collection, query, options = {}) {
    console.log('MongoDB Query:');
    console.log('Collection:', collection.collectionName);
    console.log('Query:', JSON.stringify(query, null, 2));
    console.log('Options:', options);
    return collection.find(query, options)
        .explain('executionStats')
        .then(explanation => {
            console.log('Query explanation:', explanation);
            return collection.find(query, options).toArray();
        });
}

Debugging de Concurrente y Paralelo

Race Condition Detection

// Debug async race conditions
class RaceConditionDetector {
    constructor() {
        this.operations = new Map();
    }
    startOperation(id) {
        this.operations.set(id, {
            start: Date.now(),
            stack: new Error().stack
        });
    }
    endOperation(id) {
        const op = this.operations.get(id);
        if (op) {
            const duration = Date.now() - op.start;
            console.log(`Operation ${id} took ${duration}ms`);
            this.operations.delete(id);
        }
    }
    logPendingOperations() {
        console.log('Pending operations:', this.operations.size);
        this.operations.forEach((op, id) => {
            console.log(`Operation ${id} running for ${Date.now() - op.start}ms`);
            console.log('Stack:', op.stack);
        });
    }
}

Deadlock Detection

// Resource locking debugger
class LockDebugger {
    constructor() {
        this.locks = new Map();
        this.waiting = new Map();
    }
    acquireLock(resource, owner) {
        if (this.locks.has(resource)) {
            console.warn(`Lock contention on ${resource}`);
            console.log(`Current owner: ${this.locks.get(resource)}`);
            console.log(`Waiting owner: ${owner}`);
            if (!this.waiting.has(resource)) {
                this.waiting.set(resource, []);
            }
            this.waiting.get(resource).push(owner);
        }
        this.locks.set(resource, owner);
        console.log(`Lock acquired: ${resource} by ${owner}`);
    }
    releaseLock(resource, owner) {
        if (this.locks.get(resource) === owner) {
            this.locks.delete(resource);
            console.log(`Lock released: ${resource} by ${owner}`);
        }
    }
}

Debugging de Seguridad

Security Vulnerability Debugging

// XSS detection
function detectXSS(input) {
    const suspiciousPatterns = [
        /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
        /javascript:/gi,
        /on\w+\s*=/gi,
        /expression\s*\(/gi
    ];
    suspiciousPatterns.forEach((pattern, index) => {
        if (pattern.test(input)) {
            console.warn(`Potential XSS detected in input:`, input);
            debugger;
        }
    });
}

// SQL injection detection
function detectSQLInjection(input) {
    const sqlPatterns = [
        /\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION)\b/gi,
        /'.*--/,
        /;\s*DROP/,
        /OR\s+1=1/
    ];
    sqlPatterns.forEach(pattern => {
        if (pattern.test(input)) {
            console.warn(`Potential SQL injection:`, input);
        }
    });
}

Debugging de Gráficos y UI

Visual Debugging

// Visual layout debugging
function debugLayout(element) {
    const rect = element.getBoundingClientRect();
    const styles = window.getComputedStyle(element);
    console.group('Layout Debugging:', element.tagName);
    console.log('Position:', rect);
    console.log('Display:', styles.display);
    console.log('Visibility:', styles.visibility);
    console.log('Opacity:', styles.opacity);
    console.log('Z-index:', styles.zIndex);
    console.log('Transform:', styles.transform);
    console.groupEnd();
    // Visual overlay
    const overlay = document.createElement('div');
    overlay.style.cssText = `
        position: absolute;
        border: 2px solid red;
        pointer-events: none;
        top: ${rect.top}px;
        left: ${rect.left}px;
        width: ${rect.width}px;
        height: ${rect.height}px;
        z-index: 10000;
    `;
    document.body.appendChild(overlay);
    setTimeout(() => overlay.remove(), 3000);
}

Animation Debugging

// CSS animation debugging
function debugAnimations() {
    const elements = document.querySelectorAll('*');
    elements.forEach(el => {
        const style = window.getComputedStyle(el);
        const hasAnimation = style.animationName !== 'none';
        const hasTransition = style.transition !== 'none';
        if (hasAnimation || hasTransition) {
            console.log('Animated element:', el);
            console.log('Animation:', style.animationName);
            console.log('Transition:', style.transition);
        }
    });
}

Debugging de Build y Deployment

Build Process Debugging

// Webpack build debugging
const webpack = require('webpack');

const compiler = webpack({
    // ... webpack config
    stats: 'verbose', // Detailed build information
    infrastructureLogging: {
        level: 'verbose'
    }
});

compiler.run((err, stats) => {
    if (err) {
        console.error('Build failed:', err);
        return;
    }
    if (stats.hasErrors()) {
        console.error('Build errors:');
        stats.compilation.errors.forEach(error => {
            console.error(error.message);
        });
    }
    if (stats.hasWarnings()) {
        console.warn('Build warnings:');
        stats.compilation.warnings.forEach(warning => {
            console.warn(warning.message);
        });
    }
});

Environment Debugging

// Environment variable debugging
function debugEnvironment() {
    console.group('Environment Debugging');
    console.log('NODE_ENV:', process.env.NODE_ENV);
    console.log('Platform:', process.platform);
    console.log('Architecture:', process.arch);
    console.log('Node version:', process.version);
    console.log('Current directory:', process.cwd());
    console.groupEnd();
}

// Configuration validation
function validateConfig(config) {
    const required = ['API_URL', 'DATABASE_URL', 'SECRET_KEY'];
    const missing = required.filter(key => !config[key]);
    if (missing.length > 0) {
        console.error('Missing required configuration:', missing);
        debugger;
        throw new Error(`Missing configuration: ${missing.join(', ')}`);
    }
}

Debugging de Logs Distribuidos

Distributed Tracing

// Correlation ID for distributed debugging
class RequestTracer {
    constructor() {
        this.correlationId = null;
    }
    startTrace(correlationId = null) {
        this.correlationId = correlationId || this.generateId();
        console.log(`[${this.correlationId}] Trace started`);
        return this.correlationId;
    }
    log(message, data = null) {
        const timestamp = new Date().toISOString();
        console.log(`[${this.correlationId}] ${timestamp}: ${message}`);
        if (data) {
            console.log(`[${this.correlationId}] Data:`, data);
        }
    }
    generateId() {
        return Math.random().toString(36).substr(2, 9);
    }
}

// Usage in microservices
const tracer = new RequestTracer();
const correlationId = tracer.startTrace();
tracer.log('Processing request', { userId: 123 });

Debugging de Caché

Cache Behavior Debugging

class CacheDebugger {
    constructor() {
        this.hits = 0;
        this.misses = 0;
        this.operations = [];
    }

    logOperation(key, operation, value = null) {
        const entry = {
            timestamp: Date.now(),
            key,
            operation,
            value,
            stack: new Error().stack
        };
        this.operations.push(entry);
        if (operation === 'HIT') this.hits++;
        if (operation === 'MISS') this.misses++;
        console.log(`Cache ${operation}: ${key}`, value);
    }

    getStats() {
        const hitRate = this.hits / (this.hits + this.misses);
        return {
            hits: this.hits,
            misses: this.misses,
            hitRate: hitRate.toFixed(2),
            totalOperations: this.operations.length
        };
    }

    inspectKey(key) {
        return this.operations.filter(op => op.key === key);
    }
}

Debugging de WebSockets

WebSocket Connection Debugging

class WebSocketDebugger {
    constructor(url) {
        this.messages = [];
        this.connectionStates = [];
        this.socket = new WebSocket(url);
        this.setupDebugging();
    }

    setupDebugging() {
        const events = ['open', 'message', 'error', 'close'];
        events.forEach(event => {
            this.socket.addEventListener(event, (e) => {
                this.logEvent(event, e);
                if (event === 'error' || event === 'close') {
                    debugger; // Pause on connection issues
                }
            });
        });
    }

    logEvent(type, event) {
        const entry = {
            timestamp: Date.now(),
            type,
            data: event.data,
            readyState: this.socket.readyState,
            code: event.code,
            reason: event.reason
        };
        this.connectionStates.push(entry);
        console.log(`WebSocket ${type}:`, entry);
    }

    sendWithDebug(data) {
        console.group('WebSocket Send');
        console.log('Data:', data);
        console.log('ReadyState:', this.socket.readyState);
        console.groupEnd();
        this.socket.send(JSON.stringify(data));
    }

    getConnectionHealth() {
        const recent = this.connectionStates.slice(-10);
        const errors = recent.filter(state => state.type === 'error');
        return {
            totalMessages: this.messages.length,
            recentErrors: errors.length,
            currentState: this.socket.readyState,
            latency: this.calculateLatency()
        };
    }
}

Debugging de Workers

Web Worker Debugging

// Main thread worker debugger
class WorkerDebugger {
    constructor(workerScript) {
        this.worker = new Worker(workerScript);
        this.messages = [];
        this.setupDebugging();
    }

    setupDebugging() {
        this.worker.addEventListener('message', (e) => {
            this.logMessage('FROM_WORKER', e.data);
            if (e.data.type === 'ERROR') {
                console.error('Worker error:', e.data.error);
                debugger;
            }
        });

        this.worker.addEventListener('error', (e) => {
            console.error('Worker runtime error:', e);
            debugger;
        });
    }

    postMessageWithDebug(data) {
        const messageId = this.generateMessageId();
        const debugData = {
            ...data,
            _debugId: messageId,
            _timestamp: Date.now()
        };
        this.logMessage('TO_WORKER', debugData);
        this.worker.postMessage(debugData);
        return messageId;
    }

    logMessage(direction, data) {
        this.messages.push({
            direction,
            data,
            timestamp: Date.now(),
            stack: direction === 'TO_WORKER' ? new Error().stack : null
        });
        console.log(`Worker ${direction}:`, data);
    }
}

// Worker internal debugging
self.addEventListener('message', function(e) {
    const debugId = e.data._debugId;
    try {
        // Process message
        const result = processData(e.data);
        self.postMessage({
            type: 'SUCCESS',
            result,
            _debugId: debugId
        });
    } catch (error) {
        self.postMessage({
            type: 'ERROR',
            error: error.message,
            stack: error.stack,
            _debugId: debugId
        });
    }
});

Debugging de Autenticación

Auth Flow Debugging

class AuthDebugger {
    constructor() {
        this.authEvents = [];
        this.tokenStates = [];
    }

    debugAuthFlow() {
        // Monitor localStorage/sessionStorage for tokens
        const originalSetItem = localStorage.setItem;
        localStorage.setItem = (key, value) => {
            if (key.includes('token') || key.includes('auth')) {
                this.logAuthEvent('TOKEN_STORED', { key, value });
            }
            originalSetItem.call(localStorage, key, value);
        };

        // Monitor fetch requests for auth headers
        const originalFetch = window.fetch;
        window.fetch = (...args) => {
            const request = args[1] || {};
            if (request.headers && request.headers.Authorization) {
                this.logAuthEvent('AUTH_HEADER_SENT', {
                    url: args[0],
                    header: request.headers.Authorization
                });
            }
            return originalFetch(...args);
        };
    }

    logAuthEvent(type, data) {
        const event = {
            type,
            timestamp: Date.now(),
            data,
            stack: new Error().stack
        };
        this.authEvents.push(event);
        console.log(`Auth Event [${type}]:`, data);
        if (type === 'TOKEN_EXPIRED' || type === 'AUTH_FAILED') {
            debugger; // Pause on auth failures
        }
    }

    validateToken(token) {
        try {
            const payload = JSON.parse(atob(token.split('.')[1]));
            const expiry = payload.exp * 1000;
            const now = Date.now();
            this.logAuthEvent('TOKEN_VALIDATED', {
                expiry: new Date(expiry),
                isExpired: now > expiry,
                timeUntilExpiry: expiry - now
            });
            return now < expiry;
        } catch (error) {
            this.logAuthEvent('TOKEN_INVALID', { error: error.message });
            return false;
        }
    }
}

Debugging de Rendimiento en Tiempo Real

Real-time Performance Monitoring

class PerformanceDebugger {
    constructor() {
        this.metrics = new Map();
        this.thresholds = {
            slowOperation: 100, // ms
            memoryLeak: 1000, // KB
            highCPU: 80 // %
        };
    }

    startMonitoring() {
        this.monitorMemory();
        this.monitorCPU();
        this.monitorEventLoop();
    }

    monitorMemory() {
        setInterval(() => {
            const memory = process.memoryUsage();
            const heapUsed = Math.round(memory.heapUsed / 1024);
            this.recordMetric('memory', heapUsed);
            if (heapUsed > this.thresholds.memoryLeak) {
                console.warn(`High memory usage: ${heapUsed}KB`);
                this.takeHeapSnapshot();
            }
        }, 5000);
    }

    monitorEventLoop() {
        let lastTime = Date.now();
        setInterval(() => {
            const now = Date.now();
            const delay = now - lastTime - 1000; // Expected 1s interval
            this.recordMetric('eventLoopDelay', delay);
            if (delay > 100) {
                console.warn(`Event loop delayed: ${delay}ms`);
                this.analyzeBlockingOperations();
            }
            lastTime = now;
        }, 1000);
    }

    measureRenderTime(componentName, renderFn) {
        const start = performance.now();
        const result = renderFn();
        const duration = performance.now() - start;
        this.recordMetric(`render_${componentName}`, duration);
        if (duration > this.thresholds.slowOperation) {
            console.warn(`Slow render (${componentName}): ${duration}ms`);
        }
        return result;
    }

    analyzeBlockingOperations() {
        const longTasks = performance.getEntriesByType('long-task');
        longTasks.forEach(task => {
            console.warn('Long task detected:', {
                duration: task.duration,
                startTime: task.startTime,
                name: task.name
            });
        });
    }
}

Debugging de Internacionalización

i18n Debugging

class I18nDebugger {
    constructor() {
        this.missingTranslations = new Set();
        this.usedTranslations = new Map();
    }

    wrapI18nFunction(i18nFunction) {
        return (key, params = {}) => {
            const result = i18nFunction(key, params);
            // Track usage
            this.usedTranslations.set(key, {
                lastUsed: Date.now(),
                params,
                result
            });
            // Check for missing translations
            if (result === key || result.includes('missing')) {
                this.missingTranslations.add(key);
                console.warn(`Missing translation: ${key}`);
                debugger; // Pause on missing translations
            }
            return result;
        };
    }

    analyzeCoverage() {
        const allKeys = this.getAllTranslationKeys();
        const usedKeys = Array.from(this.usedTranslations.keys());
        const unusedKeys = allKeys.filter(key => !usedKeys.includes(key));
        console.group('i18n Coverage Analysis');
        console.log('Total keys:', allKeys.length);
        console.log('Used keys:', usedKeys.length);
        console.log('Unused keys:', unusedKeys.length);
        console.log('Missing translations:', this.missingTranslations.size);
        console.groupEnd();
        return { usedKeys, unusedKeys, missing: Array.from(this.missingTranslations) };
    }

    detectHardcodedStrings() {
        // Search for non-wrapped strings in components
        const hardcodedPatterns = [
            /[^=]=['"][A-Za-z][^=]*?['"]/g,
            />[A-Za-z][^<]*?</g
        ];
        // This would typically run against source code
        console.log('Hardcoded string detection running...');
    }
}

Debugging de Accesibilidad

A11y Debugging

class AccessibilityDebugger {
    constructor() {
        this.violations = [];
    }

    scanPage() {
        this.checkColorContrast();
        this.checkKeyboardNavigation();
        this.checkScreenReaderCompatibility();
        this.checkFormLabels();
    }

    checkColorContrast() {
        const elements = document.querySelectorAll('*');
        elements.forEach(el => {
            const style = window.getComputedStyle(el);
            const bgColor = style.backgroundColor;
            const color = style.color;
            const contrast = this.calculateContrast(bgColor, color);
            if (contrast < 4.5) {
                this.recordViolation('LOW_CONTRAST', {
                    element: el,
                    contrast: contrast.toFixed(2),
                    required: 4.5
                });
            }
        });
    }

    checkKeyboardNavigation() {
        const focusable = document.querySelectorAll(
            'button, [href], input, select, textarea, [tabindex]'
        );
        focusable.forEach((el, index) => {
            const tabIndex = el.getAttribute('tabindex');
            const computedStyle = window.getComputedStyle(el);
            if (computedStyle.visibility === 'hidden' || 
                computedStyle.display === 'none') {
                this.recordViolation('HIDDEN_FOCUSABLE', { element: el });
            }
            if (tabIndex && parseInt(tabIndex) < 0) {
                this.recordViolation('NEGATIVE_TABINDEX', { element: el, tabIndex });
            }
        });
    }

    checkFormLabels() {
        const inputs = document.querySelectorAll('input, select, textarea');
        inputs.forEach(input => {
            const label = document.querySelector(`label[for="${input.id}"]`);
            const ariaLabel = input.getAttribute('aria-label');
            if (!label && !ariaLabel && input.type !== 'hidden') {
                this.recordViolation('MISSING_LABEL', { element: input });
            }
        });
    }

    recordViolation(type, data) {
        const violation = {
            type,
            timestamp: Date.now(),
            ...data,
            stack: new Error().stack
        };
        this.violations.push(violation);
        console.warn(`A11y Violation [${type}]:`, data);
        // Highlight problematic elements
        if (data.element) {
            this.highlightElement(data.element, type);
        }
    }

    highlightElement(element, violationType) {
        const borderColor = violationType === 'LOW_CONTRAST' ? 'orange' : 'red';
        element.style.outline = `2px solid ${borderColor}`;
        element.style.outlineOffset = '2px';
    }
}

Debugging de Offline y Sync

Offline Capability Debugging

class OfflineDebugger {
    constructor() {
        this.syncOperations = [];
        this.networkState = 'online';
        this.setupNetworkMonitoring();
    }

    setupNetworkMonitoring() {
        window.addEventListener('online', () => {
            this.networkState = 'online';
            this.logSyncEvent('NETWORK_ONLINE');
            this.processPendingOperations();
        });

        window.addEventListener('offline', () => {
            this.networkState = 'offline';
            this.logSyncEvent('NETWORK_OFFLINE');
        });

        // Simulate network conditions for testing
        this.simulateNetworkConditions();
    }

    logSyncOperation(operation, data) {
        const syncOp = {
            id: this.generateId(),
            operation,
            data,
            timestamp: Date.now(),
            networkState: this.networkState,
            status: this.networkState === 'online' ? 'PENDING' : 'QUEUED'
        };

        this.syncOperations.push(syncOp);
        console.log(`Sync Operation [${operation}]:`, syncOp);

        if (this.networkState === 'offline') {
            this.queueForSync(syncOp);
        }

        return syncOp.id;
    }

    queueForSync(operation) {
        // Store in IndexedDB for later sync
        const dbRequest = indexedDB.open('SyncQueue', 1);
        dbRequest.onsuccess = (event) => {
            const db = event.target.result;
            const transaction = db.transaction(['operations'], 'readwrite');
            const store = transaction.objectStore('operations');
            store.add(operation);
        };

        console.log('Operation queued for offline sync:', operation);
    }

    async processPendingOperations() {
        const pending = this.syncOperations.filter(op => op.status === 'QUEUED');
        console.group('Processing pending operations');
        for (const operation of pending) {
            try {
                await this.executeSyncOperation(operation);
                operation.status = 'COMPLETED';
                console.log(`Operation ${operation.id} completed`);
            } catch (error) {
                operation.status = 'FAILED';
                operation.error = error.message;
                console.error(`Operation ${operation.id} failed:`, error);
            }
        }
        console.groupEnd();
    }

    simulateNetworkConditions() {
        // For testing offline scenarios
        if (process.env.NODE_ENV === 'development') {
            window.debugSimulateOffline = () => {
                this.networkState = 'offline';
                window.dispatchEvent(new Event('offline'));
            };
            window.debugSimulateOnline = () => {
                this.networkState = 'online';
                window.dispatchEvent(new Event('online'));
            };
        }
    }
}

Debugging de Machine Learning

Model Training Debugging

class MLTrainingDebugger:
    def __init__(self):
        self.training_history = []
        self.gradient_norms = []
        self.loss_breakdown = []
    def log_training_step(self, epoch, loss, accuracy, gradients):
        step_data = {
            'epoch': epoch,
            'loss': float(loss),
            'accuracy': float(accuracy),
            'gradient_norm': float(torch.norm(gradients)),
            'timestamp': time.time()
        }
        self.training_history.append(step_data)
        # Check for vanishing/exploding gradients
        if step_data['gradient_norm'] < 1e-7:
            print(f"⚠️ Vanishing gradients detected at epoch {epoch}")
            debugger()
        elif step_data['gradient_norm'] > 1e5:
            print(f"⚠️ Exploding gradients detected at epoch {epoch}")
            debugger()
    def analyze_loss_components(self, model, dataloader, criterion):
        model.eval()
        total_loss = 0
        component_losses = {}
        with torch.no_grad():
            for batch in dataloader:
                outputs = model(batch)
                loss_components = criterion(outputs, batch, reduce=False)
                for key, component_loss in loss_components.items():
                    if key not in component_losses:
                        component_losses[key] = []
                    component_losses[key].append(component_loss.mean().item())
        print("📊 Loss Component Analysis:")
        for component, losses in component_losses.items():
            avg_loss = sum(losses) / len(losses)
            print(f"  {component}: {avg_loss:.6f}")

Debugging de Realidad Virtual/Aumentada

VR/AR Performance Debugging

class VRARDebugger {
    constructor(renderer, camera) {
        this.renderer = renderer;
        this.camera = camera;
        this.performanceMetrics = {
            frameTimes: [],
            memoryUsage: [],
            drawCalls: []
        };
        this.setupVRDebugging();
    }

    setupVRDebugging() {
        // Monitor frame rate and performance
        this.monitorFrameRate();
        this.monitorMemoryUsage();
        this.trackRenderPerformance();
    }

    monitorFrameRate() {
        let lastTime = performance.now();
        let frameCount = 0;
        const checkFrameRate = () => {
            frameCount++;
            const currentTime = performance.now();
            if (currentTime - lastTime >= 1000) {
                const fps = frameCount;
                frameCount = 0;
                lastTime = currentTime;
                this.performanceMetrics.frameTimes.push(fps);
                if (fps < 60) {
                    console.warn(`Low frame rate: ${fps} FPS`);
                    this.analyzePerformanceBottleneck();
                }
            }
            requestAnimationFrame(checkFrameRate);
        };
        checkFrameRate();
    }

    trackRenderPerformance() {
        const originalRender = this.renderer.render;
        this.renderer.render = (scene, camera) => {
            const startTime = performance.now();
            originalRender.call(this.renderer, scene, camera);
            const renderTime = performance.now() - startTime;
            this.performanceMetrics.drawCalls.push({
                time: renderTime,
                triangles: this.renderer.info.render.triangles,
                calls: this.renderer.info.render.calls,
                timestamp: Date.now()
            });
            if (renderTime > 16) { // More than 16ms per frame
                console.warn(`Slow render: ${renderTime.toFixed(2)}ms`);
            }
        };
    }

    debugPoseTracking() {
        // Debug VR controller/hand tracking
        const originalUpdate = this.controllers.update;
        this.controllers.update = function() {
            originalUpdate.call(this);
            this.controllers.forEach(controller => {
                console.log('Controller pose:', {
                    position: controller.position,
                    rotation: controller.rotation,
                    connected: controller.connected
                });
            });
        };
    }
}

Debugging de Blockchain

Smart Contract Debugging

class BlockchainDebugger {
    constructor(web3, contractAddress) {
        this.web3 = web3;
        this.contractAddress = contractAddress;
        this.transactionLog = [];
        this.gasUsage = [];
    }

    async debugTransaction(txHash) {
        console.group(`🔍 Debugging Transaction: ${txHash}`);
        try {
            const receipt = await this.web3.eth.getTransactionReceipt(txHash);
            const tx = await this.web3.eth.getTransaction(txHash);
            console.log('Transaction Details:', {
                from: tx.from,
                to: tx.to,
                value: tx.value,
                gasUsed: receipt.gasUsed,
                status: receipt.status ? 'Success' : 'Failed'
            });
            if (receipt.status === false) {
                await this.analyzeFailure(receipt, tx);
            }
            this.analyzeGasUsage(receipt);
        } catch (error) {
            console.error('Transaction debug failed:', error);
        }
        console.groupEnd();
    }

    async analyzeFailure(receipt, tx) {
        // Try to decode revert reason
        try {
            const code = await this.web3.eth.getCode(this.contractAddress);
            if (code === '0x') {
                console.error('❌ Contract does not exist at address');
                return;
            }
            // Simulate the transaction to get revert reason
            const result = await this.web3.eth.call({
                from: tx.from,
                to: tx.to,
                value: tx.value,
                data: tx.input,
                gas: tx.gas
            });
            console.log('Transaction simulation result:', result);
        } catch (simError) {
            console.error('Revert reason:', simError.message);
        }
    }

    monitorEvents(contract) {
        const allEvents = contract.events.allEvents({
            fromBlock: 'latest'
        });
        allEvents.on('data', (event) => {
            console.group(`📝 Contract Event: ${event.event}`);
            console.log('Return values:', event.returnValues);
            console.log('Block:', event.blockNumber);
            console.log('Transaction:', event.transactionHash);
            console.groupEnd();
            this.transactionLog.push({
                type: 'EVENT',
                event: event.event,
                values: event.returnValues,
                block: event.blockNumber,
                txHash: event.transactionHash,
                timestamp: Date.now()
            });
        });
    }
}

Debugging de IoT y Dispositivos

IoT Device Communication Debugging

class IoTDebugger:
    def __init__(self):
        self.message_log = []
        self.connection_states = []
        self.sensor_readings = []
    def debug_mqtt_communication(self, client):
        """Debug MQTT message flow"""
        original_publish = client.publish
        original_subscribe = client.subscribe
        def debug_publish(topic, payload, **kwargs):
            message_id = f"msg_{len(self.message_log)}"
            log_entry = {
                'id': message_id,
                'direction': 'OUTGOING',
                'topic': topic,
                'payload': payload,
                'timestamp': time.time(),
                'qos': kwargs.get('qos', 0)
            }
            self.message_log.append(log_entry)
            print(f"📤 MQTT Publish: {topic} -> {payload}")
            return original_publish(topic, payload, **kwargs)
        def debug_subscribe(topic, **kwargs):
            print(f"📥 MQTT Subscribe: {topic}")
            return original_subscribe(topic, **kwargs)
        client.publish = debug_publish
        client.subscribe = debug_subscribe
        # Monitor connection state
        client.on_connect = lambda client, userdata, flags, rc: (
            self.connection_states.append({'event': 'CONNECT', 'code': rc}),
            print(f"🔗 MQTT Connected: RC={rc}")
        )
        client.on_disconnect = lambda client, userdata, rc: (
            self.connection_states.append({'event': 'DISCONNECT', 'code': rc}),
            print(f"🔌 MQTT Disconnected: RC={rc}")
        )
    def monitor_sensor_data(self, sensor_callback):
        """Wrap sensor reading callbacks with debugging"""
        def debug_sensor_reading(*args, **kwargs):
            reading = sensor_callback(*args, **kwargs)
            sensor_entry = {
                'timestamp': time.time(),
                'reading': reading,
                'sensor_type': sensor_callback.__name__
            }
            self.sensor_readings.append(sensor_entry)
            # Check for abnormal readings
            if self.is_abnormal_reading(reading, sensor_callback.__name__):
                print(f"⚠️ Abnormal sensor reading: {reading}")
                # Trigger debug breakpoint
                import pdb; pdb.set_trace()
            return reading
        return debug_sensor_reading
    def is_abnormal_reading(self, reading, sensor_type):
        """Detect abnormal sensor readings"""
        thresholds = {
            'temperature': (-40, 85),
            'humidity': (0, 100),
            'pressure': (300, 1100)
        }
        if sensor_type in thresholds:
            min_val, max_val = thresholds[sensor_type]
            return reading < min_val or reading > max_val
        return False

Debugging de Sistemas Embebidos

Embedded System Debugging

#include <debug_utils.h>

typedef struct {
    uint32_t timestamp;
    char function_name[32];
    uint32_t line_number;
    char message[128];
    DebugLevel level;
} DebugEntry;

class EmbeddedDebugger {
private:
    DebugEntry log_buffer[DEBUG_BUFFER_SIZE];
    uint32_t log_index;
    bool real_time_debug;
public:
    void init_debugger() {
        log_index = 0;
        real_time_debug = true;
        // Setup debug UART
        uart_init(DEBUG_UART, 115200);
        // Enable cycle counter for timing
        enable_cycle_counter();
    }
    void debug_log(DebugLevel level, const char* function, uint32_t line, const char* format, ...) {
        if (log_index >= DEBUG_BUFFER_SIZE) {
            log_index = 0; // Circular buffer
        }
        DebugEntry* entry = &log_buffer[log_index++];
        entry->timestamp = get_system_time();
        strncpy(entry->function_name, function, 31);
        entry->line_number = line;
        entry->level = level;
        va_list args;
        va_start(args, format);
        vsnprintf(entry->message, 127, format, args);
        va_end(args);
        // Real-time output if enabled
        if (real_time_debug) {
            uart_printf(DEBUG_UART, "[%lu] %s:%lu - %s\n", 
                       entry->timestamp, function, line, entry->message);
        }
        // Break on critical errors
        if (level == DEBUG_CRITICAL) {
            trigger_breakpoint();
        }
    }
    void dump_memory_map() {
        printf("Memory Map Dump:\n");
        printf("Heap start: 0x%08lX\n", get_heap_start());
        printf("Heap end: 0x%08lX\n", get_heap_end());
        printf("Stack pointer: 0x%08lX\n", get_stack_pointer());
        printf("Free memory: %lu bytes\n", get_free_memory());
    }
    void profile_function(const char* function_name, void (*func)(void)) {
        uint32_t start_cycles = get_cycle_count();
        uint32_t start_time = get_system_time();
        func(); // Execute the function
        uint32_t end_cycles = get_cycle_count();
        uint32_t end_time = get_system_time();
        printf("Function %s profiling:\n", function_name);
        printf("  CPU cycles: %lu\n", end_cycles - start_cycles);
        printf("  Execution time: %lu us\n", end_time - start_time);
    }
};

// Macros for easy debugging
#define DEBUG_INFO(...) debug_log(DEBUG_INFO, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DEBUG_WARN(...) debug_log(DEBUG_WARN, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DEBUG_ERROR(...) debug_log(DEBUG_ERROR, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DEBUG_CRITICAL(...) debug_log(DEBUG_CRITICAL, __FUNCTION__, __LINE__, __VA_ARGS__)

Debugging de Sistemas Distribuidos

Distributed System Tracing

public class DistributedTracingDebugger {
    private final ThreadLocal<String> currentTraceId = new ThreadLocal<>();
    private final Map<String, TraceContext> traces = new ConcurrentHashMap<>();
    private final SpanCollector spanCollector;
    public void startTrace(String traceId, String operation) {
        currentTraceId.set(traceId);
        TraceContext context = new TraceContext(traceId, operation);
        traces.put(traceId, context);
        logTraceEvent("TRACE_START", traceId, operation, null);
    }
    public void logSpan(String spanName, Map<String, Object> tags) {
        String traceId = currentTraceId.get();
        if (traceId != null) {
            Span span = new Span(spanName, traceId, System.currentTimeMillis(), tags);
            spanCollector.collect(span);
            logTraceEvent("SPAN_CREATED", traceId, spanName, tags);
        }
    }
    public void logRemoteCall(String service, String endpoint, Map<String, String> headers) {
        String traceId = currentTraceId.get();
        if (traceId != null) {
            // Inject trace context into headers
            headers.put("X-Trace-Id", traceId);
            headers.put("X-Span-Id", generateSpanId());
            logTraceEvent("REMOTE_CALL", traceId, 
                         String.format("%s:%s", service, endpoint), headers);
        }
    }
    public void analyzeTrace(String traceId) {
        TraceContext context = traces.get(traceId);
        if (context != null) {
            System.out.println("=== Trace Analysis ===");
            System.out.println("Trace ID: " + traceId);
            System.out.println("Operation: " + context.getOperation());
            System.out.println("Duration: " + context.getDuration() + "ms");
            System.out.println("Spans: " + context.getSpans().size());
            // Identify bottlenecks
            context.getSpans().stream()
                .filter(span -> span.getDuration() > 1000) // Spans longer than 1s
                .forEach(span -> 
                    System.out.println("Slow span: " + span.getName() + 
                                     " (" + span.getDuration() + "ms)"));
        }
    }
    public void detectDistributedDeadlocks() {
        // Analyze trace dependencies for potential deadlocks
        traces.values().stream()
            .filter(context -> context.getDuration() > 30000) // Traces longer than 30s
            .forEach(context -> {
                System.out.println("Potential deadlock detected in trace: " + 
                                 context.getTraceId());
                analyzeTrace(context.getTraceId());
            });
    }
}

Debugging de Sistemas en Tiempo Real

Real-time System Debugging

class RealTimeDebugger {
private:
    std::vector<RTSTask> tasks;
    std::chrono::steady_clock::time_point start_time;
    bool deadline_missed;
public:
    void monitor_task_deadlines() {
        for (auto& task : tasks) {
            auto now = std::chrono::steady_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
                now - task.start_time);
            if (elapsed.count() > task.deadline_ms && !task.completed) {
                deadline_missed = true;
                log_deadline_miss(task.id, elapsed.count());
                // Trigger emergency response
                handle_deadline_miss(task);
            }
        }
    }
    void log_deadline_miss(int task_id, long actual_time) {
        std::cout << "🚨 Deadline missed - Task: " << task_id 
                  << ", Actual: " << actual_time << "ms" << std::endl;
        // Dump system state for analysis
        dump_system_state();
        // If in debug mode, break execution
        #ifdef DEBUG_MODE
        raise(SIGTRAP); // Trigger debugger breakpoint
        #endif
    }
    void profile_interrupt_latency() {
        auto interrupt_start = std::chrono::high_resolution_clock::now();
        // Simulate interrupt handling
        handle_interrupt();
        auto interrupt_end = std::chrono::high_resolution_clock::now();
        auto latency = std::chrono::duration_cast<std::chrono::microseconds>(
            interrupt_end - interrupt_start);
        if (latency.count() > MAX_INTERRUPT_LATENCY) {
            std::cout << "⚠️ High interrupt latency: " << latency.count() << "μs" << std::endl;
        }
    }
    void analyze_scheduling() {
        // Monitor context switches
        auto context_switches = get_context_switch_count();
        static auto last_check = std::chrono::steady_clock::now();
        auto now = std::chrono::steady_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - last_check);
        if (duration.count() >= 1) {
            auto switches_per_second = context_switches / duration.count();
            if (switches_per_second > MAX_CONTEXT_SWITCHES) {
                std::cout << "⚠️ High context switch rate: " 
                          << switches_per_second << "/s" << std::endl;
            }
            last_check = now;
        }
    }
};

Debugging de Sistemas de Archivos

File System Operation Debugging

class FileSystemDebugger:
    def __init__(self):
        self.file_operations = []
        self.lock_contention = []
        self.open_handles = {}
    def monitor_file_operations(self):
        """Monitor all file system operations"""
        original_open = builtins.open
        original_remove = os.remove
        original_rename = os.rename
        def debug_open(filename, mode='r', *args, **kwargs):
            start_time = time.time()
            file_handle = original_open(filename, mode, *args, **kwargs)
            end_time = time.time()
            operation = {
                'type': 'OPEN',
                'filename': filename,
                'mode': mode,
                'duration': end_time - start_time,
                'timestamp': start_time,
                'thread': threading.current_thread().name
            }
            self.file_operations.append(operation)
            # Track open file handles
            self.open_handles[file_handle] = {
                'filename': filename,
                'open_time': start_time,
                'mode': mode
            }
            print(f"📁 File opened: {filename} ({mode})")
            return file_handle
        def debug_remove(filename):
            operation = {
                'type': 'REMOVE',
                'filename': filename,
                'timestamp': time.time(),
                'thread': threading.current_thread().name
            }
            self.file_operations.append(operation)
            print(f"🗑️ File removed: {filename}")
            return original_remove(filename)
        builtins.open = debug_open
        os.remove = debug_remove
        os.rename = debug_rename
    def detect_file_leaks(self):
        """Detect unreleased file handles"""
        current_time = time.time()
        leaked_handles = []
        for handle, info in self.open_handles.items():
            if current_time - info['open_time'] > 300:  # 5 minutes
                leaked_handles.append((handle, info))
        if leaked_handles:
            print(f"⚠️ Potential file handle leaks detected: {len(leaked_handles)}")
            for handle, info in leaked_handles:
                print(f"  - {info['filename']} opened at {info['open_time']}")
    def analyze_io_patterns(self):
        """Analyze file I/O patterns for performance issues"""
        reads = [op for op in self.file_operations if op['type'] == 'READ']
        writes = [op for op in self.file_operations if op['type'] == 'WRITE']
        print("📊 I/O Pattern Analysis:")
        print(f"  Read operations: {len(reads)}")
        print(f"  Write operations: {len(writes)}")
        if reads:
            avg_read_time = sum(op['duration'] for op in reads) / len(reads)
            print(f"  Average read time: {avg_read_time:.3f}s")
        if writes:
            avg_write_time = sum(op['duration'] for op in writes) / len(writes)
            print(f"  Average write time: {avg_write_time:.3f}s")
        # Detect small, frequent writes (bad for performance)
        small_writes = [op for op in writes if op.get('size', 0) < 4096]
        if len(small_writes) > 100:
            print("⚠️ Many small writes detected - consider buffering")