Vala Binding: double free when using ChannelFree() inside a loop.

Started by blitpxl, 6 Mar '25 - 07:32

blitpxl

I'm trying to create a bass binding for the vala programming language when I stumbled upon this issue:

The code below loops through a directory of music files and extracts their tag.
Bass.Init(-1, 48000, 0, null, null);
Bass.PluginLoad("libbassflac.so", 0);

string[] track_list = VA.Util.list_file("/home/blitpxl/Music", {"flac"});
foreach (string track_path in track_list)
{
uint stream = Bass.StreamCreateFile(false, track_path, 0, 0, 0);
string tag = Bass.ChannelGetTags(stream, Bass.TAG_OGG);
// *do something with the tag*
Bass.ChannelFree(stream);  // double free or corruption (!prev) or double free detected in tcache 2
}

However, as mentioned, the code above produce an error of "double free or corruption (!prev)" or "double free detected in tcache 2" and I have no clue why.

When I use it outside of a loop, it runs just fine.
uint stream = Bass.StreamCreateFile(false, track_path, 0, 0, 0);
string tag = Bass.ChannelGetTags(stream, Bass.TAG_OGG);

// *do something with the tag*

Bass.ChannelFree(stream);  // no problemo

Attached is the VAPI binding.

Chris

Hi
if you want only the Tags in the loop(without playing ) then i suggest something like this
string[] track_list = VA.Util.list_file("/home/blitpxl/Music", {"flac"});
uint stream;
string tag;
foreach (string track_path in track_list)
{
       if (stream > 0)
       {
          Bass.ChannelFree(stream);
       }
        stream = Bass.StreamCreateFile(false, track_path, 0, 0, BASS_STREAM_DECODE);
        if (stream > 0) // valid steam
        {
    tag = Bass.ChannelGetTags(stream, Bass.TAG_OGG);
    // *do something with the tag*
        }
}

Ian @ un4seen

Quote from: blitpxl on  6 Mar '25 - 07:32However, as mentioned, the code above produce an error of "double free or corruption (!prev)" or "double free detected in tcache 2" and I have no clue why.

I'm not familiar with Vala. Does it give any more information, eg. a call stack? If so, please post that too. Does the problem still happen if you remove the "Bass.ChannelGetTags" call? Please also confirm what BASS version you're using (with BASS_GetVersion) and on what platform.

blitpxl

Thank you for the reply Chris and Ian! However I found out the answer to be quite straightforward: I'm a big bloody idiot. I somehow forgot to tell vala's refcount system not to sweep the return value of ChannelGetTags.

Changing the bindings from
[CCode (cname = "BASS_ChannelGetTags")]
string ChannelGetTags(uint handle, uint tags);

to
[CCode (cname = "BASS_ChannelGetTags")]
unowned string ChannelGetTags(uint handle, uint tags);

seems to have resolved the issue.