Skip to content

exp10(::BigFloat) is inaccurate on FreeBSD AArch64 unless MPFR is preloaded #57121

Open
@ararslan

Description

@ararslan

On FreeBSD AArch64, exp10(::BigFloat) is inaccurate unless:

  1. Julia is run with its own bundled libmpfr.so LD_PRELOADed, or
  2. Julia is invoked from C with -lmpfr passed when compiling, even if MPFR is not used at all in the C code.

Example of case 1:

$ ./usr/bin/julia -e 'show(exp10(BigFloat(-100.0)))'
8.572405434617062366618376612290057195889324961170989959113443824207244769300536e-101
$ LD_PRELOAD="./usr/lib/libmpfr.so" ./usr/bin/julia -e 'show(exp10(BigFloat(-100.0)))'
9.999999999999999999999999999999999999999999999999999999999999999999999999999955e-101

The latter value is correct. The former is not and causes some math tests to fail.

Example of case 2:

// call this test.c
#include "julia.h"
int main(void) {
    jl_init();
    jl_eval_string("show(exp10(BigFloat(-100.0)))");
    jl_atexit_hook(0);
    return 0;
}
$ cc test.c -o test1 -std=gnu11 -I/root/julia/usr/include/julia -I/root/julia/usr/include -L/root/julia/usr/lib -L/root/julia/usr/lib/julia -fPIC -Wl,--export-dynamic -Wl,-rpath,/root/julia/usr/lib -Wl,-rpath,/root/julia/usr/lib/julia -ljulia
$ ./test1
8.572405434617062366618376612290057195889324961170989959113443824207244769300536e-101
$ cc test.c -o test2 -std=gnu11 -I/root/julia/usr/include/julia -I/root/julia/usr/include -L/root/julia/usr/lib -L/root/julia/usr/lib/julia -fPIC -Wl,--export-dynamic -Wl,-rpath,/root/julia/usr/lib -Wl,-rpath,/root/julia/usr/lib/julia -ljulia -lmpfr
$ ./test2
9.999999999999999999999999999999999999999999999999999999999999999999999999999955e-101

I've attempted quite a bit of debugging, none of which has been particularly fruitful, but I did notice something odd. jl_dlfind can't find mpfr_exp10 (unless MPFR is preloaded) but we still end up calling it:

$ ./usr/bin/julia -E 'ccall(:jl_dlfind, Ptr{UInt8}, (Ptr{UInt8},), "mpfr_exp10")'
Ptr{UInt8}(0x0000000000000000)
$ LD_PRELOAD="./usr/lib/libmpfr.so" ./usr/bin/julia -E 'ccall(:jl_dlfind, Ptr{UInt8}, (Ptr{UInt8},), "mpfr_exp10")'
Ptr{UInt8}(0x0000000000000001)

The latter corresponds to JL_EXE_LIBNAME, and is the result I get on macOS AArch64. The former means we couldn't find the symbol in libjulia-internal, libjulia, or the executable (searched in that order). I would have assumed this means we couldn't find it at all—however, running under LLDB with a breakpoint on mpfr_exp10, we do actually call it.

I'm pretty stumped; this is among the stranger things I've encountered in my time spent using computers. Does anybody know what the issue could be, or have any suggestions for further debugging?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bignumsBigInt and BigFloatbugIndicates an unexpected problem or unintended behaviorsystem:armARMv7 and AArch64system:freebsdAffects only FreeBSD

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions