# Passing closures results in a segfault on Apple Silicon

**URL:** <https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096>\
**Category:** Uncategorized\
**Created:** [May 27, 2024, 11:09pm UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096 "2024-05-27T23:09:55Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![actinium226](https://avatars.discourse-cdn.com/v4/letter/a/46a35a/32.png) [@actinium226](https://fortran-lang.discourse.group/u/actinium226)\
**Post date:** [May 27, 2024, 11:09pm UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/1 "2024-05-27T23:09:55Z")

</div>

I have a program that has been working fine for me until I got this new Macbook with Apple Silicon. I’ve been able to make a small reproducible build with two files:

```auto
! main.f90
program main
  use mymodule, only : mysub
  real :: x
  x = 5.0
  print *, "Calling closure from the module in which it is defined:"
  call closure()
  print *, "Calling closure from another module:"
  call mysub(closure)

contains

subroutine closure()
    print *, x+1
end subroutine

end program main

```

```auto
! mymodule.f90
module mymodule

abstract interface
  subroutine OBJ()
  end subroutine OBJ
end interface

contains

subroutine mysub(closure)
  procedure(OBJ) :: closure
  call closure()
end subroutine

end module mymodule

```

I compile it as follows:

```auto
gfortran -c mymodule.f90
gfortran main.f90 mymodule.o

```

When I run it on Apple Silicon (with gfortran 13.2.0) I get `Segmentation fault: 11`.

If I try the same compilation commands inside a docker container (either with or without `--platform linux/amd64`) the program runs successfully. Interestingly, compiling it within docker gives a warning about requiring an executable stack - the same warning does _not_ appear on Apple Silicon.

I’m not sure what to do to investigate this further, can anyone help?

Update: This was able to compile with nagfor. Should I submit this as a bug to gcc in that case?

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 28, 2024, 2:14am UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/2 "2024-05-28T02:14:12Z")

</div>

I put all the code in a single file, and it works alright with both gfortran 14.1.0 and nagfor 7.2 on MacOS 12.7.5.

---

<div class="post-metadata">

**Author:** ![actinium226](https://avatars.discourse-cdn.com/v4/letter/a/46a35a/32.png) [@actinium226](https://fortran-lang.discourse.group/u/actinium226)\
**Post date:** [May 28, 2024, 2:35am UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/3 "2024-05-28T02:35:27Z")

</div>

Thanks for taking a look @RonShepard . Can you confirm that you’re on Apple Silicon? And did it segfault for you if it was two files?

I’m on macOS 14.5, and even when putting everything in one file it still segfaults on me.

---

<div class="post-metadata">

**Author:** ![mhulsen](https://avatars.discourse-cdn.com/v4/letter/m/ea666f/32.png) [@mhulsen](https://fortran-lang.discourse.group/u/mhulsen)\
**Post date:** [May 28, 2024, 6:20am UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/4 "2024-05-28T06:20:16Z")

</div>

No problems for me. One file and with two files. I am on Apple Silicon. macOS 14.5, gfortran 14.1.0.

---

<div class="post-metadata">

**Author:** ![wspector](https://avatars.discourse-cdn.com/v4/letter/w/47e85d/32.png) [@wspector](https://fortran-lang.discourse.group/u/wspector)\
**Post date:** [May 28, 2024, 2:53pm UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/5 "2024-05-28T14:53:57Z")

</div>

Also works fine for my with gfortran (some 14.0.1 snapshot). But running linux on x86\_64.

Technically not a closure though. Passing procedures through argument lists has been around since the 1960s. However creating closures aren’t supported.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [May 28, 2024, 3:16pm UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/6 "2024-05-28T15:16:19Z")

</div>

On macOS Monterey (v12.7.1):

```txt
$ gfortran mymodule.f90 main.f90 
$ ./a.out
 Calling closure from the module in which it is defined:
   6.00000000    
 Calling closure from another module:
   6.00000000    
$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/13.2.0/bin/../libexec/gcc/x86_64-apple-darwin21/13/lto-wrapper
Target: x86_64-apple-darwin21
Configured with: ../configure --prefix=/usr/local/opt/gcc --libdir=/usr/local/opt/gcc/lib/gcc/current --disable-nls --enable-checking=release --with-gcc-major-version-only --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-13 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-zstd=/usr/local/opt/zstd --with-pkgversion='Homebrew GCC 13.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --with-system-zlib --build=x86_64-apple-darwin21 --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Homebrew GCC 13.2.0) 

```

What is your gfortran target triplet? Are you targetting the Arm instruction set or the x86\_64 emulation? You can also check the type of the executable:

```txt
$ file a.out
a.out: Mach-O 64-bit executable x86_64

```

AFAIK, the executable stack is used because many Fortran compilers implement internal procedures using [thunks](https://en.wikipedia.org/wiki/Thunk) (for the interested reader I recommend [Doctor Fortran in “Think, Thank, Thunk”](https://stevelionel.com/drfortran/2009/09/02/doctor-fortran-in-think-thank-thunk/)).

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 28, 2024, 3:37pm UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/7 "2024-05-28T15:37:49Z")

</div>

> [@actinium226](#):
>
> Can you confirm that you’re on Apple Silicon?

Here is the relevant output on a different computer (with a recent OS).

```auto
$ uname -a
Darwin MacStudio.local 23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:49 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6020 arm64
$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/opt/homebrew/Cellar/gcc/14.1.0/bin/../libexec/gcc/aarch64-apple-darwin23/14/lto-wrapper
Target: aarch64-apple-darwin23
Configured with: ../configure --prefix=/opt/homebrew/opt/gcc --libdir=/opt/homebrew/opt/gcc/lib/gcc/current --disable-nls --enable-checking=release --with-gcc-major-version-only --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-14 --with-gmp=/opt/homebrew/opt/gmp --with-mpfr=/opt/homebrew/opt/mpfr --with-mpc=/opt/homebrew/opt/libmpc --with-isl=/opt/homebrew/opt/isl --with-zstd=/opt/homebrew/opt/zstd --with-pkgversion='Homebrew GCC 14.1.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --with-system-zlib --build=aarch64-apple-darwin23 --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.1.0 (Homebrew GCC 14.1.0) 
$ gfortran obj.f90 && a.out
 Calling closure from the module in which it is defined:
   6.00000000    
 Calling closure from another module:
   6.00000000    

```

---

<div class="post-metadata">

**Author:** ![actinium226](https://avatars.discourse-cdn.com/v4/letter/a/46a35a/32.png) [@actinium226](https://fortran-lang.discourse.group/u/actinium226)\
**Post date:** [May 29, 2024, 1:24am UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/8 "2024-05-29T01:24:55Z")

</div>

Thanks everyone for all the input.

I think the problem has to do with where I got gfortran. I installed it via nix. When I uninstalled it and installed the same version from macports, suddenly everything works. If anyone is interested here is the output of `gfortran -v` for each version:

Installed via nix:

```auto
Using built-in specs.
COLLECT_GCC=/nix/store/iq8m4kv876ijdjqwp874vrb8zxfkqi98-gfortran-13.2.0/bin/gfortran
COLLECT_LTO_WRAPPER=/nix/store/iq8m4kv876ijdjqwp874vrb8zxfkqi98-gfortran-13.2.0/libexec/gcc/aarch64-apple-darwin/13.2.0/lto-wrapper
Target: aarch64-apple-darwin
Configured with: ../gcc-13.2.0/configure --prefix=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gfortran-13.2.0 --with-gmp-include=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gmp-with-cxx-6.3.0-dev/include --with-gmp-lib=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gmp-with-cxx-6.3.0/lib --with-mpfr-include=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpfr-4.2.1-dev/include --with-mpfr-lib=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpfr-4.2.1/lib --with-mpc=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-libmpc-1.3.1 --with-native-system-header-dir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-libSystem-11.0.0/include --with-build-sysroot=/ --with-gxx-include-dir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gfortran-13.2.0/include/c++/13.2.0/ --program-prefix= --enable-lto --disable-libstdcxx-pch --without-included-gettext --with-system-zlib --enable-static --enable-languages=fortran,objc,obj-c++ --disable-multilib --enable-plugin --build=aarch64-apple-darwin --host=aarch64-apple-darwin --target=aarch64-apple-darwin
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (GCC)

```

Install via macports:

```auto
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/arm64-apple-darwin23/13.2.0/lto-wrapper
Target: arm64-apple-darwin23
Configured with: /opt/local/var/macports/build/_opt_bblocal_var_buildworker_ports_build_ports_lang_gcc13/gcc13/work/gcc-13.2.0/configure --prefix=/opt/local --build=arm64-apple-darwin23 --enable-languages=c,c++,objc,obj-c++,lto,fortran,jit --libdir=/opt/local/lib/gcc13 --includedir=/opt/local/include/gcc13 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-13 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-13 --with-gxx-include-dir=/opt/local/include/gcc13/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-isl=/opt/local --with-zstd=/opt/local --enable-checking=release --disable-multilib --enable-lto --enable-libstdcxx-time --with-build-config=bootstrap-debug --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld-classic --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --enable-host-shared --with-darwin-extra-rpath=/opt/local/lib/libgcc --with-libiconv-prefix=/opt/local --disable-tls --with-gxx-libcxx-include-dir=/opt/local/libexec/gcc13/libc++/include/c++/v1 --with-pkgversion='MacPorts gcc13 13.2.0_4+stdlib_flag' --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (MacPorts gcc13 13.2.0_4+stdlib_flag)

```

The only major difference that jumps out at me is that the nix Target is `aarch64-apple-darwin` and the one for macports is `arm64-apple-darwin23`, and also the `+stdlib_flag` in macports but I’m not sure that’s so relevant here.

In both cases `file a.out` provides `a.out: Mach-O 64-bit executable arm64`

I’d investigate the nix package, but I’m as yet not very comfortable with their configuration language so I think I’ll leave it here. Once again thanks to all who chimed in.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [May 29, 2024, 2:19am UTC](https://fortran-lang.discourse.group/t/passing-closures-results-in-a-segfault-on-apple-silicon/8096/9 "2024-05-29T02:19:49Z")

</div>

> [@actinium226](#):
>
> The only major difference that jumps out at me is that the nix Target is `aarch64-apple-darwin` and the one for macports is `arm64-apple-darwin23`

According to Wikipedia, [Aarch64](https://en.m.wikipedia.org/wiki/AArch64) and ARM64 refer to the same instruction set. Ironically, it’s no better than the `x86-64`, `x86_64`, `amd64` confusion (not to mention the Itanium, `IA-64`).

> [@actinium226](#):
>
> and also the `+stdlib_flag` in macports but I’m not sure that’s so relevant here.

I’m guessing that refers to whether the compiler supports the `-stdlib=...` flag. (It allows you to select between `libc++` and `libstdc++` libraries), but I’m also not sure if it relevant.
