Полная версия этой страницы:
Вопрос по LwIP
l_fin_l
Dec 28 2016, 05:19
Здравствуйте, использую LwIP порт для stm32f207(компилятор IAR), при работе более 24 часов, функция netconn_recv возвращает ошибку ERR_MEM. Не могу понять где не хватает памяти, как я понял стек выделяет для приема память из PBUF_POOL. Возможно я что-то недопонимаю, заранее спасибо.
Цитата(l_fin_l @ Dec 28 2016, 08:19)

Не могу понять где не хватает памяти
Для таких случаев там есть возможность сбора статистики. Включите её и посмотрите, что там кончилось.
l_fin_l
Dec 28 2016, 11:06
lwip_stats выдает в поле "NETBUF" следущее:
-avail:6
-used:2
-max:3
-err:1
-illegal:0
т.е. как я понимаю, он не смог выделить память под структуру netbuf, хотя разрешенное мной кол-во составляет 6, а откуда он черпает память для выделения под структуры этого типа?
Цитата(l_fin_l @ Dec 28 2016, 14:06)

т.е. как я понимаю, он не смог выделить память под структуру netbuf
Интересно, откуда это следует?
Правильнее будет сохранять всю статистику каждый час. Потом можно посмотреть, что утекает со временем.
l_fin_l
Dec 28 2016, 11:21
Цитата
Правильнее будет сохранять всю статистику каждый час. Потом можно посмотреть, что утекает со временем.
С другими типами структур все в порядке, всего хватает.
Pridnya
Dec 29 2016, 05:25
Цитата(l_fin_l @ Dec 28 2016, 08:19)

Здравствуйте, использую LwIP порт для stm32f207(компилятор IAR), при работе более 24 часов, функция netconn_recv возвращает ошибку ERR_MEM. Не могу понять где не хватает памяти, как я понял стек выделяет для приема память из PBUF_POOL. Возможно я что-то недопонимаю, заранее спасибо.
Укажите хотя бы версию LwIP, а то люди отвечают даже не зная какая у вас версия (1.3.2...2.0.0).

И версию компилятора тоже можно указать.
l_fin_l
Dec 29 2016, 08:00
LwIP 1.4.0, IAR - 7.80.2
Кстати, ERR_MEM не обязательно означает, что кончилась память. Если заглянуть в исходники lwip, в некоторых ситуациях этот код возвращается не из-за исчерпания памяти, а из-за достижения других ограничений.
В общем, хорошо бы поймать в отладчике момент, когда возникает этот код, и установить точную причину.
Кстати, неплохо было бы включить вывод диагностической информации. Там точно будет сообщение о причине ERR_MEM.
l_fin_l
Dec 29 2016, 09:08
Ошибка вылетает в функции netconn_recv, когда пытается выделить память под MEMP_NETBUF(api_lib.c):
Код
if (conn->type == NETCONN_TCP) {
struct pbuf *p = NULL;
/* This is not a listening netconn, since recvmbox is set */
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
if (buf == NULL) {
NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
return ERR_MEM;
}
Ну и в самом маллоке вылетает ошибка(memp.c):
Код
if (memp != NULL) {
memp_tab[type] = memp->next;
#if MEMP_OVERFLOW_CHECK
memp->next = NULL;
memp->file = file;
memp->line = line;
#endif /* MEMP_OVERFLOW_CHECK */
MEMP_STATS_INC_USED(used, type);
LWIP_ASSERT("memp_malloc: memp properly aligned",
((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
} else {
[b] LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
MEMP_STATS_INC(err, type);[/b]
}
Pridnya
Dec 29 2016, 09:09
Цитата(scifi @ Dec 29 2016, 11:43)

Кстати, неплохо было бы включить вывод диагностической информации. Там точно будет сообщение о причине ERR_MEM.
Для этого нужно настроить какой-нибудь UART на вывод, переопределить макрос, который выводит отладочные строки в конкретный UART, и в настройках стека разрешить вывод отладочной информации вообще и в конкретных ситуациях.
l_fin_l
Dec 29 2016, 13:53
Цитата
Для этого нужно настроить какой-нибудь UART на вывод, переопределить макрос, который выводит отладочные строки в конкретный UART, и в настройках стека разрешить вывод отладочной информации вообще и в конкретных ситуациях.
Завтра сделаю, но я все-равно не могу понять что происходит, вроде как место под структуру должно быть, т.к всего 6(используется 2, максимально 3), и он не может выделить память, попадает в:
Код
} else {
LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
MEMP_STATS_INC(err, type);
}
l_fin_l
Jan 5 2017, 12:23
Цитата
В общем, хорошо бы поймать в отладчике момент, когда возникает этот код, и установить точную причину.
При помощи отладчика увидел проблему, функция memp_malloc при выделении памяти переменной memp(memp_tab[5]) назначает NULL(т.е. не может выделить память)

Хотя потом продолжает дальше работать
Сергей Борщ
Jan 5 2017, 13:36
QUOTE (l_fin_l @ Jan 5 2017, 14:23)

При помощи отладчика увидел проблему, функция memp_malloc при выделении памяти переменной memp(memp_tab[5]) назначает NULL(т.е. не может выделить память)
Это больше похоже на признак конца связанного списка. Отладчику это ничего не говорит и он продолжает честно показывать список дальше - это наблюдающий за отладчиком программист должен понять, что за нулевым указателем искать дальше нечего.
l_fin_l
Jan 5 2017, 14:55
Я понимаю, что это маркер конца списка, просто сам список состоит далеко не из шести элементов. Хотя на этапе инициализации создается список из шести элементов. Или он изменяется в процессе работы?
Сергей Борщ
Jan 5 2017, 16:21
QUOTE (l_fin_l @ Jan 5 2017, 16:55)

просто сам список состоит далеко не из шести элементов
Я на вашей картинке вижу, что memp_tab[5] содержит список из трех элементов. При чем тут число шесть, я не понимаю. На указателе, хранящем ноль список заканчивается. Не нужно раскрывать этот элемент - данных по адресу ноль (очередного элемента списка) быть не может (это написано в Стандарте языка Си). Встретили ноль - остановилсь. Список закончился. Дальше данных нет. Указатель "ноль" - это бездна и заглядывать в нее не нужно. По адресу ноль физически располагается начало таблицы векторов прерываний и нет никакого смысла пытаться рассматривать часть ее как элемент списка. Отладчик таких тонкостей не знает и раскроет вам указатель, показывающий куда угодно. Но вы же человек, вы должны думать. Если вы посмотрите исходники, то увидите, что просмотр списка прекращается как только в указателе нашли NULL, а это и есть этот самый ноль.
l_fin_l
Feb 17 2017, 04:15
В режиме отладки выдает следующую ошибку(после нескольких часов работы):
memp_malloc: out of memory in pool NETBUF
В структуре lwip_stats в поле NETBUF, находятся следующие значения:
- avail: 6;
- used: 3;
- max: 3;
- err: 1;
И продолжает работать дальше...
l_fin_l
Mar 9 2017, 15:39
Как я понимаю, это утечка памяти. Но почему он выдает ошибку out of memory in pool NETBUF, если еще есть свободных три блока, ладно если все шесть блоков были заняты. Может кто сталкивался с таким?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.