Interoperability: argv*[]

Hello,

I need to pass an argument corresponding to C’s argv* from chapel to C. In my chapel code I have this:

extern proc plot(argc: c_int, argv: c_ptr(c_ptr(c_char)), x: [] c_double, y: [] c_double, xmin: c_double, xmax: c_double, ymin: c_double, ymax: c_double, size: c_int);

and call it like this:

var argc: int(32);
  var argv: [0..5,0..10] c_ptr(c_ptr(c_char));

The code does not compile.

chpl -o chpl_driver plot.o main.chpl -L/usr/local/lib -lplplot
main.chpl:6: error: Could not find C function for plot;  perhaps it is missing or is a macro?
gmake: *** [Makefile:13: chpl_driver] Error 1

I’m not certain, but I think the problem may be that the function prototype, which matches the call from chapel, does not match the function implementation:

int
plot( int argc, char *argv[], PLFLT *x, PLFLT *y, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, int NSIZE )
{
    // Parse and process command line arguments
    plparseopts( &argc, argv, PL_PARSE_FULL );

    // Initialize plplot
    plinit();

    // Create a labelled box to hold the plot.
    plenv( xmin, xmax, ymin, ymax, 0, 0 );
    pllab( "x", "y=100 x#u2#d", "Simple PLplot demo of a 2D line plot" );

    // Plot the data that was prepared above.
    plline( NSIZE, x, y );

    // Close PLplot library
    plend();

    return 0;
}

I have not tried interoperating with C before and would appreciate a bit of hand-holding.

Thanks,

Roger

Correction: here is the call from chapel.

 plot(argc, argv, x, y, xmin, xmax, ymin, ymax, n);

I believe the problem is that you are missing a C header file.

If you add

// in plot.h
#include "plplot/plplot.h"
int
plot( int argc, char *argv[], PLFLT *x, PLFLT *y, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, int NSIZE );

And then compile as chpl -o chpl_driver plot.h plot.o main.chpl -L/usr/local/lib -lplplot, does that fix the problem?

I'll also caution you about var argv: [0..5,0..10] c_ptr(c_ptr(c_char));, as that doesn't look quite right. Thats a 2D array of char**, which you are passing to a char**.

-Jade

Thank you.

Progress: I get a core dump:

*** NOTICE (proc 0): We recommend linking the debug version of GASNet to assist you in resolving this application issue.
[0] Invoking GDB for backtrace...
[0] GDB backtrace failed! (0x00000100:256)
[0] Invoking LLDB for backtrace...
[0] /usr/bin/lldb -p 3943 -o 'bt all' -o quit
[0] (lldb) process attach --pid 3943
zsh: segmentation fault (core dumped) ./chpl_driver -nl 1

How do I build a debug version of gasnet?

Thanks,

Roger

If you are just running locally and don't need multiple locales (which based on that error looks like the case), I recommend just building with a single locale version of Chapel instead of the gasnet one. That will be much easier to debug.

-Jade

1 Like

Hi Roger —

I'm closing tabs and wanted to second Jade's recommendation. Though it's possible to create a debug version of GASNet, for a core dump in a C interop scenario involving pointers like this, the fastest path to debugging is to:

  • create a CHPL_COMM=none build of the runtime if you don't already have one (note that this can happily co-exist with a CHPL_COMM=gasnet build)
  • re-compile your program with CHPL_COMM=none or --comm=none and -g (and --debug if using a pre-release of Chapel 2.7).
  • run the program within gdb or lldb, optionally using the --lldb or --gdb flags

Specifically, I'm guessing that the core dump is within the C code itself and hope that the single-locale run within gdb/lldb will quickly make the cause apparent (assuming you have a debug version of the C routine anyway?)

-Brad

Thank you Jade and Brad, the missing header was indeed the problem. The tip on diabling gasnet was most helpful. I have another question for which I'll start a new thread.

Thanks again,
Roger