Неправильное использование памяти?

Наверное, я делаю что-то не так. Я пишу скетч Arduino для ESP32. Среди прочих у меня есть такая функция:

#define HDR_MAX_LENGHT 4
#define CMD_MAX_LENGHT 5
#define ARG_MAX_LENGHT 5
#define ARG_MAX_NUMBER 8

void ProcessLine(HardwareSerial *serial, char *line)
{
  int ret;
  int argc;
  char header[HDR_MAX_LENGHT + 1];
  char cmd[CMD_MAX_LENGHT + 1];
  char argv[ARG_MAX_NUMBER][ARG_MAX_LENGHT + 1];

  return; // для отладки
}

Пример использования:

void loop() 
{
    static char inBuf[64];

    if (Serial.available())
    {
      size_t size = Serial.readBytes(inBuf, 64);
      inBuf[size] = '\0';
      ProcessLine(&Serial, inBuf);
    }  
}

В последние дни все работало нормально. После добавления другого кода я заметил, что иногда моя программа "зависает": ничего не запускается. Возможно, это попадает в ловушку исключений.

Комментируя различные разделы кода, я обнаружил, что если я удалю объявления переменных в ProcessLine(), зависаний больше не произойдет. Текущее потребление оперативной памяти незначительно: 0,5%.

Во время испытаний НИКАКИХ серийных данных получено не было! Таким образом, функция ProcessLine() никогда не вызывалась. Следовательно, только объявление переменных приводит к "зависанию".

Интересно, есть ли какие-то ошибки в приведенном выше коде. В противном случае, как я могу дополнительно отладить свой код, чтобы понять, что я сделал неправильно?

, 👍0

Обсуждение

если размер равен 64, то вы записываете \0 из массива, @Juraj

@Juraj хороший улов, спасибо. Но, как уже было сказано, я не отправляю никаких данных прямо сейчас., @Mark

Можете ли вы написать проверяемый минимальный пример, который воспроизводит проблему?, @Edgar Bonet

@EdgarBonet к сожалению, нет, потому что с минимальным примером все работает так, как ожидалось (как уже было сказано, в начале разработки проблем не было). По этой причине я спрашиваю, как отлаживать в дополнение к комментированию некоторой части кода., @Mark

Это всего лишь предположение, но как насчет оптимизации компилятора? Попробуйте отключить оптимизацию и протестировать еще раз., @JSC

Измените optimize_level в \hardware\arduino\avr\platform.txt . Допустимыми значениями являются -O0, -O1, -O2, -O3, -Os и -Ofast. По умолчанию используется -Os., @JSC

В этих заявлениях нет ничего плохого. Тот факт, что программа работает, когда вы закомментируете некоторые строки кода, не означает, что эти строки вызывают проблему. Похоже, вы, возможно, вызвали [неопределенное поведение] (https://www.nayuki.io/page/undefined-behavior-in-c-and-cplusplus-programs ) где-нибудь. Когда это происходит, поведение программы становится непредсказуемым и может зависеть от изменений в частях кода, которые совершенно не связаны с реальной проблемой. Типичным примером является повреждение памяти., @Edgar Bonet


1 ответ


Лучший ответ:

4

Как я уже сказал в комментарии, в этих заявлениях нет ничего плохого. Теперь, вот несколько стратегий отладки, которые вы можете попробовать:

  1. Вы можете перестроить свою программу с включенными всеми предупреждениями компилятора. Внимательно просмотрите сообщения компилятора и изучите любое предупреждение, которое вы видите.

  2. Вы можете продолжить свою текущую стратегию: вернуть эти объявления обратно, а затем попытаться удалить что-то еще. Вы можете обнаружить, что существует несколько фрагментов кода, которые при удалении заставляют вашу программу снова работать. Скорее всего, проблема кроется в одной из этих частей. Но тогда, возможно, проблема заключается во взаимодействии между несколькими частями, а не в одной конкретной части.

  3. Вы можете просто внимательно прочитать код и посмотреть, не заметили ли вы чего-нибудь подозрительного. Иногда это может сработать: посмотрите, как @Juraj обнаружил переполнение буфера в вашем фрагменте кода, просто прочитав его.

  4. Вы можете добавлять отладочные сообщения по всей вашей программе, чтобы проверить, какие ветви выполняются, значения переменных...

  5. Я не знаю среду разработки ESP32, но вы можете проверить , поддерживает ли компилятор добавление “дезинфицирующих средств”. Это фрагменты кода, добавленные компилятором, которые выполняют проверки вашей программы во время выполнения и сообщают о проблемах по мере их возникновения. Возможно, вы захотите включить, по крайней мере , средство очистки адресов и средство очистки неопределенного поведения.

  6. Если среда поддерживает это, вы можете попробовать запустить программу в отладчике. Успех не гарантирован: если программа повреждает свою память, она может выйти из строя в каком-то месте, не связанном с реальной проблемой. Отладчик сообщит вам, где произошел сбой, что может быть не очень полезно в данном случае.

  7. Если среда разработки ESP не поддерживает ни 5, ни 6, вы можете попытаться запустить свою программу на своем компьютере. Существует несколько совместимых с Arduino ядер, которые вы можете загрузить для запуска на ПК.

,