Garbage collected audio sources still accessable via weak tables

Issue #1087 wontfix
Daniel Langner
created an issue

I came across this while implementing pause functionality into a game. I store looping audio sources in a weak table in order to pause or resume those sounds when the user hits the pause button. Some audio sources had already been garbage collected, yet while looping over the weak table I could access those (invalid) objects, causing segmentation faults.

To be sure I printed the address of the source in its destructor as well as its pause method. and they matched.

Comments (6)

  1. Daniel Langner reporter
    local sources = setmetatable({}, { __mode = "k" })
    
    function loadSource(name)
        local s = love.audio.newSource(name)
        s:setLooping(true)
        sources[s] = name
        return s
    end
    
    local engine = loadSource("engine.wav")
    engine:play()
    
    -- force garbage collection
    engine = nil
    collectgarbage()
    
    
    function toggle()
    
        -- this fixes it
    --  collectgarbage()
    --  collectgarbage()
    
        for s, name in pairs(sources) do
            if s:isPlaying() then
                print("pause ".. name)
                s:stop()
            else
                print("resume ".. name)
                s:play()
            end
        end
    end
    
    function love.keypressed(k)
        if k == "x" then toggle() end
    end
    
  2. Alex Szpakowski

    Interesting... this appears to be a more fundamental problem with Lua/LuaJIT's implementation of weak keys (it doesn't break for me if I use weak values and set the source as a value rather than a key).

    The issue happens in Lua 5.1, LuaJIT 2.0.3, and LuaJIT 2.1-beta1 for me. It also happens (modify-after-free crash) if I modify the code to use some memory allocated with ffi.C.malloc and automatically garbage collected and deallocated using ffi.gc and ffi.C.free, rather than using a LÖVE object. So LÖVE's own code doesn't appear to be causing it.

  3. Log in to comment