Skip to content

Commit fd3af72

Browse files
NHDalyvchuravy
authored andcommitted
Fix segfault in static_show, by using correct vt instead of typeof(v) (#38399)
This fixes a segfault introduced in #38049. (cherry picked from commit b602577)
1 parent ebcc603 commit fd3af72

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/rtutils.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,30 @@ static size_t jl_static_show_x_sym_escaped(JL_STREAM *out, jl_sym_t *name) JL_NO
651651
return n;
652652
}
653653

654+
// `jl_static_show()` cannot call `jl_subtype()`, for the GC reasons
655+
// explained in the comment on `jl_static_show_x_()`, below.
656+
// This function checks if `vt <: Function` without triggering GC.
657+
static int jl_static_is_function_(jl_datatype_t *vt) JL_NOTSAFEPOINT {
658+
if (!jl_function_type) { // Make sure there's a Function type defined.
659+
return 0;
660+
}
661+
int _iter_count = 0; // To prevent infinite loops from corrupt type objects.
662+
while (vt != jl_any_type) {
663+
if (vt == NULL) {
664+
return 0;
665+
} else if (_iter_count > 10000) {
666+
// We are very likely stuck in a cyclic datastructure, so we assume this is
667+
// _not_ a Function.
668+
return 0;
669+
} else if (vt == jl_function_type) {
670+
return 1;
671+
}
672+
vt = vt->super;
673+
_iter_count += 1;
674+
}
675+
return 0;
676+
}
677+
654678
// `v` might be pointing to a field inlined in a structure therefore
655679
// `jl_typeof(v)` may not be the same with `vt` and only `vt` should be
656680
// used to determine the type of the value.
@@ -1006,7 +1030,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
10061030
n += jl_static_show_x(out, *(jl_value_t**)v, depth);
10071031
n += jl_printf(out, ")");
10081032
}
1009-
else if (jl_function_type && jl_isa(v, (jl_value_t*)jl_function_type)) {
1033+
else if (jl_static_is_function_(vt)) {
10101034
// v is function instance (an instance of a Function type).
10111035
jl_datatype_t *dv = (jl_datatype_t*)vt;
10121036
jl_sym_t *sym = dv->name->mt->name;

0 commit comments

Comments
 (0)