pycom / pycom-micropython-sigfox

A fork of MicroPython with the ESP32 port customized to run on Pycom's IoT multi-network modules.
MIT License
198 stars 167 forks source link

MEMORY LEAKAGE | LoPy | 1.15.0.b1 | OSError: [Errno 12] ENOMEM - wifis = wlan.scan() #136

Closed danieleftodi closed 6 years ago

danieleftodi commented 6 years ago

(sysname='LoPy', nodename='LoPy', release='1.15.0.b1', version='v1.8.6-849-baa8c33 on 2018-01-29', machine='LoPy with ESP32', lorawan='1.0.0')

Traceback (most recent call last): File "main.py", line 129, in OSError: [Errno 12] ENOMEM

Line 129 :: wifis = wlan.scan()

danieleftodi commented 6 years ago

When in a place where there are many Wi-Fi's ... it crashes ... as it run out of memory to allocate.

Before scanning for Wi-fis ... FREE MEM 35808 ....

danieleftodi commented 6 years ago

When in a place where there are many Wi-Fi's ... it crashes ... as it run out of memory to allocate.

Before scanning for Wi-fis ... FREE MEM 35808 ....

danieleftodi commented 6 years ago

So I found the offending code:

File: modwlan.c Line: 742 --> 750

uint16_t ap_num;
wifi_ap_record_t *ap_record_buffer;
wifi_ap_record_t *ap_record;

esp_wifi_scan_get_ap_num(&ap_num); // get the number of scanned APs
ap_record_buffer = pvPortMalloc(ap_num * sizeof(wifi_ap_record_t));
if (ap_record_buffer == NULL) {
    mp_raise_OSError(MP_ENOMEM);
}

You assume "ap_num" and "wifi_ap_record_t" to always be higher then Zero ...

This is logically a bad thing to do ... as in multiplication Samething multiplied by Zero will always become Null!!!!!

Ergo: ap_record_buffer = pvPortMalloc(ap_num * sizeof(wifi_ap_record_t));

Will most likely sometimes become NULL as "ap_num" == NULL ...

And it turns out that we might sometimes be in places on planet earth where we won't ever see any "APs" ... ergo "ap_num" == NULL ...


danieleftodi commented 6 years ago

For a 1st, I've added a Try-catch ... so we catch the error, so it won't crash the app.


try:
    wifis = wlan.scan()
except OSError:
    wifis = None
    print('-----------------------------------------------------------------------------')
    print("DEBUG :: Try-catch :: Wi-Fi.scan() OSError :: FREE MEM " + str(gc.mem_free()))
    print('-----------------------------------------------------------------------------')

Also, working on a patch ... for the firmware....

danicampora commented 6 years ago

@danieleftodi thanks for pointing this one out. I've fixed and it will be ready for the next release.

danieleftodi commented 6 years ago

@danicampora ... about when will you release a new firmware? (wondering, since we are in a time crunch :-) ....)

danicampora commented 6 years ago

@danieleftodi it's planned for tomorrow end of the day :-)

danieleftodi commented 6 years ago

Great :-D

danieleftodi commented 6 years ago

@danicampora

Hi again, could you please share a link to the new firmware for LoPy?

Since,

https://software.pycom.io/downloads/LoPy_868-1.16.0.b1.tar.gz

doesn't seem to work :-(

danieleftodi commented 6 years ago

@danicampora

Hi again, could you please share a link to the new firmware for LoPy?

Since,

https://software.pycom.io/downloads/LoPy_868-1.16.0.b1.tar.gz

doesn't seem to work :-(