You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following program demonstrates this issue in 3 different ways
use IO;
import OS.errorCode;
require"foo.h";
externrecord R {
var a,b,c,d,e,f,g,h,i,j,k:int(64);
}
proc printR(r:R) {
writeln("print R");
writeln(r.a, r.b, r.c, r.d, r.e, r.f, r.g, r.h, r.i, r.j, r.k);
}
externtype my_int64_t;
externproc printX(x: my_int64_t);
writeln("print1");
var g: R;
printR(g);
writeln("print2");
var gg: R;
printR(gg);
writeln("print3");
var ggg: R;
printR(ggg);
// all of these are uninitializedvar x: my_int64_t;
printX(x); // uninitializedwriteln("global syserr");
var globSysErr: errorCode;
writeln(globSysErr:int); // segfaults because this is uninitialized, and we try and dereference a bad pointer
This appears to only be an issue with CHPL_COMM=gasnet and CHPL_MEM=cstdlib. Since the memory is uninitialized and can by chance be zero (it frequently is on my Mac, sometimes not on a linxu64 system), the best way to reproduce this bug is with ASAN. I think in theory CHPL_MEM=jemalloc is susceptible to this, but I think we have never hit it in practice.
Furthermore, this is only an issue when the variables are declared as globals. In the above example, wrapping the code inside of an explicit main() function causes the variables to be properly initialized.
My reading of the generated C code is that we intend to memset the variable to 0, but end of not doing so.
Focusing on just printR(g), I compared the generated C;
Because g: R is at global scope (and we have compiled with COMM!=none), g_chpl is now a wide pointer. And we still have the same memset code to initialize it to zero, but it has no effect. The reason it has not effect is due to chpl_gen_comm_get. We call that on g_chpl to copy the actual R struct value locally and then call memset on that temporary. But we never write that temporary back to the wide pointer (with a put). So the memory pointed to by g_chpl is still uninitialized and the memset effectively does a deadstore.
I confirmed that hacking the C code and recompiling with the following means that g_chpl is no longer uninitialized
jabraham17
changed the title
[Bug]: Chapel variables with extern types may not be default intialized
[Bug]: Chapel variables with extern types may not be default initialized
Dec 13, 2024
The following program demonstrates this issue in 3 different ways
This appears to only be an issue with CHPL_COMM=gasnet and CHPL_MEM=cstdlib. Since the memory is uninitialized and can by chance be zero (it frequently is on my Mac, sometimes not on a linxu64 system), the best way to reproduce this bug is with ASAN. I think in theory CHPL_MEM=jemalloc is susceptible to this, but I think we have never hit it in practice.
I have the following
Furthermore, this is only an issue when the variables are declared as globals. In the above example, wrapping the code inside of an explicit
main()
function causes the variables to be properly initialized.My reading of the generated C code is that we intend to memset the variable to 0, but end of not doing so.
Focusing on just
printR(g)
, I compared the generated C;With COMM=none and
g
at global scopeIn this case,
g_chpl
is declared asstatic R g_chpl
at global scope.With COMM=gasnet and
g
at local scopeIn this case,
g_chpl
is declared asR g_chpl
at local scope, inside ofchpl_user_main
.With COMM=gasnet and
g
at global scope (i.e. the problem case)Because
g: R
is at global scope (and we have compiled with COMM!=none),g_chpl
is now a wide pointer. And we still have the samememset
code to initialize it to zero, but it has no effect. The reason it has not effect is due tochpl_gen_comm_get
. We call that ong_chpl
to copy the actual R struct value locally and then call memset on that temporary. But we never write that temporary back to the wide pointer (with aput
). So the memory pointed to byg_chpl
is still uninitialized and thememset
effectively does a deadstore.I confirmed that hacking the C code and recompiling with the following means that
g_chpl
is no longer uninitializedThe text was updated successfully, but these errors were encountered: