¿Cómo descubrir errores de desbordamiento de memoria en el código Arduino C?

10

Varias veces tuve algunas salidas sospechosas en el Monitor Serial después de cargar el código en el Arduino: como la salida eterna de espacios en blanco o el corte repentino de cadenas o cadenas codificadas.

Debido a que no hubo ningún error de compilación o advertencia en el IDE de Arduino, pensé que el Arduino estaba dañado, pero después de algunas pruebas descubrí que el compilador del IDE de Arduino no detectaba todos los tipos de errores, especialmente al asignar variables en un bucle para estructuras de matriz. Esto parece estrellar el Arduino en un corto período de tiempo.

¿Cómo puedo descubrir errores que no aparecen en el IDE de Arduino?

    
pregunta powtac

3 respuestas

10

La biblioteca de MemoryFree puede ayudarlo a encontrar riesgos con el uso de la memoria.

Ejemplo:

#include <MemoryFree.h>

// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)

// 14-bytes string
//char str[] = "Hello, world!";


void setup() {
    Serial.begin(115200);
}


void loop() {
    //Serial.println(str);

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    delay(1000);
}

No estoy seguro de si MemoryFree cuenta para el puntero de pila. Si el puntero de la pila choca con el puntero del montón, puede experimentar fallas de segmentación.

    
respondido por el Robert
6

La causa más común de agotamiento de RAM es usar el objeto String o usar muchas matrices de caracteres constantes (cadena de estilo c).

Forutantly IDE 1.0.4 incluye una solución a malloc que ha plagado el objeto String durante mucho tiempo.

Para reducir la RAM desperdiciada por cadenas de caracteres constantes como:

Serial.print("Hello World");  // This consumes RAM!

Puedes usar la macro F () Esta macro obligará a la matriz de caracteres a permanecer en PROGMEM. Cuando se usa la matriz, solo se consume un byte de memoria.

Serial.print(F("Hello World"));  // Keeps the character-array in PROGMEM

Tenga en cuenta que las cadenas almacenadas en PROGMEM no se pueden modificar durante el tiempo de ejecución.

En lo que respecta al descubrimiento, sin un depurador ni un controlador de memoria, tiene que usar técnicas de detección pasadas de moda para encontrar dónde ocurren los problemas.

    
respondido por el baldengineer
2

Parece que estás hablando de errores de tiempo de ejecución (del tipo de pérdida / segfault de memoria) aquí.

No hay ninguna forma de descubrir tales errores (a menos que se repasen cuidadosamente el código) en el código que ya está escrito. Sin embargo, es bastante fácil evitar que esto suceda mientras escribe el código. Solo ten mucho cuidado al escribir bucles o llamadas recursivas; pregúntate a ti mismo "¿podría esto irse de las manos?". Si parece que este es el alcance para que se "salga de las manos", entonces escriba un código para protegerse de eso.

Sobre segfaults: simplemente verifique los valores de los límites de los índices de matriz y debería estar bien. Si está utilizando punteros, tenga cuidado con la aritmética de punteros.

    
respondido por el Manishearth

Lea otras preguntas en las etiquetas