Yeda AI Tips · #069

English

Atrapa cada crash antes de arreglarlo

Nunca arregles un crash sin atraparlo primero. En código nativo, un crash, una fuga de memoria o un data race no desaparece cuando desaparece el síntoma: vuelve la próxima vez que alguien (o algún agente de código) toca ese camino del código, salvo que algo en el build lo vigile. Ese guardián es un test de regresión que falla, escrito antes del arreglo, y ejecutado bajo un sanitizer para siempre.

La regla: primero el test, después el arreglo

  1. Reproduce el bug como un test que falla. Dile a tu agente de código: "escribe un test de regresión que reproduzca este crash — no arregles nada todavía". Córrelo. Míralo fallar. Un test que nunca viste fallar no prueba nada.
  2. Arregla el bug. Ahora el mismo test pasa a verde, y sabes que cambió por tu arreglo — no porque la reproducción estuviera mal.
  3. Corre el test bajo un sanitizer en CI. Un build instrumentado con sanitizer convierte la corrupción silenciosa en una falla ruidosa y localizada con precisión, así la misma clase de bug no puede colarse de vuelta en una forma que tus asserts no revisan.

Este es exactamente el ciclo donde los agentes de código brillan: el test que falla es un objetivo sin ambigüedad, y "haz pasar este test sin borrarlo" es un prompt difícil de burlar.

Qué sanitizer atrapa qué bug

Clase de bugSanitizerFlag de compilaciónCosto típico
Crash / corrupción de memoria (use-after-free, buffer overflow, double-free)AddressSanitizer (ASan)-fsanitize=address~2x más lento
Fuga de memoriaLeakSanitizer (LSan)-fsanitize=leak (activado por defecto con ASan en plataformas soportadas)Casi cero hasta el chequeo de fugas al salir del proceso
Data raceThreadSanitizer (TSan)-fsanitize=thread (agrega -O1 -g para salida usable)~5x–15x más lento, ~5x–10x de memoria
Comportamiento indefinido (overflow con signo, deref de null, índice fuera de rango)UndefinedBehaviorSanitizer (UBSan)-fsanitize=undefinedBajo

En Windows, MSVC incluye ASan desde Visual Studio 2019 16.9: compila con /fsanitize=address — funciona con cualquier nivel de optimización en x86/x64.

Por qué la cobertura de sanitizer le gana a la cobertura de líneas

La cobertura de líneas te dice que una sentencia se ejecutó. No dice nada sobre si esa ejecución escribió más allá del final de un buffer, leyó memoria liberada o compitió con otro hilo — el programa sigue corriendo y el test sigue en verde. Un sanitizer revisa cada acceso a memoria y cada evento de sincronización durante esas mismas corridas, así que la suite de tests idéntica atrapa toda una clase de bugs a la que la cobertura de líneas es estructuralmente ciega. Tus tests de regresión valen tanto como el build en el que corren: corre la suite una vez normal, y otra vez bajo ASan/UBSan (y TSan para código concurrente).

Movidas de usuario avanzado

Recursos

¿Construyendo una funcionalidad con IA? Yeda AI diseña, audita y entrega sistemas LLM de producción.

Habla con nosotros · Lee el blog · Read in English