-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
I am getting odd segfaults with taglib-ruby 1.1.3 #130
Comments
The taglib variant I used was: https://github.com/taglib/taglib/releases/download/v1.13.1/taglib-1.13.1.tar.gz |
I tried it with: https://github.com/taglib/taglib/releases/download/v2.0/taglib-2.0.tar.gz just now, same result. So I think this segfault comes from taglib-ruby itself, not |
Unfortunately due to the way Ruby interacts with C++, the library is quite fragile to how binding objects are accessed/passed around, etc. And yes, there might be bugs in how the bindings are generated with regards to memory management. Do you have any more information, such as:
|
I am seeing similar issue. Fails while enumerating the memoised result of XiphComment#field_list_map , or if I remove the ||=, on the call to field_list_map itself. It seems like that object, or something within it is being freed prematurely. All within Taglib::::File.open block, so nothing should have been freed yet. Fails repeatedly enumerating my test library which is about 300 ogg and flac files, but not always on the same file. # monkey patch XiphComment to add additional getters and setters.
class XiphComment < ::TagLib::Tag
def tags
@tags ||= field_list_map
end
def album_artist(&converter)
#...
tags['ALBUM_ARTIST'].map( &converter) # converter is stripping invalid filename characters
end
end
|
I wonder if it's the same mechanism as I theorized in #126 (comment). Each SWIG Ruby wrapper object will free the underlying C++ object when Ruby GC's the wrapper because of the |
Yep GC.disable avoids the issue. So as those objects are created within the C++ wrappers and referencing each other does there need to be some kind of GC marking ? (its been a while since I did ruby C/C++ things). Oh - the theory in that comment is that the GC of an intermediate object is explicitly destroying other objects in use rather than leaving it all to the garbage collector. Makes sense |
@lwoggardner thank you for framing the problem like that! I have been struggling to see a way to fix it, but indeed marking may be the solution we need. If the parent function marks all its child objects during Ruby GC mark then that should protect us. We already have custom "free functions" in our wrapper code that do essentially the same thing (traverse C++ child objects) so each of those would need a companion "mark function". |
+1, see https://swig.org/Doc4.3/SWIGDocumentation.html#Ruby_nn61 for an example of |
FYI if things not being tracked/marked accurately then we should be able to reproduce the segfaults using GC.start, but I was not able to do this in a simple test case yet. Will keep trying. |
GC.start does not sound like it finishes GC, though. Or does it? |
At least on MRI Ruby the GC.start is just an alias for ObjectSpace.garbage_collect, which seems to default to a full and blocking event. But now the weird thing is - if I perform a GC.start before each Taglib file open, my complex app code no longer segfaults. |
I wonder if the optional arguments of GC.start play a role. https://docs.ruby-lang.org/en/3.3/GC.html#method-c-start This is particularly interesting:
First of all note the inverted logic. When |
I am getting odd segfaults with taglib-ruby 1.1.3, on Linux.
I wrote a custom wrapper in Ruby over taglib-ruby to show on the commandline
information about a .mp3 file:
The last one, aka Segmentation fault, seems to run when I close it or when the script ends.
Here is a partial strace result:
Also, while it may not have anything to do with this, I used taglib ruby wrapper in the past in a ruby-gtk3 tag.
And I also got either random segfaults, or the application was suddenly freezing. I used to think this had to
do with some of my ruby code (hard to isolate it, this was several thousand lines of ruby code, you can see
an image of this here: https://i.imgur.com/MnKgSUF.png )
I now believe that it may be that taglib-ruby causes some issue in use.
Unfortunately I can not be more specific, so I understand this may not be super-useful to you.
However had, if you ever can revisit your own wrapper code, perhaps you can have a more closer look at
anything related to memory, as well as cleanup and finalizers and external calls. taglib-ruby is great, without
it the above GUI would not even be possible (and I intend to use this for jruby eventually one day).
Perhaps a few areas of taglib-ruby can be improved. And/or, if not possible, perhaps debug-code can be
added to indicate more easily where an issue may arise. At any rate, please feel free to close this issue -
unfortunately I can not get a better summary right now. I'll continue to experiment with this and if I
find more, I'll let you know.
The text was updated successfully, but these errors were encountered: