Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault when cython generated code calls Fortran library executing a WRITE(*,FMT_STR) statement #3436

Open
fjdu opened this issue Mar 16, 2020 · 0 comments

Comments

@fjdu
Copy link

@fjdu fjdu commented Mar 16, 2020

While trying to wrap some Fortran code into Python with Cython, I found that the WRITE statement of Fortran can cause the generated Python module to crash (segmentation fault).

To be precise, the WRITE statemen only causes crash if it contains a format string. Without a format string it won't crash. Namely, WRITE(*,*) "xxx" does not crash but WRITE(*,"(A)") "xxx" does. When called by a normal Fortran or C++ procedure, the related Fortran subroutine works as expected and there is no crash.

The following is an example. It contains three files:

    1. fortran_write.f90
    2. testwrite.pyx
    3. setup.py

File fortran_write.f90:

module mod_write
use, intrinsic :: ISO_C_BINDING
implicit none

contains

subroutine fwrite(flag) bind(C, name="write_f")
    integer*4, intent(in) :: flag
    write(*, *) "In fwrite: flag=", flag
    if (flag .eq. 0) then
      write(*, *) "Message from fwrite (write_f)."
    else if (flag .eq. 1) then
      write(*, *) "MSG", 1234, 12.34
    else if (flag .eq. 2) then
      write(*, "(A40)") "Message from fwrite (write_f)."
    else if (flag .eq. 3) then
      write(*, "(I6)") 1234
    else if (flag .eq. 4) then
      write(*, "(F6.2)") 12.34
    end if
end subroutine fwrite
end module mod_write

File testwrite.pyx:

# distutils: language = c++

cdef extern:
  void write_f(int* flag)

cdef writef(flag):
  cdef int f;
  f = flag
  write_f(&f)

def run():
  writef(0)
  writef(1)
  writef(2)
  writef(3)
  writef(4)

File setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

extension = Extension(
    name="testwrite",
    sources=["testwrite.pyx"],
    libraries=["testwrite", "gfortran"],
    library_dirs=["./", "/usr/local/Cellar/gcc/9.2.0_1/lib/gcc/9/"],
    include_dirs=["./"],
    depends=['fortran_write.f90'],
    extra_compile_args=["-std=c++11"])

setup(
    name="testwrite",
    ext_modules=cythonize([extension], language_level="3")
)

Compile procedure:

gfortran -c fortran_write.f90
ar rcs libtestwrite.a fortran_write.o
python setup.py build_ext --inplace

Test procedure:

python -c "import testwrite;testwrite.run()"

Output:

 In fwrite: flag=           0
 Message from fwrite (write_f).
 In fwrite: flag=           1
 MSG        1234   12.3400002
 In fwrite: flag=           2
[1]    7631 segmentation fault  python -c "import testwrite;testwrite.run()"

Expected output:

In fwrite: flag=           0
 Message from fwrite (write_f).
 In fwrite: flag=           1
 MSG        1234   12.3400002
 In fwrite: flag=           2
          Message from fwrite (write_f).
 In fwrite: flag=           3
  1234
 In fwrite: flag=           4
 12.34

By the way, f2py works fine.

Compile procedure:

f2py -c -m testwrite fortran_write.f90

Test procedure:

python -c "import testwrite;testwrite.mod_write.fwrite(2)"

System information

macOS Version 10.15.3

gfortran -v:

Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/9.2.0_1/libexec/gcc/x86_64-apple-darwin18/9.2.0/lto-wrapper
Target: x86_64-apple-darwin18
Configured with: ../configure --build=x86_64-apple-darwin18 --prefix=/usr/local/Cellar/gcc/9.2.0_1 --libdir=/usr/local/Cellar/gcc/9.2.0_1/lib/gcc/9 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-9 --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-system-zlib --with-pkgversion='Homebrew GCC 9.2.0_1' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
Thread model: posix
gcc version 9.2.0 (Homebrew GCC 9.2.0_1)

g++ -v:

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.0 (clang-1100.0.33.16)
Target: x86_64-apple-darwin19.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

cython --version
Cython version 0.29.14

python --version:
Python 3.7.4

f2py version 2


I posted the same question at https://stackoverflow.com/questions/60693732/cython-segmentation-fault-when-calling-fortran-library-with-a-write-fmt-str-s but have not got any answer yet.

@fjdu fjdu changed the title Cython segmentation fault when calling Fortran library with a WRITE(*,FMT_STR) statement Segmentation fault when cython generated code calls Fortran library executing a WRITE(*,FMT_STR) statement Mar 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.