Exception in foreign c++ code

Dear experts,

This is my C++ code (linux, compile with swipl-ld -o foreign foreign.cpp):

#include "SWI-cpp.h"
#include <iostream>

// foreign function that just throws an exception
static foreign_t my_fn(PlTermv args, int arity, void* context)
{
    throw PlException(PlCompound("exception: my_fn:", args)) ;
}

int main(int argc, char** argv)
{
    PL_register_foreign("my_fn", 2, (void*) my_fn, PL_FA_VARARGS) ;
    PlEngine e(argc, argv) ;

    // First attempt
    {
        PlTermv args(2) ;
        PlQuery q("my_fn", args) ;
        try
        {
            if(q.next_solution())
                std::cout << (char*) args[0] << " " << (char*) args[1] << std::endl ;
            else
                std::cout << "Query failed" << std::endl ;
        }
        catch(PlException& ex)
        {
            std::cout << (char*) ex << std::endl ;
        }
    }

    // Second attempt
    {
        PlTermv args(2) ;
        PlQuery q("my_fn", args) ;
        try
        {
            if(q.next_solution())
                std::cout << (char*) args[0] << " " << (char*) args[1] << std::endl ;
            else
                std::cout << "Query failed" << std::endl ;
        }
        catch(PlException& ex)
        {
            std::cout << (char*) ex << std::endl ;
        }
    }

    return 0 ;
}

When I run this little program, the first exception is correctly printed. Thereafter, the program crashes. Do I need to clear the query in some way? In my opinion, the destructor of the query should be invoked, or shouldn’t it?

matthias@DESKTOP-A2T8IFC:~/embedded$ ./foreign
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.29-44-ga44539678)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

'exception: my_fn:'(_5304,_5306)
[Thread 1 (main) at Thu Sep 30 20:23:06 2021] /home/matthias/swipl-devel/src/pl-wam.c:2573: PL_open_query: Assertion failed: (Word)lTop >= refFliP(fli_context, fli_context->size)
C-stack trace labeled "assert_fail":
  [0] save_backtrace() at /home/matthias/swipl-devel/src/os/pl-cstack.c:333 [0x7feb6b150365]
  [1] __assert_fail() at /home/matthias/swipl-devel/src/pl-assert.c:103 [0x7feb6b0f0afa]
  [2] PL_open_query() at /home/matthias/swipl-devel/src/pl-wam.c:2572 (discriminator 1) [0x7feb6b04541c]
  [3] ./foreign(+0x30cd) [0x5634e87030cd]
  [4] ./foreign(+0x2828) [0x5634e8702828]
  [5] __libc_start_main() at ??:? [0x7feb6ac11565]
  [6] ./foreign(+0x254e) [0x5634e870254e]
Aborted
matthias@DESKTOP-A2T8IFC:~/embedded$

Inserting a PlFrame solved the problem.

https://www.swi-prolog.org/pldoc/man?section=cpp-plquery#class:PlFrame

1 Like