diff --git a/config/patches/ruby/fix-ruby-xfree-for-libxml2-2.7.patch b/config/patches/ruby/fix-ruby-xfree-for-libxml2-2.7.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac847a87405d4026e780009585e94b8a163256cd_Y29uZmlnL3BhdGNoZXMvcnVieS9maXgtcnVieS14ZnJlZS1mb3ItbGlieG1sMi0yLjcucGF0Y2g= --- /dev/null +++ b/config/patches/ruby/fix-ruby-xfree-for-libxml2-2.7.patch @@ -0,0 +1,23 @@ +diff --git a/gc.c b/gc.c +index 67a709ff79..98785901f4 100644 +--- a/gc.c ++++ b/gc.c +@@ -10174,8 +10174,16 @@ ruby_xrealloc2_body(void *ptr, size_t n, size_t size) + void + ruby_sized_xfree(void *x, size_t size) + { +- if (x) { +- objspace_xfree(&rb_objspace, x, size); ++ if (LIKELY(x)) { ++ /* It's possible for a C extension's pthread destructor function set by pthread_key_create ++ * to be called after ruby_vm_destruct and attempt to free memory. Fall back to mimfree in ++ * that case. */ ++ if (LIKELY(GET_VM())) { ++ objspace_xfree(&rb_objspace, x, size); ++ } ++ else { ++ ruby_mimfree(x); ++ } + } + } + diff --git a/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.0.patch b/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.0.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac847a87405d4026e780009585e94b8a163256cd_Y29uZmlnL3BhdGNoZXMvcnVieS9maXgtcnVieS14ZnJlZS1mb3ItbGlieG1sMi0zLjAucGF0Y2g= --- /dev/null +++ b/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.0.patch @@ -0,0 +1,23 @@ +diff --git a/gc.c b/gc.c +index 5d0c342206..2bfff21004 100644 +--- a/gc.c ++++ b/gc.c +@@ -10905,8 +10905,16 @@ ruby_xrealloc2_body(void *ptr, size_t n, size_t size) + void + ruby_sized_xfree(void *x, size_t size) + { +- if (x) { +- objspace_xfree(&rb_objspace, x, size); ++ if (LIKELY(x)) { ++ /* It's possible for a C extension's pthread destructor function set by pthread_key_create ++ * to be called after ruby_vm_destruct and attempt to free memory. Fall back to mimfree in ++ * that case. */ ++ if (LIKELY(GET_VM())) { ++ objspace_xfree(&rb_objspace, x, size); ++ } ++ else { ++ ruby_mimfree(x); ++ } + } + } + diff --git a/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.1.patch b/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.1.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac847a87405d4026e780009585e94b8a163256cd_Y29uZmlnL3BhdGNoZXMvcnVieS9maXgtcnVieS14ZnJlZS1mb3ItbGlieG1sMi0zLjEucGF0Y2g= --- /dev/null +++ b/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.1.patch @@ -0,0 +1,23 @@ +diff --git a/gc.c b/gc.c +index 030a4627bd..1c96f6401f 100644 +--- a/gc.c ++++ b/gc.c +@@ -11763,8 +11763,16 @@ ruby_xrealloc2_body(void *ptr, size_t n, size_t size) + void + ruby_sized_xfree(void *x, size_t size) + { +- if (x) { +- objspace_xfree(&rb_objspace, x, size); ++ if (LIKELY(x)) { ++ /* It's possible for a C extension's pthread destructor function set by pthread_key_create ++ * to be called after ruby_vm_destruct and attempt to free memory. Fall back to mimfree in ++ * that case. */ ++ if (LIKELY(GET_VM())) { ++ objspace_xfree(&rb_objspace, x, size); ++ } ++ else { ++ ruby_mimfree(x); ++ } + } + } + diff --git a/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.2.patch b/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.2.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac847a87405d4026e780009585e94b8a163256cd_Y29uZmlnL3BhdGNoZXMvcnVieS9maXgtcnVieS14ZnJlZS1mb3ItbGlieG1sMi0zLjIucGF0Y2g= --- /dev/null +++ b/config/patches/ruby/fix-ruby-xfree-for-libxml2-3.2.patch @@ -0,0 +1,23 @@ +diff --git a/gc.c b/gc.c +index 54400e4f6b..96d43ac8ac 100644 +--- a/gc.c ++++ b/gc.c +@@ -12614,8 +12614,16 @@ ruby_xrealloc2_body(void *ptr, size_t n, size_t size) + void + ruby_sized_xfree(void *x, size_t size) + { +- if (x) { +- objspace_xfree(&rb_objspace, x, size); ++ if (LIKELY(x)) { ++ /* It's possible for a C extension's pthread destructor function set by pthread_key_create ++ * to be called after ruby_vm_destruct and attempt to free memory. Fall back to mimfree in ++ * that case. */ ++ if (LIKELY(GET_VM())) { ++ objspace_xfree(&rb_objspace, x, size); ++ } ++ else { ++ ruby_mimfree(x); ++ } + } + } + diff --git a/config/software/ruby.rb b/config/software/ruby.rb index 0d4c30382df61a7ba2690b7f937385248262cd95_Y29uZmlnL3NvZnR3YXJlL3J1YnkucmI=..ac847a87405d4026e780009585e94b8a163256cd_Y29uZmlnL3NvZnR3YXJlL3J1YnkucmI= 100644 --- a/config/software/ruby.rb +++ b/config/software/ruby.rb @@ -105,16 +105,16 @@ # be fixed. end - # Enable custom patch created by ayufan that allows to count memory allocations - # per-thread. This is asked to be upstreamed as part of https://github.com/ruby/ruby/pull/3978 - if version.start_with?('2.7') - patch source: 'thread-memory-allocations-2.7.patch', plevel: 1, env: env - elsif version.start_with?('3.0') - patch source: 'thread-memory-allocations-3.0.patch', plevel: 1, env: env - elsif version.start_with?('3.1') - patch source: 'thread-memory-allocations-3.1.patch', plevel: 1, env: env - elsif version.start_with?('3.2') - patch source: 'thread-memory-allocations-3.2.patch', plevel: 1, env: env + # Two patches: + # 1. Enable custom patch created by ayufan that allows to count memory allocations + # per-thread. This is asked to be upstreamed as part of https://github.com/ruby/ruby/pull/3978 + # 2. Backport Ruby upstream patch to fix seg faults in libxml2/Nokogiri: https://bugs.ruby-lang.org/issues/19580 + # This has been merged for Ruby 3.3 but not yet backported: https://github.com/ruby/ruby/pull/7663 + patches = %w[thread-memory-allocations fix-ruby-xfree-for-libxml2] + ruby_version = Gem::Version.new(version).canonical_segments[0..1].join('.') + + patches.each do |patch_name| + patch source: "#{patch_name}-#{ruby_version}.patch", plevel: 1, env: env end # copy_file_range() has been disabled on recent RedHat kernels: