I am happy to announce SWI-Prolog 8.1.23. Where 8.1.22 suffered from
some regression (as expected), we are probably close to the stability
you are used to with this version.
Highlights:
Fixed building in or adjacent to the source directory (blocked building
in e.g. Macports).
Fixed a compiling module:Goal (bound module, unbound Goal)
causing possible early garbage collection of the atom module.
Fixed possible memory leak in GMP arithmetic that causes exceptions.
A lot of progress on rational and IEEE 754 float support. Thanks to
Rick Workman and issues reported by Jan Burse. See below for details.
Several patches to enable building of the core cleanly using MSVC by
Röbke Geenen.
Enjoy — Jan
SWI-Prolog Changelog since version 8.1.22
FIXED: rationalize/1 for handling subnormal floats.
FIXED: MPQ to double conversion near the end of the float range.
FIXED: round/1, ceil/1, floor/1, truncate/1 functions on special
floats. Some of these could crash (SIGFPE).
FIXED: Avoid FPE on rational(inf). Jan Burse.
TEST: UTF-8 library.
FIXED: print_term/2: could output ‘$VAR’(N) terms instead of the
variable.
PORT: Better handling of memory barriers. After discussion with
Röbke Geenen.
FIXED: MemoryBarrier under MSVC for 32-bit targets is an inline
function instead of a #define
ENHANCED: Allow for nested print_message/2, only preventing real
unbounded recursion.
ADDED: Prolog flags float_min and float_max and float_max_integer.
ENHANCED: Use ECLiPSe MPQ functions for rationalize/1 and converting
a rational number into a float. This implementation has much better
properties than our old implementation.
DOC: roundtoward/2 function.
ADDED: Compiler/VM support for roundtoward/2. This patch also reverses
the order in which function arguments are evakuated from left-to-right
to right-to-left. This order was already used for non-optimized
arithmetic. This should have no consequences except for the raised
exceptions if a function has multiple invalid arguments. For example,
in A is 1/0 + 2/0 the exception now originates from 2/0.
ADDED: roundtoward/2 function.
FIXED: Memory leak on exception during GMP arithmetic in optimized
mode.
ENHANCED: Further implementation of IEEE 754 support by Rick
Workman. The MODIFIED the float rounding mode nearest into to_nearest. The name nearest was an oversight. SWI-Prolog now has
only a single NaN value, which implies NaN is equal in term comparison.
The patches mostly fix returning NaN, Inf and -0.0 where appropriate
from many of the built-in functions.
FIXED: Debug statement in pl-tabling.c which depended on
multi-threading being enabled without checking if multi-threading
is enabled.
FIXED: Use the lock/unlock code for streams also in the single
threaded version as this ensures current write to wchar_t encoded
streams. Issue#551, Röbke Geenen
FIXED: swipl-win.exe (Windows): padding to TCHAR. Röbke Geenen.
FIXED: SWIPL_SHARED_LIB=OFF, MULTI_THREADED=OFF: C_CFLAGS being
undefined when empty
MSVC: Fixed LNK1114 error when building libswipl statically
FIXED: Missing PL_register_atom() when compiling module:X. Can lead
to the atom module to be garbage collected or its reference count
dropping below zero.
PORT: Windows: Do not include manifest when building with MSVC, since
it causes a duplicate resource error. Also uses a textual manifest
for the MinGW compilation rather than a binary blob.
FIXED: Load library(dialect/swi/syspred_options)) explicitly to
have PceEmacs colour (in)valid predicate options. Loading was lost
with the migration to autoloading.
FIXED: print_term/2: add a spaces in X + -1.
FIXED: print_term/2: avoid quoting solo operators such as ‘,’.
FIXED: Respect float_round flag when converting from GMP numbers
to floats for to_positive and to_negative modes.
TEST: IEEE 754 float handling by Rick Workman
FIXED: atom_number/2 in mode (-,+)
FIXED: Getting the local build home directory if not installed in a
subdir of the source.
FIXED: Missing () around record can cause syntax errors if
library(record) is loaded first.
FIXED: print_term/2: handle spacing for postfix operators.
FIXED: 1.5NaN is before all numbers in the standard order of terms,
also before the integers.
FIXED: Arithmetic comparison to NaN should always fail.
ADDED: float_class/2 to classify the various non-normal IEEE 754
float values.
ADDED: library(sandbox): allow access to various new flags.
DOC: float_rounding flag was undocumented.
Package pengines
FIXED: term//2 (term --> HTML) to add a spaces in X + -1.
FIXED: term//1 (term to HTML): respect rational_syntax flag of
the module.
I reproduced the test failure with a clean build – deleted subdir build and ran cd build && cmake -G Ninja .. && ninja && ctest -j 8
at commit 0bb026a6a11e8102db3a5be2906110fa13f6df3e (HEAD -> master, origin/master, origin/HEAD)
Which platform(s)? Nothing relevant should be changed and all tests passed on the various machines I tried as well as the Ubuntu PPAs on all Ubuntu versions … Can one of you get a stack trace? I normally use the environment variable CTEST_OUTPUT_ON_FAILURE=y which prints the full output on failures.
That seems interesting enough to try and track down. Looks like I forgot some declaration to guide the garbage collector on one of the recently added VM instructions. Hope I can find it by just examining the code or I can somehow reproduce it. Thanks!
My assumption was correct. It remains a bit weird that this appears on some platforms and not on others. One of the few things that differs is the absolute location of the sources. Possibly path computations cause GC to be scheduled a little different due to that.
Anyway, I spotted the omission which allowed me to create a test program to reproduce the issue by calling garbage_collect/0 explicitly at the suspect location, resulting in the same backtrace. Pushed a fix, including a new test.
diff --git a/src/pl-gc.c b/src/pl-gc.c
index 0daedad1c..494b681d5 100644
--- a/src/pl-gc.c
+++ b/src/pl-gc.c
@@ -1854,11 +1854,14 @@ walk_and_mark(walk_state *state, Code PC, code end ARG_LD)
/* dynamically sized objects */
case H_STRING: /* only skip the size of the */
case H_MPZ:
+ case H_MPQ:
mark_argp(state PASS_LD);
/*FALLTHROUGH*/
case B_STRING: /* string + header */
case A_MPZ:
case B_MPZ:
+ case A_MPQ:
+ case B_MPQ:
{ word m = *PC;
PC += wsizeofInd(m)+1;
assert(codeTable[op].arguments == VM_DYNARGC);
Its a rather simple oversight. To most of the VM, MPQ numbers are much the same as MPZ numbers. New instructions need support in a couple of places (VM, compiler, decompiler and GC), so you typically search for existing ones that play a similar role. I missed to check a file
Confirmed: I’ve rebuilt on my system and all tests pass. commit 6357cafc0b82fc5439320e66143d6aa8d69ef319 Linux 5.0.0-36-generic #39~18.04.1-Ubuntu SMP Tue Nov 12 11:09:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux