-
Notifications
You must be signed in to change notification settings - Fork 436
Description
I am finding that c_addrOf on an unmanaged class does not work properly in a program with wide pointers.
The following code demonstrates this issues
use CTypes;
class MyClass {
var x: int = 21;
}
proc main() {
var myOwned = new owned MyClass();
var myBorrow = myOwned.borrow();
var myUnmanaged = new unmanaged MyClass();
defer { delete myUnmanaged; }
var addr1 = c_addrOf(myOwned);
var addr2 = c_addrOf(myBorrow);
var addr3 = c_addrOf(myUnmanaged);
writeln(addr1.deref(), addr2.deref(), addr3.deref(), sep =" | "); // addr3.deref() fails
}
This code should either be compiled with CHPL_COMM=gasnet or --no-local.
With CHPL_COMM=gasnet, the code segfaults
*** Caught a fatal signal (proc 0): SIGSEGV(11)
*** NOTICE (proc 0): Before reporting bugs, run with GASNET_BACKTRACE=1 in the environment to generate a backtrace.
*** NOTICE (proc 0): We recommend linking the debug version of GASNet to assist you in resolving this application issue.
{x = 21} | {x = 21} | {%
$ chpl --comm=gasnet egg.chpl --print-chpl-settings
machine info: Darwin HPE-D2RLK75V43 25.0.0 Darwin Kernel Version 25.0.0: Wed Sep 17 21:41:45 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6000 arm64
CHPL_HOME: /opt/homebrew/Cellar/chapel/2.6.0_1/libexec *
script location: /opt/homebrew/Cellar/chapel/2.6.0_1/libexec/util/chplenv
CHPL_HOST_PLATFORM: darwin
CHPL_HOST_COMPILER: clang
CHPL_HOST_CC: clang
CHPL_HOST_CXX: clang++
CHPL_HOST_ARCH: arm64
CHPL_TARGET_PLATFORM: darwin
CHPL_TARGET_COMPILER: llvm
CHPL_TARGET_CC: /opt/homebrew/Cellar/llvm@20/20.1.8/bin/clang-20
CHPL_TARGET_CXX: /opt/homebrew/Cellar/llvm@20/20.1.8/bin/clang++
CHPL_TARGET_LD: /opt/homebrew/Cellar/llvm@20/20.1.8/bin/clang++
CHPL_TARGET_ARCH: arm64
CHPL_TARGET_CPU: native +
CHPL_LOCALE_MODEL: flat
CHPL_COMM: gasnet *
CHPL_COMM_SUBSTRATE: udp
CHPL_GASNET_SEGMENT: everything
CHPL_TASKS: qthreads
CHPL_LAUNCHER: amudprun
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_HOST_MEM: cstdlib
CHPL_TARGET_MEM: jemalloc +
CHPL_TARGET_JEMALLOC: system +
CHPL_ATOMICS: cstdlib
CHPL_NETWORK_ATOMICS: none
CHPL_GMP: system +
CHPL_HWLOC: system +
CHPL_RE2: bundled +
CHPL_LLVM: system +
CHPL_LLVM_SUPPORT: system
CHPL_LLVM_CONFIG: /opt/homebrew/opt/llvm@20/bin/llvm-config +
CHPL_LLVM_VERSION: 20
CHPL_AUX_FILESYS: none
CHPL_LIB_PIC: none
CHPL_SANITIZE: none
CHPL_SANITIZE_EXE: none
With --no-local, the issue can be reproduced in a CHPL_COMM=none build as long as asserts are enabled.
Assertion failed: (node==0), function chpl_comm_get, file comm-none.c, line 280.
{zsh: abort ./a.out
machine info: Darwin HPE-D2RLK75V43 25.0.0 Darwin Kernel Version 25.0.0: Wed Sep 17 21:41:45 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6000 arm64
CHPL_HOME: /Users/jade/Development/chapel-lang/chapel *
script location: /Users/jade/Development/chapel-lang/chapel/util/chplenv
CHPL_HOST_PLATFORM: darwin
CHPL_HOST_COMPILER: clang
CHPL_HOST_CC: clang *
CHPL_HOST_CXX: clang++ *
CHPL_HOST_ARCH: arm64
CHPL_TARGET_PLATFORM: darwin
CHPL_TARGET_COMPILER: llvm
CHPL_TARGET_CC: /opt/homebrew/Cellar/llvm@20/20.1.8/bin/clang-20
CHPL_TARGET_CXX: /opt/homebrew/Cellar/llvm@20/20.1.8/bin/clang++
CHPL_TARGET_LD: /opt/homebrew/Cellar/llvm@20/20.1.8/bin/clang++
CHPL_TARGET_ARCH: arm64
CHPL_TARGET_CPU: native *
CHPL_LOCALE_MODEL: flat
CHPL_COMM: none
CHPL_TASKS: qthreads
CHPL_LAUNCHER: none
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_HOST_MEM: jemalloc *
CHPL_HOST_JEMALLOC: system *
CHPL_TARGET_MEM: jemalloc
CHPL_TARGET_JEMALLOC: bundled
CHPL_ATOMICS: cstdlib
CHPL_GMP: system *
CHPL_HWLOC: system *
CHPL_RE2: bundled *
CHPL_LLVM: system
CHPL_LLVM_SUPPORT: system
CHPL_LLVM_CONFIG: /opt/homebrew/opt/llvm@20/bin/llvm-config
CHPL_LLVM_VERSION: 20
CHPL_AUX_FILESYS: none
CHPL_LIB_PIC: none
CHPL_SANITIZE: none
CHPL_SANITIZE_EXE: none
What seems to be happening is that addr1, addr2, and addr3 are all c pointers to wide pointers, but addr3 is not properly initialized
The generated C seems to point to the issues
_owned_MyClass_chpl myOwned_chpl;
chpl____wide_MyClass myBorrow_chpl = {CHPL_LOCALEID_T_INIT, NULL};
MyClass_chpl myUnmanaged_chpl = NULL;
// ...
_ref__owned_MyClass_chpl i_x_chpl = &myOwned_chpl;
c_ptr__owned_MyClass_chpl addr1_chpl = c_pointer_return(i_x_chpl);
_ref__wide_MyClass_chpl i_x_chpl2 = &myBorrow_chpl;
c_ptr_MyClass_chpl addr2_chpl = c_pointer_return(i_x_chpl2);
_ref_MyClass_chpl i_x_chpl3 = &myUnmanaged_chpl;
c_ptr_MyClass_chpl2 addr3_chpl = c_pointer_return(i_x_chpl3);
c_ptr_MyClass_chpl2 and c_ptr_MyClass_chpl are both C pointers to wide pointers, but MyClass_chpl is a C pointer to a struct. And c_pointer_return is basically just a cast to void*. So we are trying to treat a regular pointer as a wide pointer, which results in the crash.