[m-users.] Segmentation violation on FFI wrapper for linenoise-ng

Julien Fischer jfischer at opturion.com
Sat Jun 19 22:31:18 AEST 2021


Hi Sean,

On Sat, 19 Jun 2021, Sean Charles (emacstheviking) wrote:

> It all works beautifully, as expected but when I use CTRL-D it balks with this output:
> *** Mercury runtime: caught segmentation violation ***
> cause: address not mapped to object
> address involved: 0x0
> This may have been caused by a stack overflow, due to unbounded recursion.
> exiting from signal handler
> [1]    68417 segmentation fault  ./felt -r
> 
> I have attached the full FFI code at the end. I’ve tried to work it through. The source code for the input function is here:
> 
> I studied the source code, it is using fgets() which returns NULL on end-of-file and I thought I was managing that just fine!
> Does Mercury have something to with this e.g. a SIGINT handler or something that might be clashing with the linenoise-ng code I wonder ?
> 
> The calling code in my REPL loop is as follows:
> 
> :- pred run_loop(
>     command_line.felt_options::in,
>     replcon::in, replcon::out,
>     io::di, io::uo) is det.
> 
> run_loop(Options, !Repl, !IO) :-
>     ln_read(prompt, Line, LineNull, !IO),
>     io.format("LNG: NULL:%d, len:%d, \n", [i(LineNull), i(length(Line))], !IO),

Ok, so we are doing stuff with the variable Line here ...

>     (if LineNull = 1 then
>         io.format("\n%sBe excellent to one another.\n",
>              [s(prompt)], !IO)
>     else
>         execute(Line, !Repl, !IO),
>         run_loop(Options, !Repl, !IO)
>     ).

...

> :- pred ln_setup(string::in, int::in, io::di, io::uo) is det.
> :- pred ln_shutdown(string::in, io::di, io::uo) is det.
> :- pred ln_read(string::in, string::out, int::out, io::di, io::uo) is det.
> :- pred ln_free(string::in, io::di, io::uo) is det.
> 
>     % ln_read: Reads and returns a single line.
>     % Line is unified with whataver the library read from stdin.
>     % LineNull is unified with 1 if NULL(CTRL+D) is detected, else 0.
>     % If the line is not empty then we automatically add it to the history.
>     %
> :- pragma foreign_proc(
>     "C",
>     ln_read(Prompt::in, Line::out, LineNull::out, IOin::di, IOout::uo),
>     [will_not_throw_exception, promise_pure],
>     "
>     char* line = linenoise((const char*)Prompt);
>     if (line) {
>         linenoiseHistoryAdd(line);
>         LineNull = 0;
>         Line = line;

... which is set to a value in this branch , but ...

>     } else {
>         LineNull = 1;

... not in this one.


>     }
>     printf(\"leaving, strlen() is %d\\n\", strlen(line));
>     IOout = IOin;
>     "

I'm not familiar with the linenoise library, but I am assuming that the
function linenoise() returns NULL on EOF?

Julien.


More information about the users mailing list