robinst / taglib-ruby

Ruby interface for the TagLib C++ library, for reading and writing meta-data (tags) of many audio formats
https://robinst.github.io/taglib-ruby/
MIT License
256 stars 26 forks source link

Writing MP4 tag sometimes causes segmentation fault. #126

Open Ishotihadus opened 1 year ago

Ishotihadus commented 1 year ago

TagLib::MP4::Tag#[]= sometimes fails even if the same actions often success.

irb(main):001:0> require 'taglib'
=> true
irb(main):002:0> f = TagLib::MP4::File.new('test.m4a')
=> #<TagLib::MP4::File:0x0000000104ef0dd0 @__swigtype__="_p_TagLib__MP4__File">
irb(main):003:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f3b308 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):004:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f71980 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):005:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f76638 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):006:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f7b368 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):007:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f7adf0 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):008:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f79338 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):009:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f77240 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):010:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
=> #<TagLib::MP4::Item:0x0000000104f75b70 @__swigtype__="_p_TagLib__MP4__Item">
irb(main):011:0> f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
(irb):11: [BUG] Segmentation fault at 0x5f6d6f72662e6d65
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]

-- Crash Report log information --------------------------------------------
   See Crash Report log file in one of the following locations:
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0022 p:---- s:0116 e:000115 CFUNC  :[]=
c:0021 p:0018 s:0110 e:000108 EVAL   (irb):11 [FINISH]
c:0020 p:---- s:0106 e:000105 CFUNC  :eval
c:0019 p:0020 s:0098 e:000097 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/workspace.rb:113
c:0018 p:0152 s:0091 e:000089 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/context.rb:497
c:0017 p:0106 s:0078 e:000077 BLOCK  /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:581
c:0016 p:0024 s:0072 e:000071 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:770
c:0015 p:0007 s:0066 e:000065 BLOCK  /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:561
c:0014 p:0123 s:0061 e:000060 BLOCK  /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:253 [FINISH]
c:0013 p:---- s:0057 e:000056 CFUNC  :loop
c:0012 p:0005 s:0053 e:000052 BLOCK  /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:235 [FINISH]
c:0011 p:---- s:0050 e:000049 CFUNC  :catch
c:0010 p:0010 s:0045 e:000044 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:234
c:0009 p:0034 s:0041 E:000638 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:560
c:0008 p:0003 s:0036 e:000035 BLOCK  /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:494 [FINISH]
c:0007 p:---- s:0033 e:000032 CFUNC  :catch
c:0006 p:0050 s:0028 E:0005e0 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:493
c:0005 p:0069 s:0022 e:000021 METHOD /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:416
c:0004 p:0012 s:0016 e:000015 TOP    /Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/exe/irb:9 [FINISH]
c:0003 p:---- s:0013 e:000012 CFUNC  :load
c:0002 p:0078 s:0008 E:000d50 EVAL   /Users/ishotihadus/.rbenv/versions/3.2.2/bin/irb:25 [FINISH]
c:0001 p:0000 s:0003 E:001400 DUMMY  [FINISH]

-- Ruby level backtrace information ----------------------------------------
/Users/ishotihadus/.rbenv/versions/3.2.2/bin/irb:25:in `<main>'
/Users/ishotihadus/.rbenv/versions/3.2.2/bin/irb:25:in `load'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/exe/irb:9:in `<top (required)>'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:416:in `start'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:493:in `run'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:493:in `catch'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:494:in `block in run'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:560:in `eval_input'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:234:in `each_top_level_statement'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:234:in `catch'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:235:in `block in each_top_level_statement'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:235:in `loop'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/ruby-lex.rb:253:in `block (2 levels) in each_top_level_statement'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:561:in `block in eval_input'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:770:in `signal_status'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb.rb:581:in `block (2 levels) in eval_input'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/context.rb:497:in `evaluate'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/workspace.rb:113:in `evaluate'
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.4/lib/irb/workspace.rb:113:in `eval'
(irb):11:in `<top (required)>'
(irb):11:in `[]='

-- Machine register context ------------------------------------------------
  x0: 0x5f6d6f72662e6d65  x1: 0x000000000000009b  x2: 0x000000016eee1f90
  x3: 0x0000000000000ca1  x4: 0x0000000000000001  x5: 0x0000000000000000
  x6: 0x000060000309be70  x7: 0x00000000000008e0 x18: 0x0000000000000000
 x19: 0x000000000000009b x20: 0x00000001060bb650 x21: 0x0000000000000000
 x22: 0x000000016eee1ff8 x23: 0x5f6d6f72662e6d65 x24: 0x00000001016ed000
 x25: 0x000000013e004740 x26: 0x00000001060bb650 x27: 0x0000000000000000
 x28: 0x0000000000000000  lr: 0x00000001015e3a7c  fp: 0x000000016eee1fd0
  sp: 0x000000016eee1f80

-- C level backtrace information -------------------------------------------
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_bugreport+0x9a0) [0x1016044a8]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_bug_for_fatal_signal+0x160) [0x1014405b4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(sig_do_nothing+0x0) [0x10156dcc8]
/usr/lib/system/libsystem_platform.dylib(_sigtramp+0x38) [0x18ebc6a84]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(callable_method_entry_or_negative+0x6c) [0x1015e3a7c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_respond_to+0x50) [0x1015e5c98]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_check_funcall_default_kw+0xec) [0x1015e843c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(convert_type_with_id+0x3c) [0x1014e4990]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_convert_type_with_id+0xc0) [0x1014e48a4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_string_value_ptr+0x4c) [0x101581a50]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/taglib-ruby-1.1.3/lib/taglib_mp4.bundle(_ZL19SWIG_Ruby_MangleStrm+0x44) [0x10641efb0]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/taglib-ruby-1.1.3/lib/taglib_mp4.bundle(_ZL26SWIG_Ruby_ConvertPtrAndOwnmPPvP14swig_type_infoiP17swig_ruby_owntype) [0x106414a58]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/taglib-ruby-1.1.3/lib/taglib_mp4.bundle(_ZL21_wrap_Tag___setitem__iPmm) [0x106419998]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_call_cfunc_with_frame+0xe8) [0x1015f884c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_exec_core+0x1fc4) [0x1015de1c4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_exec+0x82c) [0x1015efdec]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_f_eval+0x1f0) [0x1015ea758]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_call_cfunc_with_frame+0xe8) [0x1015f884c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_exec_core+0x1fc4) [0x1015de1c4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_exec+0x82c) [0x1015efdec]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(invoke_block_from_c_bh+0x3a4) [0x1015ff188]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(loop_i+0x70) [0x1015fe908]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vrescue2+0x170) [0x10144c660]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_rescue2+0x2c) [0x10144c4c8]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_f_loop+0x48) [0x1015ec4e8]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_call_cfunc_with_frame+0xe8) [0x1015f884c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_sendish+0x488) [0x1015fabbc]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_exec_core+0x1ec4) [0x1015de0c4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_exec+0x82c) [0x1015efdec]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(invoke_block_from_c_bh+0x3a4) [0x1015ff188]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(catch_i+0x7c) [0x1015fe850]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_catch_protect+0x15c) [0x1015ebb3c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_f_catch+0x7c) [0x1015ec408]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_call_cfunc_with_frame+0xe8) [0x1015f884c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_sendish+0x488) [0x1015fabbc]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_exec_core+0x1ec4) [0x1015de0c4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_exec+0x82c) [0x1015efdec]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(invoke_block_from_c_bh+0x3a4) [0x1015ff188]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(catch_i+0x7c) [0x1015fe850]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_catch_protect+0x15c) [0x1015ebb3c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_f_catch+0x7c) [0x1015ec408]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_call_cfunc_with_frame+0xe8) [0x1015f884c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_sendish+0x488) [0x1015fabbc]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_exec_core+0x1ec4) [0x1015de0c4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_exec+0x82c) [0x1015efdec]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(load_iseq_eval+0xf8) [0x1014ac514]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_load_internal+0x84) [0x1014a97a8]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_f_load+0xb8) [0x1014aacbc]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_call_cfunc_with_frame+0xe8) [0x1015f884c]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(vm_exec_core+0x1fc4) [0x1015de1c4]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_vm_exec+0x82c) [0x1015efdec]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(rb_ec_exec_node+0x12c) [0x10144bb38]
/Users/ishotihadus/.rbenv/versions/3.2.2/lib/libruby.3.2.dylib(ruby_run_node+0x60) [0x10144b9a4]
/Users/ishotihadus/.rbenv/versions/3.2.2/bin/ruby(main+0x68) [0x100f1bf34]
Ishotihadus commented 1 year ago

I found that this phenomenon occurs when f.tag.item_map is accessed after some tags are added. (Of course, tag[key] = item is counted as a tag addition.) As a workaround, write item_map = f.tag.item_map at first, and then use item_map.insert or item_map.fetch. Calling f.tag.item_map after inserting tags can cause a segmentation fault.

jacobvosmaer commented 1 year ago

I suspect this is a problem in the implementation of __setItem__.

I am clueless about C++ so I don't understand why, but in this code I had to take a pointer to the item list map before modifying it.

Edit: take this with a grain of salt, I have not reproduced the problem yet.

jacobvosmaer commented 1 year ago

@Ishotihadus I am not able to reproduce the segfault. I tried the following, on 189fa6b.

bundle exec rake
ruby -Ilib -rtaglib test.rb

With test.rb being:

f = TagLib::MP4::File.new('test/data/mp4.m4a')

100.times do
  f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
end

puts f.tag.item_map.to_h

This prints a Ruby hash, as expected, without segfaulting.

Ishotihadus commented 1 year ago

Could you try this code? This always fails in my environment even without irb.

# frozen_string_literal: true

require 'net/http'
require 'json'

100.times do
  f = TagLib::MP4::File.new('test.m4a')
  f.tag['©nam'] = TagLib::MP4::Item.from_string_list(['name'])
  f.tag['©ART'] = TagLib::MP4::Item.from_string_list(['artist'])

  request = Net::HTTP::Post.new(URI.parse('https://example.com'))
  request.content_type = 'application/x-www-form-urlencoded;charset=UTF-8'
  request.set_form_data('name' => f.tag['©nam'].to_string_list[0], 'artist' => f.tag['©ART'].to_string_list[0])
  Net::HTTP.start('example.com', 443, use_ssl: true) { |http| http.request(request) }

  f.tag['©lyr'] = TagLib::MP4::Item.from_string_list(['a'])
end

I have a feeling that something in the memory handling around strings is causing this problem, but I am not sure.

jacobvosmaer commented 1 year ago

@Ishotihadus that reproducer still does nothing on my end. I'm also using a mac and taglib 1.13.

  1. What ruby version are you using?
  2. Does your reproducer work if you use the test file from taglib-ruby?
Ishotihadus commented 1 year ago
  1. I use Ruby 3.2.2 from rbenv without customization.
  2. Yes. I can even reproduce the problem with the test file. I have MacBook Pro and Mac Studio, but the problem occurs on both hardwares.

My environment has

My Gemflie.lock is: Gemfile.lock. I also attach logs of bundle exec rake: rake.log; but I think there is no valuable information in this log.

Thanks for your supporting.

Ishotihadus commented 1 year ago

I found this problem appears on Ruby >= 3.2.0 and does not appear on Ruby <= 3.1.4! I use Ruby 3.1.4 for taglib-ruby for now!

jacobvosmaer commented 1 year ago

Thanks. Using ruby 3.2.2 I also get the segfault.

I can't get rid of the HTTP request in the reproducer yet; writing the tag values to /dev/null breaks the reproducer.

jacobvosmaer commented 1 year ago

The segfault also happens if I replace f.tag['©lyr'] = ... with f.tag.empty?. Looks like f.tag is a Ruby object pointing to a garbage memory address?

jacobvosmaer commented 1 year ago

I've narrowed down the reproducer a bit.

require 'net/http'

def do_stuff
  Net::HTTP.get('localhost', '/', 8080)
end

$stdout.sync=true

1000.times do |i|
  printf("%d ", i)

  f = TagLib::MP4::File.new('test/data/mp4.m4a')
  f.tag['©ART'] = TagLib::MP4::Item.from_string_list(['artist'])

  do_stuff

  f.tag.empty?
  f.close
end

puts

I still don't understand why I can't get rid of net/http here.

The number of iterations before a segfault seems to be kind of stable. It varies if you make small changes to the code, such as adding another f.tag[xxx] =.

robinst commented 1 year ago

Interesting. What might help narrowing it down is to see if any of the specific TagLib functionality triggers it. E.g. if you remove from_string_list and use a different tag, can you still reproduce? If not, that would suggest the problem is somewhere in our handling of string lists (just an example).

robinst commented 1 year ago

Also, reading through the Ruby 3.2 release notes, it looks like YJIT is now enabled by default? Does the problem also occur if you disable it on 3.2 (not sure if that's possible?) or if you enable it on < 3.2?

jacobvosmaer commented 1 year ago

Good idea, but YJIT does not seem to be active when I reproduce the bug. I checked by adding puts "YJIT enabled: #{RubyVM::YJIT.enabled?}" which reports false.

Replacing from_string_list with e.g. from_int does not make the crash go away. Replacing the f.tag[xxx] = with f.tag.empty? still triggers the crash.

require 'net/http'

def do_stuff
  Net::HTTP.get('localhost', '/', 8080)
end

$stdout.sync=true

puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"

1000.times do
  f = TagLib::MP4::File.new('test/data/mp4.m4a')
  f.tag.empty?

  do_stuff

  f.tag.empty? # <- second call to #empty? triggers segfault
  f.close
end

puts
jacobvosmaer commented 1 year ago

To be clear, it's not about #empty?, that is just a conveniently succise method call. It also crashes if you call #album or something else.

It seems as if the HTTP request eventually causes the tag to get deallocated somewhere (in C++?).