Skip to content
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

[bug] Use of Ruby's memory management causes crash in unrelated code that also uses libxml2 #2898

Closed
mvz opened this issue Jun 2, 2023 · 5 comments
Labels
topic/memory Segfaults, memory leaks, valgrind testing, etc.

Comments

@mvz
Copy link

mvz commented Jun 2, 2023

Please describe the bug

This is a problem that occurs in CI when running the tests for alexandria. The test process crashes with Ruby 3.2 and up because libxml2 tries to allocate some memory during garbage collection and this is no longer allowed when using the Ruby allocator.

What I think happens is this:

  • GC starts
  • Ruby/GNOME traverses the known GObject objects to mark them
  • Ruby/GNOME fetches properties (in the GObject sense) for all these objects
  • One of the properties gets initialized to its default value
  • As part of this process some SVG is parsed using libxml2
  • Do do this, libxml2 tries to allocate some memory
  • Ruby does not want memory to be allocated during GC
  • The process crashes

In Ruby 3.3.0-preview1 the message is clearer due to ruby/ruby@a1758fb

Help us reproduce what you're seeing

See the build results for mvz/alexandria-book-collection-manager#236. I have not been able to reproduce this locally.

Expected behavior

Environment

Additional context

@mvz mvz added the state/needs-triage Inbox for non-installation-related bug reports or help requests label Jun 2, 2023
@flavorjones
Copy link
Member

flavorjones commented Jun 2, 2023

@mvz Thanks for reporting this. I'll investigate.

In the future, please fill out the template when reporting a bug, in particular the output from nokogiri -v on the system in question is the most valuable thing you can provide, followed by the stack trace (which will eventually be deleted by github after aging so it's important to have here in the issue).

Error and stack trace from the 3.2 failing build:

/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.12.5/lib/rspec/mocks/space.rb:180: [BUG] object allocation during garbage collection phase
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_print_backtrace+0xd) [0x7f6c86edb149] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/vm_dump.c:785
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_vm_bugreport) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/vm_dump.c:1080
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(bug_report_end+0x0) [0x7f6c86cd1639] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:790
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_bug_without_die) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:790
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(die+0x0) [0x7f6c86c28e6f] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:798
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_bug) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:800
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(newobj_slowpath+0x0) [0x7f6c86c299a5] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2812
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(newobj_slowpath_wb_unprotected) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2849
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(newobj_of0+0x16) [0x7f6c86d02ce6] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2886
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(newobj_of) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2896
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_wb_protected_newobj_of) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2918
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(str_alloc_embed+0x10) [0x7f6c86e3ff98] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:894
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(str_new0) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:930
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(str_new_static+0x17) [0x7f6c86e4556f] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:1041
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_enc_str_new_static) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:1076
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(warn_vsprintf+0x5) [0x7f6c86cd0644] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:349
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(warning_string) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:399
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_warning_warn+0x0) [0x7f6c86c28d90] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:414
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_write_warning_str) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:342
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(rb_warn) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:415
/opt/hostedtoolcache/Ruby/3.2.2/x64/lib/libruby.so.3.2(objspace_xmalloc0+0x13) [0x7f6c86c2990d] /tmp/ruby-build.20230330[190](https://github.com/mvz/alexandria-book-collection-manager/actions/runs/5153149748/jobs/9280084087?pr=236#step:5:191)414.1922.caF6Ij/ruby-3.2.2/gc.c:12289
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.15.2-x86_64-linux/lib/nokogiri/3.2/nokogiri.so(xmlAllocParserInputBuffer+0x17) [0x7f6c814c0557]
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.15.2-x86_64-linux/lib/nokogiri/3.2/nokogiri.so(xmlParserInputBufferCreateIO+0x19) [0x7f6c814c0c89]
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.15.2-x86_64-linux/lib/nokogiri/3.2/nokogiri.so(xmlCreateIOParserCtxt+0x33) [0x7f6c81498cd3]

Error and stack trace from 3.3.0-preview1:

/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/gobject-introspection-4.1.7/lib/gobject-introspection/loader.rb:570: [BUG] Cannot malloc during GC
ruby 3.3.0preview1 (2023-05-12 master a1b01e7701) [x86_64-linux]
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(rb_print_backtrace+0xd) [0x7f8e410c7e2b] /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/vm_dump.c:785
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(rb_vm_bugreport) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/vm_dump.c:1101
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(bug_report_end+0x0) [0x7f8e40eccb49] /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/error.c:791
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(rb_bug_without_die) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/error.c:791
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(die+0x0) [0x7f8e40e25a0b] /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/error.c:799
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(rb_bug) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/error.c:801
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(size_mul_or_raise+0x0) [0x7f8e40e264aa] /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:12248
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(size_mul_or_raise) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:196
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(xmalloc2_size) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:12271
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(ruby_xmalloc2_body) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:12510
/opt/hostedtoolcache/Ruby/3.3.0-preview1/x64/lib/libruby.so.3.3(check_malloc_not_in_gc) (null):0
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/lib/nokogiri/nokogiri.so(xmlAllocParserInputBuffer+0x1b) [0x7f8e3b72d3ab] /home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/ext/nokogiri/tmp/x86_64-pc-linux/ports/libxml2/2.11.4/libxml2-2.11.4/xmlIO.c:2326
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/lib/nokogiri/nokogiri.so(xmlAllocParserInputBuffer) (null):0
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/lib/nokogiri/nokogiri.so(xmlParserInputBufferCreateIO+0x1d) [0x7f8e3b72db5d] /home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/ext/nokogiri/tmp/x86_64-pc-linux/ports/libxml2/2.11.4/libxml2-2.11.4/xmlIO.c:3010
/home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/lib/nokogiri/nokogiri.so(xmlCreateIOParserCtxt+0x37) [0x7f8e3b704ed7] /home/runner/work/alexandria-book-collection-manager/alexandria-book-collection-manager/vendor/bundle/ruby/3.3.0+0/gems/nokogiri-1.15.2/ext/nokogiri/tmp/x86_64-pc-linux/ports/libxml2/2.11.4/libxml2-2.11.4/parser.c:12275

@flavorjones flavorjones added topic/memory Segfaults, memory leaks, valgrind testing, etc. and removed state/needs-triage Inbox for non-installation-related bug reports or help requests labels Jun 2, 2023
@flavorjones
Copy link
Member

flavorjones commented Jun 2, 2023

OK, I've looked a bit and I think there are three independent contributing factors that are combining to cause this segfault.

Three contributing factors

First, note that this isn't Nokogiri causing this problem, it's librsvg calling into the libxml2 that Nokogiri vendors. This is happening for complicated reasons, but I'm pretty sure it's because of the issues I outlined in #2746 -- though note in this case, instead of Nokogiri binding to somebody else's libxml2, it's somebody else binding to Nokogiri's libxml2.

Second, something the glib2 gem is doing is allocating memory during Ruby's GC cycle. I'm not sure why this would be without some digging into the glib2 gem to understand the root cause here. Note that glib2 isn't doing anything obviously illegal by allocating memory during GC -- but I am very very curious why it's doing so much work during the mark phase of GC, and that may be unintentional and something the glib2 maintainers should look at.

Third, Nokogiri is configuring it's version of libxml2 to use ruby's memory management functions which means that ruby_xmalloc is invoked when memory is allocated.

Recommended workaround

These three things combine to cause this segfault. We can eliminate the segfault by removing any one (or more) of these three contributing factors.

The third factor is the easiest to address -- you can set the environment variable to default and it should avoid this issue. If you can do that, please do.

Longer-term fix for Nokogiri

The first factor is something that I'm already planning to fix -- see #2746 which I'll probably update with a backreference to this issue.

glib2 behavior

The second factor is, ultimately, something up to the glib2 team to decide whether and how to address. It looks like the mark phase of GC is causing (maybe unintentionally) a whole bunch of work to happen.

A cleaned up stack trace from the 3.3.0-preview1 stack dump shows this pretty clearly:

libruby.so.3.3(check_malloc_not_in_gc) (null):0
nokogiri.so(xmlAllocParserInputBuffer+0x1b) [0x7f8e3b72d3ab] /nokogiri-1.15.2/.../libxml2-2.11.4/xmlIO.c:2326
nokogiri.so(xmlAllocParserInputBuffer) (null):0
nokogiri.so(xmlParserInputBufferCreateIO+0x1d) [0x7f8e3b72db5d] /nokogiri-1.15.2/.../libxml2-2.11.4/xmlIO.c:3010
nokogiri.so(xmlCreateIOParserCtxt+0x37) [0x7f8e3b704ed7] /nokogiri-1.15.2/.../libxml2-2.11.4/parser.c:12275
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f8e1a72b2da) [0x7f8e1a72b2da]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f8e1a7539eb) [0x7f8e1a7539eb]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f8e1a7549ab) [0x7f8e1a7549ab]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f8e1a7c4d67) [0x7f8e1a7c4d67]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f8e1a6da60f) [0x7f8e1a6da60f]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f8e1a72dd0d) [0x7f8e1a72dd0d]
/lib/x86_64-linux-gnu/librsvg-2.so.2(rsvg_handle_close+0x336) [0x7f8e1a731006]
/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so(0x7f8e2c2ec456) [0x7f8e2c2ec456]
/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0(gdk_pixbuf_loader_close+0xeb) [0x7f8e36c13eab]
/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0(0x7f8e36c148e3) [0x7f8e36c148e3]
/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0(gdk_pixbuf_new_from_stream_at_scale+0x7f) [0x7f8e36c1498f]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f8e2f86a54e) [0x7f8e2f86a54e]
/lib/x86_64-linux-gnu/libgtk-3.so.0(gtk_icon_info_load_icon+0x58) [0x7f8e2f86b848]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f8e2f873fba) [0x7f8e2f873fba]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f8e2f87432f) [0x7f8e2f87432f]
/lib/x86_64-linux-gnu/libgtk-3.so.0(gtk_entry_get_icon_pixbuf+0xc4) [0x7f8e2f81bc14]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f8e2f818d4d) [0x7f8e2f818d4d]
/lib/x86_64-linux-gnu/libgobject-2.0.so.0(g_object_get_property+0x1d1) [0x7f8e38536e61]
/glib2-4.1.7/lib/glib2.so(gobj_mark+0xa0) [0x7f8e386e4dd0] /glib2-4.1.7/ext/glib2/rbgobj_object.c:295
/glib2-4.1.7/lib/glib2.so(call_cinfo_mark+0xe) [0x7f8e386eeae2] /glib2-4.1.7/ext/glib2/rbgobj_typeinstance.c:94
/glib2-4.1.7/lib/glib2.so(each_cinfo) /glib2-4.1.7/ext/glib2/rbgobj_typeinstance.c:80
/glib2-4.1.7/lib/glib2.so(rbgobj_instance_call_cinfo_mark) /glib2-4.1.7/ext/glib2/rbgobj_typeinstance.c:100
/glib2-4.1.7/lib/glib2.so(holder_mark+0x25) [0x7f8e386e4275] /glib2-4.1.7/ext/glib2/rbgobj_object.c:84
libruby.so.3.3(gc_mark_stacked_objects+0x78) [0x7f8e40ef6cd8] /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:7438
libruby.so.3.3(gc_mark_stacked_objects_all) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:7476
libruby.so.3.3(gc_marks_rest) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:8632
libruby.so.3.3(gc_marking_exit+0x0) [0x7f8e40ef7c92] /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:8689
libruby.so.3.3(gc_marks) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:8700
libruby.so.3.3(gc_start) /tmp/ruby-build.20230512190356.1915.yQqg5L/ruby-3.3.0-preview1/gc.c:9485

@flavorjones
Copy link
Member

Ah, I went to open an issue on ruby-gnome but discovered that you can implement a get_property method on a descendant of gobject (https://github.com/ToshioCP/Gobject-tutorial/blob/main/gfm/sec5.md#overriding-set_property-and-get_property-class-methods) and so this is likely going to be an issue in whatever gem you're using that's using glib. Maybe you have an idea of what gem that is?

The issue I was going to file looked like this, maybe you could file an upstream issue if you know what gem it is?


g_object_get_property can end up doing a lot of work during the GC mark phase

This is the stack trace of an error that was reported at #2898, which shows that the GC mark phase is triggering some significant computing that requires allocating new memory:

libruby.so.3.2(rb_bug) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:800
libruby.so.3.2(newobj_slowpath+0x0) [0x7f6c86c299a5] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2812
libruby.so.3.2(newobj_slowpath_wb_unprotected) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2849
libruby.so.3.2(newobj_of0+0x16) [0x7f6c86d02ce6] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2886
libruby.so.3.2(newobj_of) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2896
libruby.so.3.2(rb_wb_protected_newobj_of) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2918
libruby.so.3.2(str_alloc_embed+0x10) [0x7f6c86e3ff98] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:894
libruby.so.3.2(str_new0) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:930
libruby.so.3.2(str_new_static+0x17) [0x7f6c86e4556f] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:1041
libruby.so.3.2(rb_enc_str_new_static) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/string.c:1076
libruby.so.3.2(warn_vsprintf+0x5) [0x7f6c86cd0644] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:349
libruby.so.3.2(warning_string) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:399
libruby.so.3.2(rb_warning_warn+0x0) [0x7f6c86c28d90] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:414
libruby.so.3.2(rb_write_warning_str) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:342
libruby.so.3.2(rb_warn) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/error.c:415
libruby.so.3.2(objspace_xmalloc0+0x13) [0x7f6c86c2990d] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:12289
nokogiri-1.15.2-x86_64-linux/lib/nokogiri/3.2/nokogiri.so(xmlAllocParserInputBuffer+0x17) [0x7f6c814c0557]
nokogiri-1.15.2-x86_64-linux/lib/nokogiri/3.2/nokogiri.so(xmlParserInputBufferCreateIO+0x19) [0x7f6c814c0c89]
nokogiri-1.15.2-x86_64-linux/lib/nokogiri/3.2/nokogiri.so(xmlCreateIOParserCtxt+0x33) [0x7f6c81498cd3]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f6c646002da) [0x7f6c646002da]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f6c646289eb) [0x7f6c646289eb]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f6c646299ab) [0x7f6c646299ab]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f6c64699d67) [0x7f6c64699d67]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f6c645af60f) [0x7f6c645af60f]
/lib/x86_64-linux-gnu/librsvg-2.so.2(0x7f6c64602d0d) [0x7f6c64602d0d]
/lib/x86_64-linux-gnu/librsvg-2.so.2(rsvg_handle_close+0x336) [0x7f6c64606006]
/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so(0x7f6c740b1456) [0x7f6c740b1456]
/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0(gdk_pixbuf_loader_close+0xeb) [0x7f6c7cab2eab]
/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0(0x7f6c7cab38e3) [0x7f6c7cab38e3]
/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0(gdk_pixbuf_new_from_stream_at_scale+0x7f) [0x7f6c7cab398f]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f6c7586454e) [0x7f6c7586454e]
/lib/x86_64-linux-gnu/libgtk-3.so.0(gtk_icon_info_load_icon+0x58) [0x7f6c75865848]
/lib/x86_64-linux-gnu/libgtk-3.so.0(gtk_icon_theme_load_icon_for_scale+0xcc) [0x7f6c7586ae7c]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f6c75720a74) [0x7f6c75720a74]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f6c75720eb2) [0x7f6c75720eb2]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f6c7586cecc) [0x7f6c7586cecc]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f6c7586e6f7) [0x7f6c7586e6f7]
/lib/x86_64-linux-gnu/libgtk-3.so.0(gtk_entry_get_icon_pixbuf+0xb6) [0x7f6c75815c06]
/lib/x86_64-linux-gnu/libgtk-3.so.0(0x7f6c75812d4d) [0x7f6c75812d4d]
/lib/x86_64-linux-gnu/libgobject-2.0.so.0(g_object_get_property+0x1d1) [0x7f6c7e3d7e61]
glib2-4.1.7/lib/glib2.so(gobj_mark+0xa0) [0x7f6c7e585ad0] glib2-4.1.7/ext/glib2/rbgobj_object.c:295
glib2-4.1.7/lib/glib2.so(call_cinfo_mark+0xe) [0x7f6c7e58f772] glib2-4.1.7/ext/glib2/rbgobj_typeinstance.c:94
glib2-4.1.7/lib/glib2.so(each_cinfo) glib2-4.1.7/ext/glib2/rbgobj_typeinstance.c:80
glib2-4.1.7/lib/glib2.so(rbgobj_instance_call_cinfo_mark) glib2-4.1.7/ext/glib2/rbgobj_typeinstance.c:100
glib2-4.1.7/lib/glib2.so(holder_mark+0x25) [0x7f6c7e584f75] glib2-4.1.7/ext/glib2/rbgobj_object.c:84
libruby.so.3.2(gc_mark_stacked_objects+0x78) [0x7f6c86cfdc48] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:7437
libruby.so.3.2(gc_mark_stacked_objects_all) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:7477
libruby.so.3.2(gc_marks_rest) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:8675
libruby.so.3.2(gc_marks+0x423) [0x7f6c86cfec63] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:8716
libruby.so.3.2(gc_start) /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:9547
libruby.so.3.2(heap_prepare+0x2d) [0x7f6c86d02058] /tmp/ruby-build.20230330190414.1922.caF6Ij/ruby-3.2.2/gc.c:2431

I don't know glib or GTK very well anymore, but the issue seems to stem from calling g_object_get_property from gobj_mark:

static void
gobj_mark(gpointer ptr)
{
    GObject* gobj = ptr;
    guint n_properties;
    GParamSpec** properties;
    guint i;

    properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(gobj), &n_properties);

    for (i = 0; i < n_properties; i++) {
        GParamSpec* pspec = properties[i];
        GType value_type = G_PARAM_SPEC_VALUE_TYPE(pspec);
        if (G_TYPE_FUNDAMENTAL(value_type) != G_TYPE_OBJECT) continue;
        if (!(pspec->flags & G_PARAM_READABLE)) continue;
        /* FIXME: exclude types that doesn't have identity. */

        {
            GValue gval = G_VALUE_INIT;
            g_value_init(&gval, value_type);
            g_object_get_property(gobj, pspec->name, &gval);
            rbgobj_gc_mark_gvalue(&gval);
            g_value_unset(&gval);
        }
    }

    g_free(properties);
}

This seems like it's an unintentional side effect of some object's get_property implementation.

@mvz
Copy link
Author

mvz commented Jun 5, 2023

Thanks @flavorjones for the detailed analysis and explanation!

Based on your three factors, I will

  • Keep the environment variable set to default in CI.
  • Investigate setting the environment variable before requiring nokogiri, to avoid any potential crashes when users use alexandria (which is a Gtk+ based GUI program).
  • Await the result of RFC: Stop exporting symbols #2746. As far as I can tell, that should solve the problem.
  • See if I can find out what is causing so much work to be done in a simple get_property implementation.

@flavorjones
Copy link
Member

@mvz OK, I'm going to close this issue since I don't think there's anything immediately actionable beyond the work at #2746. But I'm happy to continue the conversation if you've got questions, just comment here or on #2746.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic/memory Segfaults, memory leaks, valgrind testing, etc.
Projects
None yet
Development

No branches or pull requests

2 participants