-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backport Ruby upstream patch to fix seg faults in libxml2/Nokogiri
As sparklemotion/nokogiri#2785 (comment) explains, there is a bug in the Ruby interpreter (https://bugs.ruby-lang.org/issues/19580) that has been fixed upstream (ruby/ruby#7663) that causes a seg fault during shutdown with libxml2/Nokogiri. We patched the Ruby interpreter in CI to work around the problem (https://gitlab.com/gitlab-org/gitlab-build-images/-/merge_requests/672) in https://gitlab.com/gitlab-org/gitlab/-/issues/390313, but it appears the seg faults have appeared in production now. On GitLab.com, this week we have seen more than 20 cases with the error: ``` [BUG] Segmentation fault at 0x0000000000000440 ``` We could also work around this problem by setting `NOKOGIRI_LIBXML_MEMORY_MANAGEMENT=default`, but this may cause unexpected memory growth since Ruby no longer manages the memory (see https://github.com/sparklemotion/nokogiri/pull/2843/files). Let's just fix the interpreter since we'd also need to make sure that environment variable is set in any environment that uses Nokogiri (including Rake tasks). Changelog: fixed
- Loading branch information
Showing
5 changed files
with
102 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
+ } | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
+ } | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
+ } | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
+ } | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters