nodemcu / nodemcu-firmware

Lua based interactive firmware for ESP8266, ESP8285 and ESP32
https://nodemcu.readthedocs.io
MIT License
7.66k stars 3.12k forks source link

net.createServer closed connections memory leak bug/feature request #1801

Closed Uinden closed 7 years ago

Uinden commented 7 years ago

Hi. I'm new to NodeMCU, ESP8266 and Lua so this report may be wrong. Tell me if it is, i will close it. I was testing TCP server and noticed memory leak.

Hardware

ESP-12-E

Software

I built mine NodeMCU online at https://nodemcu-build.com/ I used integer: http://nodemcu-build.com/builds/nodemcu-master-13-modules-2017-02-14-22-27-27-integer.bin Load output is:

NodeMCU custom build by frightanic.com
    branch: master
    commit: b96e31477ca1e207aa1c0cdc334539b1f7d3a7f0
    SSL: false
    modules: adc,bit,cjson,crypto,dht,file,gpio,net,node,pwm,tmr,uart,wifi
 build  built on: 2017-02-14 22:26
 powered by Lua 5.1.4 on SDK 2.0.0(656edbf)

I got HTTP server example code from here: http://nodemcu.readthedocs.io/en/dev/en/

srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
    conn:on("receive", function(sck, payload)
        --print(payload)
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1> Hello, NodeMCU.</h1>")
    end)
    conn:on("sent", function(sck) sck:close() end)
end)

Problem

Holding Ctrl+R in web browser causing crash with out of memory reason. I modified code like that:

requests = 0

-- a simple HTTP server
srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
    conn:on("receive", function(sck, payload)
        --print(payload)
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1> Hello, NodeMCU.</h1>")
        requests = requests+1
    end)
    conn:on("sent", function(sck) sck:close() end)
end)

tmr.create():alarm(200, tmr.ALARM_AUTO, function()
  print(node.heap() .. " - " .. requests)
end)

and holding Ctrl+R causes this:

42600 - 0
42600 - 0
42600 - 0
40240 - 1
42160 - 1
42320 - 1
37672 - 5
36760 - 10
35648 - 16
34544 - 22
//making requests
7448 - 159
5096 - 163
5456 - 166
4536 - 171
3424 - 177
E:M 1584
PANIC: unprotected error in call to Lua API (webserver.lua:8: out of memory)

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

After investigation i found something. If i do about 150 requests and wait some time i will get this:

43464 - 0
41064 - 1
43000 - 1
//making requests
11920 - 154
11920 - 154
//waiting
14352 - 154
15640 - 154
15640 - 154
//waiting more
42624 - 154
42624 - 154
42624 - 154
//memory is back

Calculating time i got about 2 minutes. So after closing connection memory is "reserved" for about 2 minutes. After searching something related to it i found this: https://github.com/espressif/ESP8266_RTOS_SDK/blob/master/include/espressif/espconn.h#L534 bit 0: 1: free memory after TCP disconnection happen need not wait 2 minutes; I'm not completely sure what is this but as i understand it is some espconn_set_opt function inside ESP8266. Searching this repository i found espconn_set_opt is mentioned https://github.com/nodemcu/nodemcu-firmware/search?utf8=%E2%9C%93&q=espconn_set_opt But as i understand it is not used anywhere in the code. Is there way to access it? Or maybe we can have that opt bits in net.createServer(type, timeout) as third parameter like net.createServer(type, timeout, opt)?

djphoenix commented 7 years ago

We have found this at https://github.com/nodemcu/nodemcu-firmware/pull/1379#issuecomment-268074953. So there may (should) be some tunes for TIME_WAIT sockets...

Uinden commented 7 years ago

Ah, okay, thank you.