Skip to content

Potential Issue with 2-D ARGOUTVIEWM Wrapping #17398

Closed
@leakec

Description

@leakec

I am having an issue with 2-D ARGOUTVIEWM wrapping with swig. The code works when using the form (double** ARGOUTVIEWM_ARRAY2, int* DIM1, int* DIM2), but not when using the form (int* DIM1, int* DIM2, double** ARGOUTVIEWM_ARRAY2). Moreover, when using the latter form, the form that causes a seg fault, swig issues a warning:
"warning: cast to pointer from integer of different size." Looking at the wrapped swig code, it appears that the wrong argument is being freed. When using the first form, this issue does not arise. It should also be noted that if ARGOUTVIEW arrays are used rather than ARGOUTVIEWM arrays, this issue also does not arise.

Since this is a swig wrapping issue, I will include the C++ code, swig code, setup file, and test file. After building the code with "python setup.py build" and moving the library from the build folder to the current directly, the test.py file can be used to reproduce the error, i.e. just run "python test.py".

Reproducing code example:

BF.h:

#include <iostream>

#ifndef BF_H
#define BF_H

void getw(double** arrOut, int* dimOut, int* nOut);
void getw2(int* dimOut, int* nOut, double** arrOut);

#endif

BF.cxx:

#include "BF.h"

void getw(double** arrOut, int* dimOut, int* nOut){
	int m=5; int dim=2;
	*arrOut = new double[m*dim];
	for (int k=0;k<m*dim;k++)
		(*arrOut)[k] = 2.;
	*dimOut = dim;
	*nOut = m;
	return;
}

void getw2(int* dimOut, int* nOut, double** arrOut){
	int m=5; int dim=2;
	*arrOut = new double[m*dim];
	for (int k=0;k<m*dim;k++)
		(*arrOut)[k] = 2.;
	*dimOut = dim;
	*nOut = m;
	return;
}

BF.i

// BF.i

%module BF
%{
#define SWIG_FILE_WITH_INIT
#include <iostream>
#include "BF.h"
%}

%include "numpy.i"

%init %{
        import_array();
%}

// Apply typemaps to allow hooks into Python

%apply (double** ARGOUTVIEWM_ARRAY2, int* DIM1, int* DIM2){(double** arrOut, int* dimOut, int* nOut)}; 
%apply (int* DIM1, int* DIM2, double** ARGOUTVIEWM_ARRAY2){(int* dimOut, int* nOut, double** arrOut)}; 

%include "BF.h"

setup.py

#! /usr/bin/env python

# System imports
from distutils.core import *
from distutils      import sysconfig

# Third-party modules - we depend on numpy for everything
import numpy

# Obtain the numpy include directory.  This logic works across numpy versions.
try:
    numpy_include = numpy.get_include()
except AttributeError:
    numpy_include = numpy.get_numpy_include()

# crop extension module
_BF = Extension("_BF",
                   ["BF.i","BF.cxx"],
                   include_dirs = [numpy_include],
                   swig_opts = ['-c++','-py3'],
                   extra_compile_args = ["--verbose"]
                   )

# NumyTypemapTests setup
setup(  name        = "test",
        description = "A simple test to show the use of ARGOUTVIEWM_ARRAY2",
        author      = "foobar",
        version     = "1.0",
        ext_modules = [_BF]
        )

test.py:

import numpy as np
from BF import getw, getw2

print("Running getw")
W = getw()
del W
getw()
getw()
getw()
getw()

print("Running getw2")
W = getw2()
del W
getw2()
getw2()
getw2()
getw2()
getw2()

Error message:

GDB traceback:
#0  __GI___libc_free (mem=0x2) at malloc.c:3102
#1  0x000000000043da3e in ?? ()
#2  0x00007ffff70f05fa in ?? () from /usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-38-x86_64-linux-gnu.so
#3  0x00000000005cc894 in _PyDict_DelItem_KnownHash ()
#4  0x000000000056b042 in _PyEval_EvalFrameDefault ()
#5  0x0000000000565972 in _PyEval_EvalCodeWithName ()
#6  0x0000000000686053 in PyEval_EvalCode ()
#7  0x00000000006753d1 in ?? ()
#8  0x000000000067544f in ?? ()
#9  0x0000000000675507 in PyRun_FileExFlags ()
#10 0x000000000067758a in PyRun_SimpleFileExFlags ()
#11 0x00000000006ae99e in Py_RunMain ()
#12 0x00000000006aed29 in Py_BytesMain ()
#13 0x00007ffff7dd30b3 in __libc_start_main (main=0x4ebd20 <main>, argc=2, argv=0x7fffffffddd8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffddc8) at ../csu/libc-start.c:308
#14 0x00000000005f62ee in _start ()

Terminal printout:
Running getw
Running getw2
Segmentation fault (core dumped)

NumPy/Python version information:

1.17.4 3.8.2 (default, Jul 16 2020, 14:00:26)
[GCC 9.3.0]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions