Skip to content

Commit 6d70d2a

Browse files
NHDalyd-netto
andauthored
Attempting to add debug logs for ENQUEUING an invalid object (#49741)
* Attempting to add debug logs for ENQUEUING an invalid object Check for the object's validity _before enqueuing_ so that we can hopefully give a more useful error message (which object's pointer was corrupted). --------- Co-authored-by: Diogo Netto <[email protected]>
1 parent a43ca05 commit 6d70d2a

File tree

1 file changed

+42
-14
lines changed

1 file changed

+42
-14
lines changed

src/gc.c

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,14 +1777,37 @@ STATIC_INLINE uintptr_t gc_read_stack(void *_addr, uintptr_t offset,
17771777
return *(uintptr_t*)real_addr;
17781778
}
17791779

1780-
JL_NORETURN NOINLINE void gc_assert_datatype_fail(jl_ptls_t ptls, jl_datatype_t *vt,
1781-
jl_gc_markqueue_t *mq) JL_NOTSAFEPOINT
1782-
{
1783-
jl_safe_printf("GC error (probable corruption) :\n");
1784-
jl_gc_debug_print_status();
1785-
jl_(vt);
1786-
jl_gc_debug_critical_error();
1787-
abort();
1780+
STATIC_INLINE void gc_assert_parent_validity(jl_value_t *parent, jl_value_t *child) JL_NOTSAFEPOINT
1781+
{
1782+
#ifdef GC_ASSERT_PARENT_VALIDITY
1783+
jl_taggedvalue_t *child_astagged = jl_astaggedvalue(child);
1784+
jl_taggedvalue_t *child_vtag = (jl_taggedvalue_t *)(child_astagged->header & ~(uintptr_t)0xf);
1785+
uintptr_t child_vt = (uintptr_t)child_vtag;
1786+
if (child_vt == (jl_datatype_tag << 4) ||
1787+
child_vt == (jl_unionall_tag << 4) ||
1788+
child_vt == (jl_uniontype_tag << 4) ||
1789+
child_vt == (jl_tvar_tag << 4) ||
1790+
child_vt == (jl_vararg_tag << 4)) {
1791+
// Skip, since these wouldn't hit the object assert anyway
1792+
return;
1793+
}
1794+
else if (child_vt < jl_max_tags << 4) {
1795+
// Skip, since these wouldn't hit the object assert anyway
1796+
return;
1797+
}
1798+
if (__unlikely(!jl_is_datatype((jl_datatype_t *)child_vt) || ((jl_datatype_t *)child_vt)->smalltag)) {
1799+
jl_safe_printf("GC error (probable corruption)\n");
1800+
jl_gc_debug_print_status();
1801+
jl_safe_printf("Parent %p\n", (void *)parent);
1802+
jl_safe_printf("of type:\n");
1803+
jl_(jl_typeof(parent));
1804+
jl_safe_printf("While marking child at %p\n", (void *)child);
1805+
jl_safe_printf("of type:\n");
1806+
jl_(child_vtag);
1807+
jl_gc_debug_critical_error();
1808+
abort();
1809+
}
1810+
#endif
17881811
}
17891812

17901813
// Check if `nptr` is tagged for `old + refyoung`,
@@ -1884,6 +1907,7 @@ STATIC_INLINE jl_value_t *gc_mark_obj8(jl_ptls_t ptls, char *obj8_parent, uint8_
18841907
if (new_obj != NULL) {
18851908
verify_parent2("object", obj8_parent, slot, "field(%d)",
18861909
gc_slot_to_fieldidx(obj8_parent, slot, (jl_datatype_t*)jl_typeof(obj8_parent)));
1910+
gc_assert_parent_validity((jl_value_t *)obj8_parent, new_obj);
18871911
if (obj8_begin + 1 != obj8_end) {
18881912
gc_try_claim_and_push(mq, new_obj, &nptr);
18891913
}
@@ -1915,6 +1939,7 @@ STATIC_INLINE jl_value_t *gc_mark_obj16(jl_ptls_t ptls, char *obj16_parent, uint
19151939
if (new_obj != NULL) {
19161940
verify_parent2("object", obj16_parent, slot, "field(%d)",
19171941
gc_slot_to_fieldidx(obj16_parent, slot, (jl_datatype_t*)jl_typeof(obj16_parent)));
1942+
gc_assert_parent_validity((jl_value_t *)obj16_parent, new_obj);
19181943
if (obj16_begin + 1 != obj16_end) {
19191944
gc_try_claim_and_push(mq, new_obj, &nptr);
19201945
}
@@ -1946,6 +1971,7 @@ STATIC_INLINE jl_value_t *gc_mark_obj32(jl_ptls_t ptls, char *obj32_parent, uint
19461971
if (new_obj != NULL) {
19471972
verify_parent2("object", obj32_parent, slot, "field(%d)",
19481973
gc_slot_to_fieldidx(obj32_parent, slot, (jl_datatype_t*)jl_typeof(obj32_parent)));
1974+
gc_assert_parent_validity((jl_value_t *)obj32_parent, new_obj);
19491975
if (obj32_begin + 1 != obj32_end) {
19501976
gc_try_claim_and_push(mq, new_obj, &nptr);
19511977
}
@@ -2011,6 +2037,7 @@ STATIC_INLINE void gc_mark_objarray(jl_ptls_t ptls, jl_value_t *obj_parent, jl_v
20112037
if (new_obj != NULL) {
20122038
verify_parent2("obj array", obj_parent, obj_begin, "elem(%d)",
20132039
gc_slot_to_arrayidx(obj_parent, obj_begin));
2040+
gc_assert_parent_validity(obj_parent, new_obj);
20142041
gc_try_claim_and_push(mq, new_obj, &nptr);
20152042
gc_heap_snapshot_record_array_edge(obj_parent, &new_obj);
20162043
}
@@ -2084,6 +2111,7 @@ STATIC_INLINE void gc_mark_array8(jl_ptls_t ptls, jl_value_t *ary8_parent, jl_va
20842111
if (new_obj != NULL) {
20852112
verify_parent2("array", ary8_parent, &new_obj, "elem(%d)",
20862113
gc_slot_to_arrayidx(ary8_parent, ary8_begin));
2114+
gc_assert_parent_validity(ary8_parent, new_obj);
20872115
gc_try_claim_and_push(mq, new_obj, &nptr);
20882116
gc_heap_snapshot_record_array_edge(ary8_parent, &new_obj);
20892117
}
@@ -2158,6 +2186,7 @@ STATIC_INLINE void gc_mark_array16(jl_ptls_t ptls, jl_value_t *ary16_parent, jl_
21582186
if (new_obj != NULL) {
21592187
verify_parent2("array", ary16_parent, &new_obj, "elem(%d)",
21602188
gc_slot_to_arrayidx(ary16_parent, ary16_begin));
2189+
gc_assert_parent_validity(ary16_parent, new_obj);
21612190
gc_try_claim_and_push(mq, new_obj, &nptr);
21622191
gc_heap_snapshot_record_array_edge(ary16_parent, &new_obj);
21632192
}
@@ -2311,12 +2340,16 @@ STATIC_INLINE void gc_mark_module_binding(jl_ptls_t ptls, jl_module_t *mb_parent
23112340
if (b == (jl_binding_t *)jl_nothing)
23122341
continue;
23132342
verify_parent1("module", mb_parent, mb_begin, "binding_buff");
2343+
gc_assert_parent_validity((jl_value_t *)mb_parent, (jl_value_t *)b);
23142344
gc_try_claim_and_push(mq, b, &nptr);
23152345
}
23162346
jl_value_t *bindings = (jl_value_t *)jl_atomic_load_relaxed(&mb_parent->bindings);
2347+
gc_assert_parent_validity((jl_value_t *)mb_parent, bindings);
23172348
gc_try_claim_and_push(mq, bindings, &nptr);
23182349
jl_value_t *bindingkeyset = (jl_value_t *)jl_atomic_load_relaxed(&mb_parent->bindingkeyset);
2350+
gc_assert_parent_validity((jl_value_t *)mb_parent, bindingkeyset);
23192351
gc_try_claim_and_push(mq, bindingkeyset, &nptr);
2352+
gc_assert_parent_validity((jl_value_t *)mb_parent, (jl_value_t *)mb_parent->parent);
23202353
gc_try_claim_and_push(mq, (jl_value_t *)mb_parent->parent, &nptr);
23212354
size_t nusings = mb_parent->usings.len;
23222355
if (nusings > 0) {
@@ -2346,7 +2379,7 @@ void gc_mark_finlist_(jl_gc_markqueue_t *mq, jl_value_t **fl_begin, jl_value_t *
23462379
}
23472380
for (; fl_begin < fl_end; fl_begin++) {
23482381
new_obj = *fl_begin;
2349-
if (__unlikely(!new_obj))
2382+
if (__unlikely(new_obj == NULL))
23502383
continue;
23512384
if (gc_ptr_tag(new_obj, 1)) {
23522385
new_obj = (jl_value_t *)gc_ptr_clear_tag(new_obj, 1);
@@ -2535,11 +2568,6 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
25352568
}
25362569
return;
25372570
}
2538-
else {
2539-
jl_datatype_t *vt = (jl_datatype_t *)vtag;
2540-
if (__unlikely(!jl_is_datatype(vt) || vt->smalltag))
2541-
gc_assert_datatype_fail(ptls, vt, mq);
2542-
}
25432571
jl_datatype_t *vt = (jl_datatype_t *)vtag;
25442572
if (vt->name == jl_array_typename) {
25452573
jl_array_t *a = (jl_array_t *)new_obj;

0 commit comments

Comments
 (0)