An error of chez-scheme FFI just like because of C Cross-platform

194 Views Asked by At

There is a c file

#include <stdio.h>
#include <termios.h>


struct termios raw;


int raw_on(void)
{

    if (tcgetattr(0, &raw) == -1)
        return -1;


    raw.c_lflag &= ~ECHO;
    raw.c_lflag &= ~ICANON;
    raw.c_lflag &= ~ISIG;


    // raw.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    // raw.c_oflag &= ~(OPOST);
    // raw.c_cflag |= (CS8);
    // raw.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    // raw.c_cc[VMIN] = 1;
    // raw.c_cc[VTIME] = 0;

    return tcsetattr(0, TCSAFLUSH, &raw);
}

And when I call it in chez-scheme

> (load-shared-object "./emacs.so")
> (foreign-procedure "raw_on"() int)
#<procedure>
> (define raw-on (foreign-procedure "raw_on"() int))
> (raw-on)
Exception: invalid memory reference.  Some debugging context lost
Type (debug) to enter the debugger.

When I search it in internet, I find the termios.h is for POSIX terminal, and my OS is Debian.

May I ask why this bug occurs Thanks in advance.

1

There are 1 best solutions below

0
On

The problem here is that the C function raw_on() you are binding to the Scheme procedure raw-on is accessing a global variable struct termios raw;. The problem (I think) is that these variables are not allocated for position-independent code (PIC) unless you declare them static. Since you must build the .so file using -fPIC and -shared in order for the functions within to be executable by Chez Scheme, you must declare the global variables to be static for these memory locations to exist when load-shared-object is evaluated.

static struct termios raw; // prepend "static" keyword here

int raw_on(void) { ... }

Rebuild:

cc -fPIC -shared -o ./emacs.so emacs.c

After you have rebuilt the emacs.so file, try running your Scheme program again, the "invalid memory reference" failure should be gone.