RIOT-OS / RIOT

RIOT - The friendly OS for IoT
https://riot-os.org
GNU Lesser General Public License v2.1
4.92k stars 1.99k forks source link

gcoap/esp8266: Stack overflow with gcoap example #13606

Open kb2ma opened 4 years ago

kb2ma commented 4 years ago

Description

The gcoap example app experiences a stack overflow when running on board esp8266-esp-12x. This issue arose due to stack use from #13386, which rebased gcoap's use of the sock library on the sock_async feature. For the lwIP stack, also depends on #13427 which added sock_async for lwIP.

Steps to reproduce the issue

There is a problem with stack use both with the GNRC networking stack and with the lwIP sock stack. However, the issue manifests itself differently for each stack. The problem is more acute with the lwIP stack.

To reproduce, build the gcoap example with DEVELHELP=0. Send a request to a server. Then accept a request from a client.

Expected results

Should be able to repeatedly send/receive messages.

Actual results

For GNRC, works as expected. However, the ps command (with DEVELHELP=1) shows the stack overflow. Notice that after send/receive, stack use is 1108 bytes out of 1108 available. If you rebuild with GCOAP_STACK_SIZE set for example to 2048, stack use is 1152 bytes.

For lwIP, the app receives and displays the response from the server. After receiving the request from the client, the board displays something like:

   EXCEPTION!! exccause=28 (LoadProhibitedCause) @4023782a excvaddr=00000004

The board then will reboot after about 30 seconds.

Versions

For GNRC, use RIOT master. For lwIP, use gcoap/lwip_async_support branch, which includes #13427 for lwip sock_async.

Detailed Measurements

The table below shows stack use after sending a /time request to libcoap example and receiving a /riot/board request.

> coap get -c fd00:bbbb::1 5683 /time
$ ./coap-client -m get -T 5a -U coap://[fd00:bbbb::2]/riot/board

"samr21" is for samr21-xpro board. "esp8266" is for esp8266-esp-12x board.

On samr21-xpro and esp8266-esp-12x, GCOAP_STACK_SIZE is 1108: 1024 from THREAD_STACKSIZE DEFAULT + 84 from sizeof(coap_pkt_t). We increased GCOAP_STACK_SIZE to 2048 for the esp8266 builds.

Using RIOT master 6dd69e7, 2019-02-29, which includes the gcoap adaptation to sock_async in #13386. esp8266 lwIP values using gcoap/lwip_async_support branch, based on RIOT master 2cc3d38, 2020-03-08, which includes #13427.

thread samr21
ethos
samr21
6lo
esp8266
GNRC
esp8266
lwIP
isr_stack 208 168 344 344
idle 160 156 240 240
main 980 932 1396 2000
ipv6 568 624 804
udp 356 360 508
coap 816 740 1152 1648 (1)
ethos 564
6lo 468
at86rf2xx 608
netif-esp-wifi 920
ppT 1320 1320
pmT 328 328
rtT 1388 1388
esp_events 892 892
lwip_netdev_mux 448
tcpip_thread 1244
SUM 3652 4056 9392 9852

(1) Stack use is 1156 bytes after sending the GET to libcoap, and then increases to 1648 after receiving the GET from libcoap.

kb2ma commented 4 years ago

The stack size for gcoap on esp8266 is not sufficient. Presently GCOAP_STACK_SIZE is 1108. How to address? @gschorcht, I'd appreciate your thoughts.

  1. esp32 uses 2048 for THREAD_STACKSIZE_DEFAULT. Increase the default for esp8266?

  2. Set GCOAP_STACK_SIZE to 1536 (GNRC) or 2048 (lwIP) in esp8266 cpu_conf.h when the respective module is present? Stack size for GNRC IPv6 thread is set this way. Or set the value in gcoap.h based on CPU?

  3. Create a GCOAP_STACKSIZE_EXTRA and set that to 0 by default, but 512 (GNRC) or 1024 (lwIP) in esp8266 cpu_conf.h?

gschorcht commented 4 years ago

@kb2ma I would prefer option 2. Increasing the default stack size could lead to insufficient memory for other applications if a lot of threads are created.

kb2ma commented 4 years ago

I would prefer option 2

Sounds good to me. I plan to create PRs to incorporate the changes from the gcoap/lwip_async_support branch as well as the increase to GCOAP_STACK_SIZE for esp8266.

maribu commented 1 year ago

Is this still an issue? Bumping the stack size should be easy enough