Control: tags -1 patch
Michael,
My theory as to what is going on here follows.
Libfastjson uses modf(3) as implemented in libm, but does not declare NEEDED
against the library:
$ grep -r modf /tmp/libfastjson/
/tmp/libfastjson/json_print.c: // needed for modf()
/tmp/libfastjson/json_print.c: result = buffer_printf(buffer,
(modf(jso->o.c_double.value, &dummy)==0)?"%.17g.0":"%.17g",
jso->o.c_double.value);
/tmp/libfastjson/json_object.c: double dummy; /* needed for modf() */
/tmp/libfastjson/json_object.c: (modf(jso->o.c_double.value,
&dummy)==0)?"%.17g.0":"%.17g",
$ objdump -x /usr/lib/x86_64-linux-gnu/libfastjson.so | grep NEEDED
NEEDED libc.so.6
The default Debian build of src:rsyslog links with libsystemd.
$ grep LIBSYSTEMD_LIBS rsyslog/configure.ac
RSRT_LIBS="\$(RSRT_LIBS1) \$(LIBESTR_LIBS) \$(LIBFASTJSON_LIBS)
\$(LIBSYSTEMD_LIBS)"
LIBSYSTEMD_LIBS is specified *after* LIBFASTJSON_LIBS and contains -lsystemd.
Libsystemd.so itself NEEDS libm and so at compile time the correct modf()
implementation is linked and all is well.
$ objdump -x /usr/lib/x86_64-linux-gnu/libsystemd.so | grep NEEDED
NEEDED libm.so.6
NEEDED libc.so.6
NEEDED ld-linux-x86-64.so.2
When building rsyslog without libsystemd (--disable-libsystemd), LIBSYSTEMD_LIBS
is empty. Although rsyslog specifies -lm, it is *before* -lfastjson. So in lines
such as this:
libtool: link: gcc -g -O2 -Werror=implicit-function-declaration
-ffile-prefix-map=/build/rsyslog-8.2510.0=. -fstack-protector-strong
-fstack-clash-protection -Wformat -Werror=format-security -fcf-protection
-Wl,-z -Wl,relro -Wl,-z -Wl,now -o rsyslogd rsyslogd-syslogd.o
rsyslogd-rsyslogd.o rsyslogd-omshell.o rsyslogd-omusrmsg.o rsyslogd-omfwd.o
rsyslogd-omfile.o rsyslogd-ompipe.o rsyslogd-omdiscard.o rsyslogd-pmrfc5424.o
rsyslogd-pmrfc3164.o rsyslogd-smtradfile.o rsyslogd-smfile.o rsyslogd-smfwd.o
rsyslogd-smtradfwd.o rsyslogd-iminternal.o -Wl,--export-dynamic
../grammar/.libs/libgrammar.a ../compat/.libs/compat.a -lz -lpthread
../runtime/.libs/librsyslog.a -lm -lestr -lfastjson -luuid
modf() in libfastjson is not resolved and this produces the IFUNC runtime error
observed.
/usr/sbin/rsyslogd: Relink `/usr/lib/x86_64-linux-gnu/libfastjson.so.4' with
`/usr/lib/x86_64-linux-gnu/libm.so.6' for IFUNC symbol `modf'
There apear to be 2 possible fixes:
1) Add -lm to libfastjson.pc, as implemented in the current upstream fix.
2) Rebuild libfastjson with explicit -lm linkage as suggested by the error
message.
To me, 2) makes more sense; surely it is libfastjson's responsibility to link
the correct symbols?
Adding the following patch to libfastjson, adds the correct libm NEEDED
+ diff -u /tmp/libfastjson/Makefile.am
/var/cache/pbuilder/build/cow.393/libfastjson-1.2304.0/Makefile.am
--- /tmp/libfastjson/Makefile.am 2025-12-05 16:35:42.382689052 +0000
+++ /var/cache/pbuilder/build/cow.393/libfastjson-1.2304.0/Makefile.am
2025-12-08 08:24:40.794398879 +0000
@@ -1,4 +1,3 @@
-
EXTRA_DIST = README.html
SUBDIRS = . tests
@@ -27,7 +26,7 @@
-export-symbols-regex '^fjson_.*' \
-no-undefined \
@JSON_BSYMBOLIC_LDFLAGS@
-libfastjson_la_LIBADD = libfastjson-internal.la
+libfastjson_la_LIBADD = libfastjson-internal.la -lm
libfastjson_la_SOURCES = \
json_version.c \
$ objdump -x /libfastjson-1.2304.0/.libs/libfastjson.so | grep NEEDED
NEEDED libm.so.6
NEEDED libc.so.6
and rebuilding rsyslog without libsystemd against the patched libfastjson
$ objdump -x tools/rsyslogd|grep NEEDED
NEEDED libz.so.1
NEEDED libm.so.6
NEEDED libestr.so.0
NEEDED libfastjson.so.4
NEEDED libuuid.so.1
NEEDED libc.so.6
no longer produces a runtime error.
Which solution do you prefer?
Best wishes
Mark