-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: SWI-Prolog install from Termux repositories don't work on arm 32 bit devices: ABI mismatch #22737
Comments
This is a pretty confusing problem, but since I can reproduce it, I have noticed that disabling the check that prints that message results in the software continuing to run and seemingly providing, at the very least, some subset of the normal functionality, despite the error. I have written this patch that converts the error into a warning, so that we can see the problem at a slightly deeper level, and possibly find the root cause of the problem, find any further errors that currently occur when using an This patch can be applied and tested by putting it in the folder swi-prolog cannot currently continue in Termux on 32-bit ARM architecture without this patch.
the root cause of the problem is not yet fully understood.
--- a/src/pl-init.c
+++ b/src/pl-init.c
@@ -256,11 +256,21 @@ check_home(const char *dir)
Ssnprintf(abi_file_name, sizeof(abi_file_name),
"%s/ABI", dir);
if ( (fd = Sopen_file(abi_file_name, "r")) )
- { char *abi_string = Sfgets(abi_buf, sizeof(abi_buf), fd);
+ { char *build_time_abi_string = Sfgets(abi_buf, sizeof(abi_buf), fd);
Sclose(fd);
- if ( abi_string )
- { remove_trailing_whitespace(abi_string);
- return match_abi_version(abi_version(), abi_string);
+ if ( build_time_abi_string )
+ { remove_trailing_whitespace(build_time_abi_string);
+ char *run_time_abi_string = abi_version();
+ if (match_abi_version(run_time_abi_string, build_time_abi_string) == 1)
+ { return true;
+ } else
+ { printf("WARNING: ABI mismatch!\n");
+ printf("build time ABI found in %s: %s\n", abi_file_name, build_time_abi_string);
+ printf("run time ABI returned by abi_version(): %s\n", run_time_abi_string);
+ printf("attempting to continue for workaround purposes...\n");
+ // returning true to force the error into a warning
+ return true;
+ }
} else
{ return BAD_HOME_BAD_ABI;
} On my 32-bit Termux device, doing that results in this:
If I have time, I will try to continue troubleshooting this to look for additional leads on a root cause, for example, I would like to test a similar release of SWI-Prolog on a 32-bit ARM GNU/Linux device, to check whether the problem is specifically related to 32-bit ARM on bionic libc systems and/or using the termux-packages |
Update: Searching cryptic forums, I found a solution. The ABI file of the swi-prolog package on the termux repos for arm as the wrong ABI.
The correct ABI is returned by the --abi-version of swipl. Replacing the ABI manually worked. The real fix should be correct the packages. |
That is very interesting, since on my 32-bit ARM Termux device, the value printed by Edit: I have noticed that this value printed by This implies that this issue could probably be categorized as a cross-compilation-related issue, and therefore it might be helpful if I can find somewhere, other examples of cross-compiled It is true there are at least a few packages, like |
TL;DR: MurmurHashAligned2 is broken on big endian machines, producing different hashes according to alignment. But this all could well be a red herring. Well, this is all very weird. Strange. Here's my findings, I don't know if they will be of help or if you already know them. The api is determined by 5 values, but 4 of them are practically constant, except for one, the penultimate string, which is a global variable, GD->foreign.signature. Searching for the repo, it appears to be only modified inside a loop on pl-ext.c, line 330. The loop loops for every extension until there's no more predicates, then if it's signonly and the extensions are not loaded, it is xor-ed with the result of the call predicate_signature(f->predicate_name, f->arity, flags). predicate_signature is defined on the same file on line 199. It prints the three paramaters on a formatted string ("%s/%zu/0x%" appended to a constant PRIx64), And calls a hash function on them (MurmurHashAligned2), together with the seed 0x1a3be34a. PRIx64 indicates a 64 bit hexadecimal. MurmurHashAligned2 is defined on pl-hash.c, according to the documentation comment above it, it's broken on big endian machines, producing different hashes according to the alignment. I think I found something… |
Typically, in the context of UNIX-like operating systems, it can usually be assumed that the system being "big endian" is not a problematic factor in most cases with mainstream, consumer devices. For example, sometimes when there is a PowerPC-based or z/Architecture-based device, the developer needs to start thinking in a "big endian compatibility" context, in order to attempt to write code that is fully portable between little-endian devices, and those devices which might be truly "big endian". On the other hand, in this particular context, it can be entirely assumed that all supported platforms are little-endian only, specifically because Android does not support PowerPC, or z/Architecture, and is in fact explicitly defined as supporting only little-endian devices, in the documentation here, where it is stated "Android is always little-endian." For this reason, it is more or less acceptable from a practicality and scope-of-support perspective, to write code for Termux with the assumption that it will never be exposed to a truly "big endian" system (outside of full system emulators like QEMU), and when troubleshooting bugs in Termux, it can be reasonably assumed that "big endian compatibility" problems are highly unlikely to be the direct cause of most bugs that do not involve full system emulators of true "big endian" devices. |
Yeah, makes sense. But that function in particular is the maximum I could narrow down in my exploration of the source code. I'm not familiarized enough with this area of development. EDIT: and it's exactly processing at the part of ABI string that changes. It's the one that is defined by a global variable instead of a constant, and I could find only one place where it could change. |
one to obtain a working string for the "ABI" file, and the second one to produce artifacts for everything else that is not the "ABI" file. fixes termux#22737
I thought of another way to work around the problem that does involve micromanaging the contents of the |
Problem description
Package swi-prolog, as installed from termux repositories, don't work on arm 32 bit devices. For now I'm using proot-distro on debian, but it's cumbersome and uses to much storage.
What steps will reproduce the bug?
What is the expected behavior?
swipl should open the interactive repl, or consult a file passed by command line.
System information
The text was updated successfully, but these errors were encountered: