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 =
        sources[s] = name
        return s
    local engine = loadSource("engine.wav")
    -- force garbage collection
    engine = nil
    function toggle()
        -- this fixes it
    --  collectgarbage()
    --  collectgarbage()
        for s, name in pairs(sources) do
            if s:isPlaying() then
                print("pause ".. name)
                print("resume ".. name)
    function love.keypressed(k)
        if k == "x" then toggle() 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, 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