Неправильное использование памяти?
Наверное, я делаю что-то не так. Я пишу скетч 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()
никогда не вызывалась.
Следовательно, только объявление переменных приводит к "зависанию".
Интересно, есть ли какие-то ошибки в приведенном выше коде. В противном случае, как я могу дополнительно отладить свой код, чтобы понять, что я сделал неправильно?
@Mark, 👍0
Обсуждение1 ответ
Лучший ответ:
Как я уже сказал в комментарии, в этих заявлениях нет ничего плохого. Теперь, вот несколько стратегий отладки, которые вы можете попробовать:
Вы можете перестроить свою программу с включенными всеми предупреждениями компилятора. Внимательно просмотрите сообщения компилятора и изучите любое предупреждение, которое вы видите.
Вы можете продолжить свою текущую стратегию: вернуть эти объявления обратно, а затем попытаться удалить что-то еще. Вы можете обнаружить, что существует несколько фрагментов кода, которые при удалении заставляют вашу программу снова работать. Скорее всего, проблема кроется в одной из этих частей. Но тогда, возможно, проблема заключается во взаимодействии между несколькими частями, а не в одной конкретной части.
Вы можете просто внимательно прочитать код и посмотреть, не заметили ли вы чего-нибудь подозрительного. Иногда это может сработать: посмотрите, как @Juraj обнаружил переполнение буфера в вашем фрагменте кода, просто прочитав его.
Вы можете добавлять отладочные сообщения по всей вашей программе, чтобы проверить, какие ветви выполняются, значения переменных...
Я не знаю среду разработки ESP32, но вы можете проверить , поддерживает ли компилятор добавление “дезинфицирующих средств”. Это фрагменты кода, добавленные компилятором, которые выполняют проверки вашей программы во время выполнения и сообщают о проблемах по мере их возникновения. Возможно, вы захотите включить, по крайней мере , средство очистки адресов и средство очистки неопределенного поведения.
Если среда поддерживает это, вы можете попробовать запустить программу в отладчике. Успех не гарантирован: если программа повреждает свою память, она может выйти из строя в каком-то месте, не связанном с реальной проблемой. Отладчик сообщит вам, где произошел сбой, что может быть не очень полезно в данном случае.
Если среда разработки ESP не поддерживает ни 5, ни 6, вы можете попытаться запустить свою программу на своем компьютере. Существует несколько совместимых с Arduino ядер, которые вы можете загрузить для запуска на ПК.
- Как очистить кучу памяти в esp32
- ESP32 не может спать дольше 35 минут.
- Пространство, занимаемое глобальными переменными
- Можно ли использовать WiFi и Bluetooth/BLE в одном проекте ESP32?
- Энергонезависимое хранение nRF52/возврат переменной-есть ли простое решение?
- Ограничен ли веб-сервер ESP32 HTTP определенным количеством изображений Base64?
- 1 глобальная переменная, потребляющая 19% памяти
- передать «большой» массив измерений на сервер через Wi-Fi
если размер равен 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