Open matthew-8925 opened 1 month ago
@matthew-8925 Thanks for noticing this problem! We could reproduce it. As of now, it looks a bit as if the idle task in the simulation is not correctly starting up. Hence, it is not in the "task ready list" (pxReadyTasksLists
in tasks.c
) and the assert, that basically checks that a task is always available, fails.
This might happen due to the higher priority HTTPD task that runs select()
. select()
is not recognized by the simulator as a blocking call, which causes the HTTPD task to be scheduled even though it's blocked from the actual OS perspective. This, in turn, might starve other tasks such as the IDLE task, before it even gets ready. This explanation is not bullet-proof, however, and we need to further investigate. We'll keep you updated here.
@matthew-8925 The problem is that the esp_http_server
component creates a "normal" pthread that is running in parallel with the simulated FreeRTOS tasks. Once you call vTaskDelay()
from that pthread in the http callback, it creates a situation that shouldn't be possible: vTaskDelay()
eventually tries to suspend the current FreeRTOS task and run the next FreeRTOS task that is in "ready" state. But since all the other tasks in the simulation are running, blocked or suspended, there is no "ready" task and that's why the assertion triggers.
The workaround on Linux for now would be to completely avoid any FreeRTOS API calls in the http callback. It's probably also a very good idea to avoid any system calls in the http task or block all signals. Otherwise, the task could receive a signal meant for another simulated FreeRTOS task, which would create havoc.
That being said, we are working an a long-term solution for this and other problems with the current Linux simulator. We don't have an ETA yet, though.
Please also note that this example hasn't listed the Linux target in its README file. This means - among other things - that it is not regularly tested in our CI system, which makes encountering any bugs much more likely.
Thanks for the explanation, that's useful to know.
Answers checklist.
IDF version.
v5.2, master
Espressif SoC revision.
n/a
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
n/a
Power Supply used.
USB
What is the expected behavior?
Run the http_server/simple on Linux, with a modified handler using vTaskDelay()
cd /opt/esp/idf/examples/protocols/http_server/simple idf.py --preview set-target linux
Modified the /hello handler to include a vTaskDelay(1). Expect to be able to request the /hello handler without crashing.
What is the actual behavior?
docker run --rm -p 8001:8001 -it espressif/idf:release-v5.2 bash apt update && apt install -y gdb vim cd /opt/esp/idf/examples/protocols/http_server/simple idf.py --preview set-target linux vim main/main.c # ... Edit as per diff below git diff .
idf.py build
gdb -ex run ./build/simple.elf curl http://localhost:8001/hello (from other console)
Steps to reproduce.
Change examples/protocols/http_server/simple/main/main.c to use vTaskDelay(1) in the main loop and hander, resulting in crash.
We have random double free()s when using a mutex in the handler, but the vTaskDelay is the easiest to reproduce.
Debug Logs.
No response
More Information.
No response