aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-07-06 17:30:36 -0400
committerPeter Zhu <peter@peterzhu.ca>2022-07-07 09:39:28 -0400
commitf36859869f31a4cf10805cc620ee6338b66558d1 (patch)
treeaf5bfde9d27b974051212aa9f086d31d5c811674 /gc.c
parentd6c98626da706fe5399a2a13f4a934c27c8f4c7b (diff)
downloadruby-f36859869f31a4cf10805cc620ee6338b66558d1.tar.gz
Improve error message for segv in read_barrier_handler
If the page_body is a null pointer, then read_barrier_handler will crash with an unrelated message. This commit improves the error message. Before: test.rb:1: [BUG] Couldn't unprotect page 0x0000000000000000, errno: Cannot allocate memory After: test.rb:1: [BUG] read_barrier_handler: segmentation fault at 0x14
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index 1ef9cab171..7197e81061 100644
--- a/gc.c
+++ b/gc.c
@@ -5210,18 +5210,27 @@ static void invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *pag
#if GC_CAN_COMPILE_COMPACTION
static void
-read_barrier_handler(uintptr_t address)
+read_barrier_handler(uintptr_t original_address)
{
VALUE obj;
rb_objspace_t * objspace = &rb_objspace;
- address -= address % BASE_SLOT_SIZE;
+ /* Calculate address aligned to slots. */
+ uintptr_t address = original_address - (original_address % BASE_SLOT_SIZE);
obj = (VALUE)address;
+ struct heap_page_body *page_body = GET_PAGE_BODY(obj);
+
+ /* If the page_body is NULL, then mprotect cannot handle it and will crash
+ * with "Cannot allocate memory". */
+ if (page_body == NULL) {
+ rb_bug("read_barrier_handler: segmentation fault at 0x%lx", original_address);
+ }
+
RB_VM_LOCK_ENTER();
{
- unlock_page_body(objspace, GET_PAGE_BODY(obj));
+ unlock_page_body(objspace, page_body);
objspace->profile.read_barrier_faults++;