Julia: Name collision in kwfunction can cause lost root

Created on 19 May 2019  路  2Comments  路  Source: JuliaLang/julia

CUDAnative is currently reliably seqfaulting during precompilation on current master (https://github.com/JuliaGPU/CUDAnative.jl/issues/407),
I bisected it to https://github.com/JuliaLang/julia/pull/31916#issuecomment-493688476

(rr) bt
#0  0x00007f2d582f056f in jl_is_submodule (child=0x1, parent=0x7f2d48c94010) at /home/vchuravy/julia/src/module.c:706
#1  0x00007f2d582ff622 in module_in_worklist (mod=0x1) at /home/vchuravy/julia/src/dump.c:227
#2  0x00007f2d582ff682 in type_in_worklist (dt=0x7f2d4aa21820) at /home/vchuravy/julia/src/dump.c:238
#3  0x00007f2d58303298 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d492a4a88, as_literal=0) at /home/vchuravy/julia/src/dump.c:982
#4  0x00007f2d583037a8 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d49efcc10, as_literal=0) at /home/vchuravy/julia/src/dump.c:1066
#5  0x00007f2d58303548 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4960c420, as_literal=0) at /home/vchuravy/julia/src/dump.c:1021
#6  0x00007f2d582fffff in jl_serialize_datatype (s=0x7ffe41c05a20, dt=0x7f2d4aa216d0) at /home/vchuravy/julia/src/dump.c:403
#7  0x00007f2d58301fdf in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4aa216d0, as_literal=0) at /home/vchuravy/julia/src/dump.c:766
#8  0x00007f2d58302151 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d48386c70, as_literal=0) at /home/vchuravy/julia/src/dump.c:780
#9  0x00007f2d58301210 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4a50ba10, as_literal=0) at /home/vchuravy/julia/src/dump.c:626
#10 0x00007f2d58300037 in jl_serialize_datatype (s=0x7ffe41c05a20, dt=0x7f2d4aa21740) at /home/vchuravy/julia/src/dump.c:405
#11 0x00007f2d58301fdf in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4aa21740, as_literal=0) at /home/vchuravy/julia/src/dump.c:766
#12 0x00007f2d58302d95 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4960c560, as_literal=0) at /home/vchuravy/julia/src/dump.c:923
#13 0x00007f2d583037a8 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d49efcbb0, as_literal=0) at /home/vchuravy/julia/src/dump.c:1066
#14 0x00007f2d58303548 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4960c3d0, as_literal=0) at /home/vchuravy/julia/src/dump.c:1021
#15 0x00007f2d582fffff in jl_serialize_datatype (s=0x7ffe41c05a20, dt=0x7f2d4aa21660) at /home/vchuravy/julia/src/dump.c:403
#16 0x00007f2d58301fdf in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4aa21660, as_literal=0) at /home/vchuravy/julia/src/dump.c:766
#17 0x00007f2d583002bc in jl_serialize_module (s=0x7ffe41c05a20, m=0x7f2d4898dae0) at /home/vchuravy/julia/src/dump.c:446
#18 0x00007f2d58302ba3 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d4898dae0, as_literal=0) at /home/vchuravy/julia/src/dump.c:899
#19 0x00007f2d58300210 in jl_serialize_module (s=0x7ffe41c05a20, m=0x7f2d48c94010) at /home/vchuravy/julia/src/dump.c:439
#20 0x00007f2d58302ba3 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d48c94010, as_literal=0) at /home/vchuravy/julia/src/dump.c:899
#21 0x00007f2d583018e6 in jl_serialize_value_ (s=0x7ffe41c05a20, v=0x7f2d48c7f2b0, as_literal=0) at /home/vchuravy/julia/src/dump.c:686
#22 0x00007f2d5830ae03 in jl_save_incremental (fname=0x55ccafc39a60 "/home/vchuravy/.julia/compiled/v1.3/CUDAnative/4Zu2W.ji", worklist=0x7f2d48c7f2b0) at /home/vchuravy/julia/src/dump.c:2821
#23 0x00007f2d5833993c in jl_write_compiler_output () at /home/vchuravy/julia/src/precompile.c:66
#24 0x00007f2d582f4ee9 in jl_atexit_hook (exitcode=0) at /home/vchuravy/julia/src/init.c:234
#25 0x000055ccae28fd13 in main (argc=0, argv=0x7ffe41c06128) at /home/vchuravy/julia/ui/repl.c:218

In frame 4, we are in the process of serializing a MethodTable, and are about to serialize the kwsorter.

(rr) call jl_(v)
Core.MethodTable(name=:hook, defs=Core.TypeMapEntry(sig=Tuple{getfield(CUDAnative, Symbol("#hook#179")){#hook#178} where #hook#178, CUDAnative.CompilerJob}, simplesig=nothing, guardsigs=svec(), min_world=26826, max_world=-1, func=CUDAnative.hook(...), isleafsig=false, issimplesig=false, va=false, next=鈫╋笌
  nothing), cache=nothing, max_args=2, kwsorter=<?#0x7f2d492a4a88::<?#0x7f2d4aa21820::<?#0x7f2d4aa21880::(nil)>>>, module=CUDAnative, backedges=#<null>, =0, =139831250255872, offs=0x00, =0x00)

(rr) call jl_get_nth_field(v, i)
$23 = (jl_value_t *) 0x7f2d492a4a88
(rr) call jl_($23)
<?#0x7f2d492a4a88::<?#0x7f2d4aa21820::<?#0x7f2d4aa21880::(nil)>>>
bug keyword arguments regression

Most helpful comment

MWE:

function g(i::Float32; args...)
    hook(i; args...) = args
    hook(i; args...)
end

function g(i::Int32; args...)
    hook(i; args...) = args
    hook(i; args...)
end
diff --git a/src/module.c b/src/module.c
index ae7520e098..6db361b7c2 100644
--- a/src/module.c
+++ b/src/module.c
@@ -500,20 +500,18 @@ JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var)
 JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT)
 {
     jl_binding_t *bp = jl_get_binding_wr(m, var, 1);
-    if (!bp->constp) {
-        bp->value = val;
-        jl_gc_wb(m, val);
-    }
+    assert(!bp->constp);
+    bp->value = val;
+    jl_gc_wb(m, val);
 }

 JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT)
 {
     jl_binding_t *bp = jl_get_binding_wr(m, var, 1);
-    if (!bp->constp) {
-        bp->value = val;
-        bp->constp = 1;
-        jl_gc_wb(m, val);
-    }
+    assert(!bp->constp);
+    bp->value = val;
+    bp->constp = 1;
+    jl_gc_wb(m, val);
 }
 ```

~~edit:
Before:

%13 = (Core.kwfunc)(hook)::Core.Compiler.Const(getfield(Main, Symbol("#kw##hook#6"))(), false)


After:

%14 = Core.kwfunc(hook)::Core.Compiler.Const(getfield(Main, Symbol("#kw#hook"))(), false)
```

All 2 comments

I think I know what is going on:
https://github.com/JuliaLang/julia/blob/e39f498aca58abb8aecac34d329d7de9a0cead02/src/gf.c#L2367 depends on jl_set_const to root its argument in module, which it might not
do due to https://github.com/JuliaLang/julia/blob/e39f498aca58abb8aecac34d329d7de9a0cead02/src/module.c#L512, e.g. if we have a name collision.

This might be similar to #32128

~~edit:

We are trying to insert a new ftype for #kw#hook, but there are several inner methods with the same name.

https://github.com/JuliaGPU/CUDAnative.jl/blob/ee3981ea3f7ceddabacf2b357f26b345da03337b/src/reflection.jl#L248
https://github.com/JuliaGPU/CUDAnative.jl/blob/ee3981ea3f7ceddabacf2b357f26b345da03337b/src/reflection.jl#L260

MWE:

function g(i::Float32; args...)
    hook(i; args...) = args
    hook(i; args...)
end

function g(i::Int32; args...)
    hook(i; args...) = args
    hook(i; args...)
end
diff --git a/src/module.c b/src/module.c
index ae7520e098..6db361b7c2 100644
--- a/src/module.c
+++ b/src/module.c
@@ -500,20 +500,18 @@ JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var)
 JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT)
 {
     jl_binding_t *bp = jl_get_binding_wr(m, var, 1);
-    if (!bp->constp) {
-        bp->value = val;
-        jl_gc_wb(m, val);
-    }
+    assert(!bp->constp);
+    bp->value = val;
+    jl_gc_wb(m, val);
 }

 JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT)
 {
     jl_binding_t *bp = jl_get_binding_wr(m, var, 1);
-    if (!bp->constp) {
-        bp->value = val;
-        bp->constp = 1;
-        jl_gc_wb(m, val);
-    }
+    assert(!bp->constp);
+    bp->value = val;
+    bp->constp = 1;
+    jl_gc_wb(m, val);
 }
 ```

~~edit:
Before:

%13 = (Core.kwfunc)(hook)::Core.Compiler.Const(getfield(Main, Symbol("#kw##hook#6"))(), false)


After:

%14 = Core.kwfunc(hook)::Core.Compiler.Const(getfield(Main, Symbol("#kw#hook"))(), false)
```

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sbromberger picture sbromberger  路  3Comments

musm picture musm  路  3Comments

ararslan picture ararslan  路  3Comments

manor picture manor  路  3Comments

omus picture omus  路  3Comments