Ann: SWI-Prolog 10.1.3

Dear SWI-Prolog user,

SWI-Prolog 10.1.3 is ready for download. This is a maintenance
release. All changes are merged into the stable version. If this
version does not show any major problems it will be used as the basis
for the stable version 10.0.1. Highlights:

  • @EricGT worked hard to getting a clean build that passes all tests
    using the Microsoft Visual C (MSVC) compiler. That is the majority
    of the patches. Of course most are MSVC oddities, but as usual such
    efforts did reveal some real issues:
    • Bignum memory management could crash.
    • Two issues in tabling that could cause crashes, notably for
      subsumptive tabling.
    • Broken work-around for non-standard MS snprintf() could cause
      non-terminated output.
    • Portable and safe solution for Snowball stemmer cleanup of
      thread-specific data.
  • @brebs raised some portability issues for 32-bit (Alpine) platforms.
    This fixes broken clause/record handles due to reading uninitialized
    (padding) data in a struct. Also drop building XPCE as XPCE 7 no
    longer supports 32 bit platforms.
  • Platform binary dependency updates. This updates the shared objects
    or DLLs for bundled 3rd party libraries. Notable OpenSSL for recent
    security issues and SDL3 from 3.2.6 to 3.4.0.
  • Fixed XPCE 3d boxes geometry and re-added support for rounded corners
    on 3d boxes. This notably makes the scrollbars render again as
    intended.
  • Lots of type cleanup, notably further conversion to modern C bool
    and more usages of enum types instead of int to clarify interface
    expectations.

Please test, notably if you are relying on the stable versions as this
is the 10.0.1 candidate
.

Enjoy --- Jan	

SWI-Prolog Changelog since version 10.1.2

  • CLEANUP: Avoid unreferenced variable warning for MSVC

  • BUILD: MSVC Sanitize build

  • TEST: Windows pipe test by using absolute batch file path The pipe:cat1
    test was failing because the batch file path was relative. cmd /c
    couldn’t find pltest-XXXX.bat. Fixed using absolute_file_name/2.

  • BUILD: Use proper CMake dependencies for building the INDEX.pl
    files Since we no longer merge the package library files with the
    main library and since CMake has evolved, we can get rid of the ugly
    “run always” approach to building the INDEX.pl files and create
    a proper custom rule with the proper dependencies.

  • FIXED: Hashing over uninitialized memory on 32-bit systems. On 32-bit
    systems, clause references are created in part from unitialized memory.
    This leads to crashes in atom-gc for clause references.

  • TEST: Add alternative bitint term hash for 32 bit engines.

  • PORT: Remove /D_DEBUG and /DO_DEBUG from MSVC Sanitize build flags
    MSVC AddressSanitizer requires the release CRT (/MD), but /D_DEBUG
    causes the STL to reference debug-CRT symbols (_CrtDbgReport) and
    makes Python headers demand python3XX_d.lib.

  • PORT: MSVC debug build CRT mismatch for plugins

  • PORT: MSVC debug build: variadic macros and PRETTY_FUNCTION

  • PORT: Set CMAKE_MSVC_RUNTIME_LIBRARY globally for MSVC builds

  • PORT: Fix MSVC C4334 warning in pl-buffer.c

  • PORT: Drop xpce on < 64 bit platforms.

  • BUILD: Extend build_home.pl to support multi-config generators There
    was specific code to support Microsoft Visual Studio. This patch
    supports multi-config generators on platforms that leave the modules
    in the package directories such as ninja -G "Ninja Multi-Config"

  • PORT: Avoid undefined ms_snprintf() and renamed to c99_snprintf().

  • PORT: Add /EHsc to MAKE_CXX_FLAGS for MSVC. Thanks to Eric Tauber.

  • CLEANUP: Avoid implict enum conversion warnings. Based on #1445 by
    Eric Tauber.

  • FIXED: Make PL_query(PL_QUERY_HALTING) return true inside atexit()
    handlers. This addresses the cleanup in package nlp cleanup issues.

  • PORT: Make exit() work properly in Windows with Asan and Debug enabled.
    Thanks to Eric Tauber.

  • PORT: Avoid calling sleep() after Lsan detects a leak.

  • PORT: Updated scripts/macos-deps.h for SDL3 Updated version and build
    instructions for building a universal binary.

  • ADDED: check_installation/0: report OpenSSL version

  • PORT: Exclude LeakSanitizer code on Windows (MSVC ASan lacks LSan
    support)

  • FIXED: Bignum allocation issues. This may lead to memory corruption
    on LibBF as well as using GMP on arithmetic errors. Found by Eric
    Taucher while debugging the MSVC compiled version.

  • FIXED: Tabling with attributed variables: memory management. Make sure
    avm in trie_lookup_abstract() never points below the allocated
    buffer. It is not clear to me whether that is strictly necessary,
    but MSYS-2 using clang and Asan suggests it is. I do not understand
    why this is not reported using Asan under Linux. Surely this prevents
    reading below the buffer, causing a SEGV if it is tried anyway.

  • TEST: term_hash/2 for indirect data types (bigints, floats) term_hash/2
    is platform dependent as it hashes the binary representations of
    indirect types (big int, rational, float). The test succeeds if
    the produced hash is one of a set. When using LibBF, the hash also
    depends on whether the limb size is 32 bits or 64 bits. The C
    compiler must support a twice as wide integer type, i.e., the choice
    depends on HAVE_INT128.

  • FIXED: term_hash/2: exception when exhausting memory. Also cleanup
    types.

  • CLEANUP: Avoid reading uninitialized local variable. Not entirely sure
    why the popSegStack() can fail. Surely it does on the XSB tests from
    tests/xsb/sub_tests/xsb_test_sub.pl. In debug mode we set dstate
    such that accessing it crashes. This seems not to be the case.

  • FIXED: Windows: ms_snprintf null-termination bug for edge case

  • PORT: Ensure default 4Mb C-stack on Windows Otherwise the default is
    2Mb for MinGW and 1Mb for MSVC

  • FIXED: When specified, also set the C-stack limit for swipl-win

  • PORT: Compile MacOSX bundle using gcc. This provides about 40%
    performance improvement.

  • PORT: Support CMake < 3.24 Using CMake < 3.24 the build was broken due
    to the usage of cmake -E env ... -- ... We now omit that for older
    cmake version. This implies that building in e.g build.gcc=14
    does not work for these versions.

Package clib

  • CLEANUP: Bool types and avoid conversion warnings for Windows

  • PORT: Ensure ssize_t is defined when using MSVC

Package http

  • BUILD: Add zlib to doc generation dependencies

Package nlp

  • FIXED: Crash during cleanup on Windows This patch replaces the
    pthread specific handling of the thread specific stemmers with
    __thread__ and using Prolog’s ``PL_thread_at_exit’’ to clean
    stemmers for terminated threads.

    This is a safe solution that also avoids the need for platform
    specific code.

Package xpce

  • FIXED: undefined Dprintf and _T symbols in terminal.c debug code

  • FIXED: MSVC C4319 warning and potential bug in
    clearDFlagProgramObject() Cast mask to uintptr_t before applying
    bitwise NOT. Without this, ~mask produces a 32-bit result on Win64
    (unsigned long is 32 bits) that gets zero-extended to 64-bit uintptr_t,
    incorrectly clearing the upper 32 bits of dflags.

  • CLEANUP: Remove old deprecated usage of SunOS on_exit()

  • ADDED: implementation for 3d rounded corners box r_3d_box()

  • ENHANCED: 3d effect rendering. Notably makes scrollbars look better.

  • PORT: Support MSVC

  • FIXED: GUI Tracer: remove non-functioning Help menu entries. Links to
    the manual and notably xpce manual seem unnecessary. Also removed
    the About as it is all part of the integrated Prolog IDE tools.

  • ADDED: PceEmacs: associate emacs_<mode>_mode module with mode.
    And define style/2 and def_style/2 for style mapping. This is used
    by the experimental LSP client and should be used by the other modes,
    notably the Prolog mode.

1 Like

Thank you.

This was a team effort and would not have been possible without your help and patience.

I appreciate it.

Good news - this is compiling successfully in Alpine Linux, for all arches (with XPCE disabled for 32-bit):

aarch64
armhf
armv7
loongarch64
ppc64le
riscv64
s390x
x86
x86_64

2 Likes

Great! There are actually two problems caused by changing types to bool internally: a possible crash while exhausting the stacks during tabling and dicts that can now have duplicate keys. Both are resolved and will be merged into 10.0.1 (stable)

1 Like

Getting a continuous stream of

Confirmer running; discarding input ...failed

messages on stdout when using the debugger. There on the last release as well.

That happens if the debugger runs in the same thread as the console. Whether or not that happens depends on the Prolog version and platform. The best debugging experience is using swipl-win (the GUI app). As of version 10, that runs the GUI in the process main thread (as demanded by the SDL graphics library on most platforms) and your Prolog console in a separate thread. The nice thing is that you can split the console, so you have one for running your query to debug and another for listing/1, edit/1, make/0, etc. or to run some other tests while the GUI debugger waits for you.

Note that if you started the debugger in swipl you have this problem. However, you can start a second console using the break button (bound to capital B). It is connected to a very bad ( :frowning: ) icon around the middle. image

2 Likes

The heart is for the icon.

1 Like

I’m starting the debugger using --gspy=foo:bar/3 on the command line as it’s a #! script. I’ve commented out the spewage in the C source, I’m not really sure why it’s there in the first place, or if it is there, why there isn’t a flag to shut it up.

I tried something simple to reproduce without luck. Can you share a short demo program and tell how you use it and what happens?

It doesn’t always happen, it seems to be triggered if you gspy something, hit the breakpoint and step through the code in the debugger. It’s not necessarily the first step op that triggers it, perhaps when the target does some IO? Dunno.

I’ll add it to my “try to reproduce” list. If only work would get out of the way… :wink:

I suspect that, but my trivial example worked fine. Inside swipl, the main thread reads from stdin (user_input in Prolog) and at the same time listens for SDL3 (GUI) events. I.e., the GUI events are processed as interrupts during reading. This can lead to some potential deadlock situations. When these threaten it discards the input and prints this message. At least, that is how it is in my memory … Surely it is related to the interaction of the GUI and I/O (well, only input).

1 Like

There seems to be a bug reloading foreign libs:

Welcome to SWI-Prolog (threaded, 64 bits, version 10.1.3-15-g39f600e7d)
[...]
154 ?- reload_foreign_libraries.
ERROR: Type error: `list' expected, found `install_libedit4pl' (an atom)
ERROR: In:
ERROR:   [15] throw(error(type_error(list,install_libedit4pl),context(...,_19824)))
ERROR:   [13] shlib:reload_libraries([lib(...,install_libedit4pl,editline)]) at /tmp/swipl-devel/b.pgo-native/home/library/shlib.pl:535
ERROR:   [11] toplevel_call(user:user:reload_foreign_libraries) at /tmp/swipl-devel/b.pgo-native/home/boot/toplevel.pl:1520
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

Thanks. Fixed. It is not very relevant though. use_foreign_library/1,2 registers an initialization handler that should take care of reinstalling the library after loading a saved state. Possibly this predicate should simply be removed.

1 Like

Thanks, I think it can be quite useful, I was trying to use it much like I use make/0, but for foreign C interfaces which compile to a shared lib. Otherwise I have to restart swipl to load the new version of the shared lib. I tried unload_foreign_library/1 but it silently failed.

AFAIK it does not reload the already loaded library. It reloads the libraries as they were attached before a saved state is created. I.e., creating a saved state saves the registration of which foreign libraries are loaded. After restoring the Prolog code reload_foreign_libraries/0 was used to reload the foreign libraries. That is now done as a result of the initialization/1 directives generated from use_foreign_library/1.