-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
static analysis finds problem in gc_never_free #2204
Comments
I've managed to trigger this bug with this code import displayio
import adafruit_displayio_sh1106
import time
import busio
import board
def setup():
print("initialising i2c")
i2c = busio.I2C(board.D8, board.D7)
print("initialising bus")
bus = displayio.I2CDisplay(i2c, device_address=0x3c)
print("initialising display")
disp = adafruit_displayio_sh1106.SH1106(bus, width=132,height=64)
time.sleep(0.1)
displayio.release_displays()
i2c.deinit()
time.sleep(0.1)
for i in range(10):
print(f"loop {i}")
time.sleep(0.5)
setup() This gives the following output:
As you can see this fits with the above issue - we successfully create the first block of pointers, and can allocate three items to the never_free list, but it then crashes when we try to create a second block of pointers |
I've submitted a fix for this, and now my code works as expected:
There is however another issue: there is now a memory leak as we add a new i2c bus reference for each time around my loop My application will maybe do 50 loops before getting a hard reset, so I can live with this for now. Fixing would likely require a new function like |
I can work on creating |
I'm happy to review if you think it'll help these situations. |
After reviewing the PR, I think it'd be better to remove |
thanks @furbrain! did you encounter this problem "organically" or did you go looking for it? |
Fixed by #7983. |
@jepler I encountered it organically - I have a display that i need to regularly power down and then reinitialise and was encountering this bug. @tannewt I agree - I think you said that only one display is actually used by CP internals for displaying error messages etc - so may be better just to keep a reference to that one display. |
The full report from scan-build-7 is here: http://media.unpythonic.net/emergent-files/sandbox/report-3d3d49.html#LN954
Basically, in the case where the first block of 3 "never free" objects is filled, the code needs to allocate a new block and hook it into the linked list that goes via the
[0]
index of each block. The logic to chain the blocks together erroneously tries to usecurrent_reference_block[0]
butcurrent_reference_block
is guaranteed to be NULL at this point, by the condition of the while loop.This bug isn't triggering in practice at this time, as gc_never_free sees only limited use from displayio and I think this means at most one entry is ever used.
The text was updated successfully, but these errors were encountered: