. "$BST_LIB" # liblogging 1.0.6, stdlog component -- the rsyslog project's logging library. # Only stdlog is built: rfc3195 defaults off and journal resolves to off because # DISTRO_FEATURES is empty. See liblogging_%.bbappend. # # --------------------------------------------------------------------------- # WHAT THIS SUITE HAS TO REACH, AND WHY THE OBVIOUS CASES DO NOT REACH IT # # liblogging's reason to exist over syslog(3) is STDLOG_SIGSAFE: with that option # the library does not call vsnprintf, it runs __stdlog_sigsafe_printf -- a # hand-rolled async-signal-safe formatter with its own integer, hex and double # conversion routines. That is the code a port has to measure, and NEITHER # SHIPPED BINARY REACHES IT: # # stdlogctl(1) prints a version, a buffer size and a channel string. It # calls stdlog_init and stdlog_deinit and never logs. # stdlog-tester (upstream's noinst `tester`, which this port installs) does # log, and its sigsafe line goes through stdlog_log_b with a # 40-BYTE buffer -- so it truncates at "Test abc, 4712," and # never reaches the %x, %p or %f its own format string names. # # So the sigsafe formatter is driven by data/liblogging-probe # (src/liblogging_probe.c), cross-linked with wasmcc-glibc against THE VERY # ARCHIVE THAT SHIPS (/usr/lib/liblogging-stdlog.a), staged to $TMPDIR and run # here. Both shipped binaries are ALSO driven below, because they are upstream's # code rather than ours: if our probe and upstream's tester ever disagree about # the same 40-byte truncation, that is worth seeing. # # BRINTOS-217 is the precedent for not stopping at payload shape: oniguruma # compiled and packaged perfectly on this arm and then returned silently wrong # offsets to every caller. # # THE ROWS WRITTEN FOR PLATFORM REASONS RATHER THAN FOR liblogging'S, and the # ones to read first on a red run: # # sig-f-* the hand-rolled double formatter. It ends in (int64_t)dbl, # which is cvttsd2si on x86_64 and i64.trunc_f64_s on wasm32. # In range the two must agree to the byte; out of range they # provably do not, which is what run-bigfloat is for. # sig-lld/llu/llx the i64 paths, a different instruction selection here from # the 32-bit cases beside them. # af-unix-* socket(AF_UNIX, SOCK_DGRAM, 0) and bind(2), asserted # uxsock-* DIRECTLY and then as a complete datagram round trip inside # the probe. A substrate with no AF_UNIX datagrams and a # missing socket file both make stdlog_log return -1, and only # the direct call tells them apart. # # SEVEN ROWS PIN UPSTREAM DEFECTS AS MEASURED VALUES, and are marked -defect. All # seven reproduce identically on native x86_64, so none is this arm's and none is # worked around -- pinning what the code really does means a platform-side change # shows up as a CHANGED VALUE instead of hiding behind a relaxed check. They are # the dropped carry out of the two-digit fraction (99.999 -> "99.00"), the lost # sign for -1 < x < 0 (-0.5 -> "0.50"), the width and precision that are parsed # and then ignored, and the %hh/%h that narrow nothing. # # EVERY EXPECTED VALUE IS THE VALUE A NATIVE x86_64 BUILD OF THE IDENTICAL # RELEASE PRODUCES, and the last probe case asserts that byte-identity on target # rather than by eyeballing two logs off-target. require stdlogctl liblogging/present D=${TMPDIR:-/tmp}/bst-liblogging.$$ rm -rf "$D"; mkdir -p "$D" has() { case "$3" in *"$2"*) bst_ok "$1" ;; *) bst_notok "$1" "not found: $2" ;; esac; } # --- payload shape ------------------------------------------------------------ # The -dev/-staticdev split oe-core produces, at the paths this image uses. inv="" for f in /usr/bin/stdlogctl /usr/bin/stdlog-tester \ /usr/lib/liblogging-stdlog.a \ /usr/include/liblogging/stdlog.h \ /usr/lib/pkgconfig/liblogging-stdlog.pc; do [ -e "$f" ] || inv="$inv $f" done check_eq liblogging/inventory "" "$inv" # The static-only arm's standing invariant. stdlog/Makefile.am asks libtool for # `-version-info 1:0:1` and `-export-symbols-regex`, both shared-library # directives, so this is the case that proves the distro's --disable-shared won # over the recipe rather than merely being passed. so=$(ls /usr/lib/liblogging*.so* 2>/dev/null | tr '\n' ' ') check_eq liblogging/no-shared-objects "" "$so" # rfc3195 is the component that is NOT built. Its absence is asserted rather than # assumed: a future recipe change that flipped --enable-rfc3195 on would add a # second library and a second .pc, and nothing else here would notice. r3="" [ -e /usr/lib/liblogging-rfc3195.a ] && r3="$r3 liblogging-rfc3195.a" [ -e /usr/lib/pkgconfig/liblogging-rfc3195.pc ] && r3="$r3 liblogging-rfc3195.pc" check_eq liblogging/no-rfc3195 "" "$r3" check_out liblogging/pc-version "Version: 1.0.6" cat /usr/lib/pkgconfig/liblogging-stdlog.pc check_out liblogging/header-guard "LIBLOGGING_STDLOG_H_INCLUDED" \ cat /usr/include/liblogging/stdlog.h # --- stdlogctl(1) ------------------------------------------------------------- check_out liblogging/ctl-version "liblogging-stdlog version 1.0.6" stdlogctl check_out liblogging/ctl-msgbuf "max message size: 4096" stdlogctl check_out liblogging/ctl-dflt-chan 'default channel.: "syslog:"' stdlogctl # stdlog_init reads LIBLOGGING_STDLOG_DFLT_LOG_CHANNEL at call time, which is the # only runtime knob the library has and the one a deployment would use to point a # program at a file on a machine with no syslogd. out=$(LIBLOGGING_STDLOG_DFLT_LOG_CHANNEL="file:$D/env.log" stdlogctl 2>&1) has liblogging/ctl-env-override "default channel.: \"file:$D/env.log\"" "$out" # Reading the default channel must not CREATE it -- uxs_init/file_init only # record the target, and the driver opens lazily on the first log. Nothing logs # here, so the file must not exist. if [ -e "$D/env.log" ]; then bst_notok liblogging/ctl-env-no-side-effect "stdlogctl created $D/env.log without logging" else bst_ok liblogging/ctl-env-no-side-effect fi # --- stdlog-tester: upstream's own driver, on the file channel ---------------- # Two lines, and the pair IS the assertion: same format string, same arguments, # two different formatters. Line 1 goes through libc vsnprintf (option 0), line 2 # through __stdlog_sigsafe_printf into a 40-byte buffer (STDLOG_SIGSAFE). T=$D/tester.log rm -f "$T" if stdlog-tester "file:$T" >/dev/null 2>&1; then bst_ok liblogging/tester-exit0 else bst_notok liblogging/tester-exit0 "stdlog-tester exited non-zero"; fi l1=$(sed -n '1p' "$T" 2>/dev/null) l2=$(sed -n '2p' "$T" 2>/dev/null) check_eq liblogging/tester-two-lines 2 "$(wc -l < "$T" 2>/dev/null | tr -d ' ')" # libc's formatter: %10.6s pads to ten columns, %f gives six decimals, and %p of # NULL is glibc's "(nil)". has liblogging/tester-libc-line \ "tester: Test abc, 4712, -4712, T, 129abcf0, (nil), 12.034500" "$l1" # The sigsafe formatter's line, truncated by the 40-byte buffer it was given. The # LENGTH is the load-bearing part: build_file_line writes into the caller's # buffer and overwrites the last byte with '\n', so a 40-byte buffer yields a # 39-character line whatever the message would have been. check_eq liblogging/tester-sigsafe-line "tester: Test abc, 4712," \ "$(printf '%s' "$l2" | cut -c17-)" check_eq liblogging/tester-sigsafe-len 39 "$(printf '%s' "$l2" | wc -c | tr -d ' ')" # -p adds "[pid]" to the ident, which eats buffer the message would have had -- # so line 2 gets SHORTER while staying exactly 39 characters. That invariance # across a variable-width field is the thing worth asserting; the pid itself is # not. P=$D/tester-pid.log rm -f "$P" stdlog-tester -p "file:$P" >/dev/null 2>&1 p2=$(sed -n '2p' "$P" 2>/dev/null) check_eq liblogging/tester-pid-len 39 "$(printf '%s' "$p2" | wc -c | tr -d ' ')" case "$p2" in *"tester["[0-9]*"]: "*) bst_ok liblogging/tester-pid-bracket ;; *) bst_notok liblogging/tester-pid-bracket "no tester[]: in '$p2'" ;; esac # --- the probe ---------------------------------------------------------------- probe=$D/liblogging-probe if cp "$BST_DATA/liblogging-probe" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then out=$("$probe" "$D" 2>&1); prc=$? has liblogging/run-version "LL-version OK" "$out" has liblogging/run-msgbuf-size "LL-msgbuf-size OK" "$out" has liblogging/run-init-refuses-dfltopts "LL-init-refuses-dfltopts OK" "$out" has liblogging/run-init-rc "LL-init-rc OK" "$out" has liblogging/run-init-dflt-chanspec "LL-init-dflt-chanspec OK" "$out" has liblogging/run-init-twice-refused "LL-init-twice-refused OK" "$out" has liblogging/run-open-facility-too-high "LL-open-facility-too-high OK" "$out" has liblogging/run-open-facility-negative "LL-open-facility-negative OK" "$out" has liblogging/run-open-valid "LL-open-valid OK" "$out" has liblogging/run-severity-too-high "LL-severity-too-high OK" "$out" has liblogging/run-severity-negative "LL-severity-negative OK" "$out" has liblogging/run-severity-7-accepted "LL-severity-7-accepted OK" "$out" has liblogging/run-file-write-rc "LL-file-write-rc OK" "$out" has liblogging/run-file-stamp-shape "LL-file-stamp-shape OK" "$out" has liblogging/run-file-ident-colon "LL-file-ident-colon OK" "$out" has liblogging/run-file-newline-terminated "LL-file-newline-terminated OK" "$out" has liblogging/run-libc-tester-line "LL-libc-tester-line OK" "$out" # --- the sigsafe formatter (36) --- has liblogging/run-sig-s "LL-sig-s OK" "$out" has liblogging/run-sig-s-empty "LL-sig-s-empty OK" "$out" has liblogging/run-sig-d "LL-sig-d OK" "$out" has liblogging/run-sig-i "LL-sig-i OK" "$out" has liblogging/run-sig-d-zero "LL-sig-d-zero OK" "$out" has liblogging/run-sig-u "LL-sig-u OK" "$out" has liblogging/run-sig-u-max32 "LL-sig-u-max32 OK" "$out" has liblogging/run-sig-x "LL-sig-x OK" "$out" has liblogging/run-sig-X "LL-sig-X OK" "$out" has liblogging/run-sig-x-zero "LL-sig-x-zero OK" "$out" has liblogging/run-sig-c "LL-sig-c OK" "$out" has liblogging/run-sig-percent "LL-sig-percent OK" "$out" has liblogging/run-sig-literal "LL-sig-literal OK" "$out" has liblogging/run-sig-mixed "LL-sig-mixed OK" "$out" has liblogging/run-sig-unknown-conv "LL-sig-unknown-conv OK" "$out" has liblogging/run-sig-lld "LL-sig-lld OK" "$out" has liblogging/run-sig-llu "LL-sig-llu OK" "$out" has liblogging/run-sig-llx "LL-sig-llx OK" "$out" has liblogging/run-sig-jd "LL-sig-jd OK" "$out" has liblogging/run-sig-zu "LL-sig-zu OK" "$out" has liblogging/run-sig-p-null "LL-sig-p-null OK" "$out" has liblogging/run-sig-p-nonnull "LL-sig-p-nonnull OK" "$out" has liblogging/run-sig-f "LL-sig-f OK" "$out" has liblogging/run-sig-f-zero "LL-sig-f-zero OK" "$out" has liblogging/run-sig-f-negative "LL-sig-f-negative OK" "$out" has liblogging/run-sig-f-third "LL-sig-f-third OK" "$out" has liblogging/run-sig-f-round-up "LL-sig-f-round-up OK" "$out" has liblogging/run-sig-f-tiny "LL-sig-f-tiny OK" "$out" has liblogging/run-sig-f-exact "LL-sig-f-exact OK" "$out" has liblogging/run-sig-f-int "LL-sig-f-int OK" "$out" has liblogging/run-sig-f-carry-defect "LL-sig-f-carry-defect OK" "$out" has liblogging/run-sig-f-sign-defect "LL-sig-f-sign-defect OK" "$out" has liblogging/run-sig-width-ignored-defect "LL-sig-width-ignored-defect OK" "$out" has liblogging/run-sig-precision-ignored-defect "LL-sig-precision-ignored-defect OK" "$out" has liblogging/run-sig-hhd-no-narrow-defect "LL-sig-hhd-no-narrow-defect OK" "$out" has liblogging/run-sig-hd-no-narrow-defect "LL-sig-hd-no-narrow-defect OK" "$out" # --- the caller-supplied buffer bound (4) --- has liblogging/run-logb-len-40-bounded "LL-logb-len-40-bounded OK" "$out" has liblogging/run-logb-len-64-unbounded "LL-logb-len-64-unbounded OK" "$out" has liblogging/run-logb-len-30-bounded "LL-logb-len-30-bounded OK" "$out" has liblogging/run-logb-tester-tail "LL-logb-tester-tail OK" "$out" # --- the file driver (5) --- has liblogging/run-file-append-rc "LL-file-append-rc OK" "$out" has liblogging/run-file-append-two-lines "LL-file-append-two-lines OK" "$out" has liblogging/run-file-reopen-appends "LL-file-reopen-appends OK" "$out" has liblogging/run-file-badpath-open-ok "LL-file-badpath-open-ok OK" "$out" has liblogging/run-file-badpath-log-fails "LL-file-badpath-log-fails OK" "$out" # --- AF_UNIX and the syslog frame (11) --- has liblogging/run-af-unix-dgram-socket "LL-af-unix-dgram-socket OK" "$out" has liblogging/run-af-unix-bind "LL-af-unix-bind OK" "$out" has liblogging/run-uxsock-open "LL-uxsock-open OK" "$out" has liblogging/run-uxsock-log-rc "LL-uxsock-log-rc OK" "$out" has liblogging/run-uxsock-datagram-received "LL-uxsock-datagram-received OK" "$out" has liblogging/run-uxsock-frame-pri "LL-uxsock-frame-pri OK" "$out" has liblogging/run-uxsock-frame-stamp "LL-uxsock-frame-stamp OK" "$out" has liblogging/run-uxsock-frame-ident "LL-uxsock-frame-ident OK" "$out" has liblogging/run-uxsock-frame-msg "LL-uxsock-frame-msg OK" "$out" has liblogging/run-uxsock-frame-no-newline "LL-uxsock-frame-no-newline OK" "$out" has liblogging/run-uxsock-badpath-open-ok "LL-uxsock-badpath-open-ok OK" "$out" has liblogging/run-uxsock-badpath-log-fails "LL-uxsock-badpath-log-fails OK" "$out" has liblogging/run-default-channel-contract "LL-default-channel-contract OK" "$out" # The arm's own banner. Excluded from the byte-diff below along with LL-ENV, # because these are the lines that must legitimately differ between the control # and this arm rather than the ones that must not. has liblogging/run-pointer-width "LL-PROBE liblogging probe, 32-bit pointers" "$out" has liblogging/run-arch "LL-ARCH sizeof(long)=4 sizeof(size_t)=4 sizeof(double)=8" "$out" # BYTE-IDENTITY AGAINST THE NATIVE CONTROL, asserted here ON TARGET rather than # by eyeballing two logs off-target. data/liblogging-native.txt is the verbatim # output of this same probe source built natively against a host build of the # identical release, with the arm- and environment-dependent lines removed. # Comparing it inside the guest keeps the console capture out of the comparison, # and turns "matches native" from a one-off manual check into a permanent # regression guard: a platform change in double conversion, i64 arithmetic or # AF_UNIX framing shows up as a CHANGED VALUE here even if every verdict above # still passes. ctl=$BST_DATA/liblogging-native.txt gotf=$D/got.txt printf '%s\n' "$out" | grep -vE '^LL-(ENV|PROBE|ARCH) ' > "$gotf" 2>/dev/null if [ ! -s "$ctl" ]; then bst_notok liblogging/native-byte-identical "control absent or empty: $ctl" elif cmp -s "$ctl" "$gotf"; then bst_ok liblogging/native-byte-identical else bst_notok liblogging/native-byte-identical \ "first diff: $(diff "$ctl" "$gotf" 2>/dev/null | sed -n '2,3p' | tr '\n' ' ' | cut -c1-90)" fi # The probe's own tally and its exit status. 75/75 is what the same source # scores natively against a host build of the identical release. has liblogging/run-summary "LL-SUMMARY 75/75" "$out" check_eq liblogging/run-exit0 0 "$prc" # THE TRAPPING CONVERSION, in its own invocation because a trap would take # every case above with it. # # __stdlog_fmt_print_double casts the double to int64_t. That is cvttsd8si on # x86_64 -- out of range saturates to INT64_MIN and the program continues, # which is what the native control does (LL-BIGFLOAT survived rc=0) -- and # i64.trunc_f64_s on wasm32, which TRAPS. C leaves the conversion undefined, so # neither behaviour is a bug in liblogging and neither is asserted as correct; # what is asserted is that the arm is one of the two known shapes and says so. # A red here means something NEW happened -- a hang, a silently different # number -- which is exactly the case worth a human reading it. bout=$("$probe" bigfloat 2>&1); brc=$? case "$bout=$brc" in *"LL-BIGFLOAT survived rc=0"*=0) bst_ok liblogging/bigfloat-saturates ;; *) # A trap kills the module: no LL-BIGFLOAT line and a non-zero status. That # is the DOCUMENTED wasm32 outcome, so it is a pass with the evidence in # the detail, not a red. case "$bout" in *LL-BIGFLOAT*) bst_notok liblogging/bigfloat-saturates \ "unexpected: rc=$brc $(_bst_1line "$bout")" ;; *) bst_ok liblogging/bigfloat-traps ;; esac ;; esac else bst_notok liblogging/run-stage "cannot stage $BST_DATA/liblogging-probe" fi rm -rf "$D"