diff --git a/01-Med-qblog.h-better-explanation-behaviour-of-QB_LOG_I.patch b/01-Med-qblog.h-better-explanation-behaviour-of-QB_LOG_I.patch index 70223d8..01a9bc4 100644 --- a/01-Med-qblog.h-better-explanation-behaviour-of-QB_LOG_I.patch +++ b/01-Med-qblog.h-better-explanation-behaviour-of-QB_LOG_I.patch @@ -1,4 +1,4 @@ -From a7014f6d411685a5691be0f59c0634e165771811 Mon Sep 17 00:00:00 2001 +From 3f9ccfc3b291196657edb2e920327f2d26804d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 6 Oct 2017 17:17:26 +0200 Subject: [PATCH 1/6] Med: qblog.h: better explanation + behaviour of @@ -28,8 +28,8 @@ requires. pacemakerd: utils.c:69: common: Assertion `"non-empty callsite section" && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP' failed. -Inspired by the suggestion of Ferenc Wágner (for the subsequent -commit, actually). +Restructuring of the assertion inspired by the suggestion of Ferenc +Wágner (for the subsequent commit, actually). And regarding: > as a side effect, it can ensure the boundary-denoting symbols for @@ -42,11 +42,11 @@ libqb-target cross-combination matrix and the findings). Signed-off-by: Jan Pokorný --- - include/qb/qblog.h | 34 +++++++++++++++++++++++++++++----- - 1 file changed, 29 insertions(+), 5 deletions(-) + include/qb/qblog.h | 43 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/include/qb/qblog.h b/include/qb/qblog.h -index 3cb4eef..d39803f 100644 +index 3cb4eef..7b6db8b 100644 --- a/include/qb/qblog.h +++ b/include/qb/qblog.h @@ -42,6 +42,10 @@ extern "C" { @@ -69,8 +69,8 @@ index 3cb4eef..d39803f 100644 + * Following section discusses the customization. Moreover, it's quite + * vital to instrument the target user of this logging subsystem with + * @c QB_LOG_INIT_DATA() macro placed in the top file scope in an exactly -+ * one source file (preferably the main one) to be compiled into the -+ * resulting binary. This is a self-defensive measure for when the ++ * one source file (preferably the main one) to be mixed into the resulting ++ * compilation unit. This is a self-defensive measure for when the + * linker-assisted collection of callsite data silently fails, which + * could otherwise go unnoticed, causing troubles down the road. + * @@ -78,7 +78,7 @@ index 3cb4eef..d39803f 100644 * @par Configuring log targets. * A log target can be syslog, stderr, the blackbox, stdout, or a text file. * By default only syslog is enabled. -@@ -268,11 +283,20 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs); +@@ -268,11 +283,29 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs); extern struct qb_log_callsite QB_ATTR_SECTION_START[]; extern struct qb_log_callsite QB_ATTR_SECTION_STOP[]; @@ -88,14 +88,23 @@ index 3cb4eef..d39803f 100644 - void name(void) \ - { if (QB_ATTR_SECTION_START == QB_ATTR_SECTION_STOP) assert(0); } \ +/* optional on-demand self-check of (1) toolchain sanity (prerequisite for -+ * the logging subsystem to work properly) and (2) non-void active use of -+ * logging (satisfied with a justifying existence of a logging callsite as -+ * defined with a @c qb_logt invocation) at the target binary, which is -+ * presumably assured by it's author as of relying on this very macro; -+ * only effective when link-time ("run-time amortizing") callsite collection -+ * is; as a side effect, it can ensure the boundary-denoting symbols for the -+ * target collection area are kept alive with some otherwise unkind linkers; -+ * may be extended in future for more in-depth self-validation */ ++ the logging subsystem to work properly) and (2) non-void active use of ++ logging (satisfied with a justifying existence of a logging callsite as ++ defined with a @c qb_logt invocation) at the target (but see below), which ++ is presumably assured by it's author as of relying on this very macro ++ [technically, the symbols that happen to be resolved under the respective ++ identifiers do not necessarily come from the same compilation unit level ++ as when it's not the end program (or by induction, a library higher in ++ the symbol resolution fall-through) but a shared library, the former takes ++ a precedence unless it lacks use of logging on its own making its very ++ section empty and hence without such boundary symbols provided at the ++ respective level and thus deferring to lower priority symbol resolution ++ stop -- despite this fuzzily targeted attestation, the check remains ++ reasonable and should not harm anything]; ++ only effective when link-time ("run-time amortizing") callsite collection ++ is; as a side effect, it can ensure the boundary-denoting symbols for the ++ target collection area are kept alive with some otherwise unkind linkers; ++ may be extended in future for more in-depth self-validation */ +#define QB_LOG_INIT_DATA(name) \ + void name(void); \ + void name(void) \ diff --git a/02-build-configure-run-attribute-section-test-through-r.patch b/02-build-configure-run-attribute-section-test-through-r.patch index c6a4aa8..1390235 100644 --- a/02-build-configure-run-attribute-section-test-through-r.patch +++ b/02-build-configure-run-attribute-section-test-through-r.patch @@ -1,4 +1,4 @@ -From ccfe20a89b3099f17f22971995ace787356ed5f4 Mon Sep 17 00:00:00 2001 +From 796ce1191ffd99f0bceba174355f695af8dc368a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 6 Oct 2017 17:17:26 +0200 Subject: [PATCH 2/6] build: configure: run attribute section test through diff --git a/03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch b/03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch index efafe90..d900bc3 100644 --- a/03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch +++ b/03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch @@ -1,4 +1,4 @@ -From c489cb378cd8ad7a7a089067e39b65b0c359c60b Mon Sep 17 00:00:00 2001 +From 3df0138ba57e274b8c8065739870b1529b95e087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 6 Oct 2017 17:17:26 +0200 Subject: [PATCH 3/6] tests: new sort of tests dubbed "functional", cover @@ -44,7 +44,7 @@ commit is in the pipeline... Developmental consumption model (a.) is now also tested automatically in Travis CI runs and as a part of %check within upstream-suggested libqb.spec for RPM packaging, whereas the regular one (b.) serves as -a building block for new new log_test_mock.sh runner of said test matrix +a building block for new log_test_mock.sh runner of said test matrix -- it iterates through all the possible permutations of linker-imposed implicit visibility of mentioned symbols between various affected linkage sides (see 1. - 3. above) so as to demonstrate a/ the impact @@ -127,36 +127,45 @@ proclaimed complete once all combinations pass barring QB_LOG_INIT_DATA usage (incurring the mentioned active referential use of the symbols), along with a spin using it everywhere for good measure. +For another level of the analysis depth, one can further play with +combinations of -n{sc,cl,il} options (explained upon -h switch) to +log_test_mock.sh (taking an oracle, this is added mostly to justify +the upcoming self-check test change because linker-script-based +workaround for newer linkers will cause the section boundary symbols +to be present regardless if that section is utilized, leading to +a self-inflicted breakage due to these empty section symbols suddenly +winning in the symbol resolution mechanism). + Signed-off-by: Jan Pokorný --- - configure.ac | 7 +- - libqb.spec.in | 3 +- - tests/Makefile.am | 3 + - tests/functional/GNUmakefile | 20 ++ - tests/functional/Makefile.am | 23 +++ - tests/functional/log.am | 49 +++++ - tests/functional/log_client.c | 86 ++++++++ - tests/functional/log_client.err | 2 + - tests/functional/log_external/Makefile.am | 23 +++ - tests/functional/log_interlib.c | 68 +++++++ - tests/functional/log_interlib_client.c | 64 ++++++ - tests/functional/log_interlib_client.err | 4 + - tests/functional/log_internal/Makefile.am | 23 +++ - tests/functional/log_test_client.sh | 22 ++ - tests/functional/log_test_interlib_client.sh | 22 ++ - tests/functional/log_test_mock.sh | 289 +++++++++++++++++++++++++++ - 16 files changed, 706 insertions(+), 2 deletions(-) + configure.ac | 7 +- + libqb.spec.in | 3 +- + tests/Makefile.am | 3 + + tests/functional/GNUmakefile | 20 ++ + tests/functional/Makefile.am | 23 ++ + tests/functional/log.am | 49 ++++ + tests/functional/log_client.c | 88 ++++++++ + tests/functional/log_external/Makefile.am | 23 ++ + tests/functional/log_interlib.c | 70 ++++++ + tests/functional/log_interlib_client.c | 68 ++++++ + tests/functional/log_internal/Makefile.am | 23 ++ + tests/functional/log_test_client.err | 2 + + tests/functional/log_test_client.sh | 30 +++ + tests/functional/log_test_interlib_client.err | 4 + + tests/functional/log_test_interlib_client.sh | 33 +++ + tests/functional/log_test_mock.sh | 310 ++++++++++++++++++++++++++ + 18 files changed, 767 insertions(+), 4 deletions(-) create mode 100644 tests/functional/GNUmakefile create mode 100644 tests/functional/Makefile.am create mode 100644 tests/functional/log.am create mode 100644 tests/functional/log_client.c - create mode 100644 tests/functional/log_client.err create mode 100644 tests/functional/log_external/Makefile.am create mode 100644 tests/functional/log_interlib.c create mode 100644 tests/functional/log_interlib_client.c - create mode 100644 tests/functional/log_interlib_client.err create mode 100644 tests/functional/log_internal/Makefile.am + create mode 100644 tests/functional/log_test_client.err create mode 100755 tests/functional/log_test_client.sh + create mode 100644 tests/functional/log_test_interlib_client.err create mode 100755 tests/functional/log_test_interlib_client.sh create mode 100755 tests/functional/log_test_mock.sh @@ -248,7 +257,7 @@ index 0000000..1b9de81 +.PHONY: check distclean force install diff --git a/tests/functional/Makefile.am b/tests/functional/Makefile.am new file mode 100644 -index 0000000..72f551e +index 0000000..0d34ae8 --- /dev/null +++ b/tests/functional/Makefile.am @@ -0,0 +1,23 @@ @@ -272,12 +281,12 @@ index 0000000..72f551e +# along with libqb. If not, see . + +MAINTAINERCLEANFILES = Makefile.in -+EXTRA_DIST = GNUmakefile log_client.err log_interlib_client.err \ ++EXTRA_DIST = GNUmakefile log_test_client.err log_test_interlib_client.err \ + log_test_client.sh log_test_interlib_client.sh log_test_mock.sh +SUBDIRS = log_external log_internal diff --git a/tests/functional/log.am b/tests/functional/log.am new file mode 100644 -index 0000000..5fe1ae7 +index 0000000..e8e4740 --- /dev/null +++ b/tests/functional/log.am @@ -0,0 +1,49 @@ @@ -301,7 +310,7 @@ index 0000000..5fe1ae7 +# along with libqb. If not, see . + +MAINTAINERCLEANFILES = Makefile.in -+CLEANFILES = log_client.err.real log_interlib_client.err.real ++CLEANFILES = log_test_client.err.real log_test_interlib_client.err.real + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include + @@ -332,10 +341,10 @@ index 0000000..5fe1ae7 +# vim: ft=automake diff --git a/tests/functional/log_client.c b/tests/functional/log_client.c new file mode 100644 -index 0000000..aa6ebe1 +index 0000000..c60d657 --- /dev/null +++ b/tests/functional/log_client.c -@@ -0,0 +1,86 @@ +@@ -0,0 +1,88 @@ +/* + * Copyright 2017 Red Hat, Inc. + * @@ -397,8 +406,10 @@ index 0000000..aa6ebe1 + printf("--\n"); +#endif + ++#ifndef NLOG + /* Casual test of "user-space" logging. */ + qb_log(LOG_DEBUG, "hello"); ++#endif + + /* And now of "library-space" logging, i.e., let libqb generated + an error message on its own behalf, first to see if it will be @@ -422,14 +433,6 @@ index 0000000..aa6ebe1 + free(tmpfile_buf); + qb_log_fini(); +} -diff --git a/tests/functional/log_client.err b/tests/functional/log_client.err -new file mode 100644 -index 0000000..0ae7665 ---- /dev/null -+++ b/tests/functional/log_client.err -@@ -0,0 +1,2 @@ -+[MAIN |debug] ../log_client.c:63:hello -+[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2) diff --git a/tests/functional/log_external/Makefile.am b/tests/functional/log_external/Makefile.am new file mode 100644 index 0000000..36aa0af @@ -461,10 +464,10 @@ index 0000000..36aa0af +liblog_inter_la_LIBADD = -lqb diff --git a/tests/functional/log_interlib.c b/tests/functional/log_interlib.c new file mode 100644 -index 0000000..498f82c +index 0000000..228a339 --- /dev/null +++ b/tests/functional/log_interlib.c -@@ -0,0 +1,68 @@ +@@ -0,0 +1,70 @@ +/* + * Copyright 2017 Red Hat, Inc. + * @@ -509,8 +512,10 @@ index 0000000..498f82c + printf("--\n"); +#endif + ++#ifndef NLIBLOG + /* Casual test of "user-space" logging. */ -+ qb_log(LOG_INFO, "hello"); ++ qb_log(LOG_INFO, "aloha"); ++#endif + + /* And now of "library-space" logging, i.e., let libqb generated + an error message on its own behalf, first to see if it will be @@ -535,10 +540,10 @@ index 0000000..498f82c +} diff --git a/tests/functional/log_interlib_client.c b/tests/functional/log_interlib_client.c new file mode 100644 -index 0000000..c669703 +index 0000000..820df67 --- /dev/null +++ b/tests/functional/log_interlib_client.c -@@ -0,0 +1,64 @@ +@@ -0,0 +1,68 @@ +/* + * Copyright 2017 Red Hat, Inc. + * @@ -598,21 +603,15 @@ index 0000000..c669703 + printf("--\n"); +#endif + ++#ifndef NLOG + qb_log(LOG_INFO, "BEFORE"); ++#endif + foo(); ++#ifndef NLOG + qb_log(LOG_INFO, "AFTER"); ++#endif + qb_log_fini(); +} -diff --git a/tests/functional/log_interlib_client.err b/tests/functional/log_interlib_client.err -new file mode 100644 -index 0000000..486071a ---- /dev/null -+++ b/tests/functional/log_interlib_client.err -@@ -0,0 +1,4 @@ -+[MAIN |info] ../log_interlib_client.c:60:BEFORE -+[MAIN |info] ../log_interlib.c:46:hello -+[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2) -+[MAIN |info] ../log_interlib_client.c:62:AFTER diff --git a/tests/functional/log_internal/Makefile.am b/tests/functional/log_internal/Makefile.am new file mode 100644 index 0000000..697cee2 @@ -642,12 +641,20 @@ index 0000000..697cee2 + +log_client_LDADD = $(top_builddir)/lib/libqb.la +liblog_inter_la_LIBADD = $(top_builddir)/lib/libqb.la +diff --git a/tests/functional/log_test_client.err b/tests/functional/log_test_client.err +new file mode 100644 +index 0000000..cb0ff3c +--- /dev/null ++++ b/tests/functional/log_test_client.err +@@ -0,0 +1,2 @@ ++[MAIN |debug] ../log_client.c:64:hello ++[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2) diff --git a/tests/functional/log_test_client.sh b/tests/functional/log_test_client.sh new file mode 100755 -index 0000000..875871e +index 0000000..17e9254 --- /dev/null +++ b/tests/functional/log_test_client.sh -@@ -0,0 +1,22 @@ +@@ -0,0 +1,30 @@ +#!/bin/sh +# Copyright 2017 Red Hat, Inc. +# @@ -668,14 +675,32 @@ index 0000000..875871e +# You should have received a copy of the GNU Lesser General Public License +# along with libqb. If not, see . + -+./log_client >/dev/null 2>log_client.err.real -+diff -u ../log_client.err log_client.err.real ++./log_client >/dev/null 2>log_test_client.err.real ++ ++_pipeline='cat ../log_test_client.err' ++case "${CPPFLAGS}" in ++ *-DNLOG*) ++ _pipeline="${_pipeline} | \ ++ grep -Ev '^\[MAIN |info] \.\./log_client\.c'";; ++esac ++ ++eval "${_pipeline}" | diff -u - log_test_client.err.real +diff --git a/tests/functional/log_test_interlib_client.err b/tests/functional/log_test_interlib_client.err +new file mode 100644 +index 0000000..dc0de9c +--- /dev/null ++++ b/tests/functional/log_test_interlib_client.err +@@ -0,0 +1,4 @@ ++[MAIN |info] ../log_interlib_client.c:61:BEFORE ++[MAIN |info] ../log_interlib.c:47:aloha ++[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2) ++[MAIN |info] ../log_interlib_client.c:65:AFTER diff --git a/tests/functional/log_test_interlib_client.sh b/tests/functional/log_test_interlib_client.sh new file mode 100755 -index 0000000..59c5555 +index 0000000..e066cae --- /dev/null +++ b/tests/functional/log_test_interlib_client.sh -@@ -0,0 +1,22 @@ +@@ -0,0 +1,33 @@ +#!/bin/sh +# Copyright 2017 Red Hat, Inc. +# @@ -696,14 +721,25 @@ index 0000000..59c5555 +# You should have received a copy of the GNU Lesser General Public License +# along with libqb. If not, see . + -+./log_interlib_client >/dev/null 2>log_interlib_client.err.real -+diff -u ../log_interlib_client.err log_interlib_client.err.real ++./log_interlib_client >/dev/null 2>log_test_interlib_client.err.real ++ ++_pipeline='cat ../log_test_interlib_client.err' ++case "${CPPFLAGS}" in ++ *-DNLOG*) ++ _pipeline="${_pipeline} | \ ++ grep -Ev '^\[MAIN \|info] \.\./log_interlib_client\.c'";; ++ *-DNLIBLOG*) ++ _pipeline="${_pipeline} | \ ++ grep -Ev '^\[MAIN \|info\] \.\./log_interlib\.c'";; ++esac ++ ++eval "${_pipeline}" | diff -u - log_test_interlib_client.err.real diff --git a/tests/functional/log_test_mock.sh b/tests/functional/log_test_mock.sh new file mode 100755 -index 0000000..4489718 +index 0000000..145b9f4 --- /dev/null +++ b/tests/functional/log_test_mock.sh -@@ -0,0 +1,289 @@ +@@ -0,0 +1,310 @@ +#!/bin/sh +# Copyright 2017 Red Hat, Inc. +# @@ -763,6 +799,7 @@ index 0000000..4489718 +arch=x86_64 +mock_args="-r fedora-27-${arch}" +pkg_binutils_228=binutils-2.28-14.fc27 ++#pkg_binutils_228=binutils-2.27-23.fc27 # alternatively test with 2.27 ... +pkg_binutils_229=binutils-2.29-6.fc27 +#pkg_binutils_229=binutils-2.29.1-2.fc28 # alternatively test with 2.29.1 + @@ -890,10 +927,27 @@ index 0000000..4489718 +do_proceed () { + + _makevars= -+ case "$1" in -+ shell) shift; do_shell "$@"; return;; -+ -n) shift; _makevars='CPPFLAGS=-DNSELFCHECK';; -+ esac ++ _resultsdir_tag= ++ _selfcheck=1 ++ _clientlogging=1 ++ _interliblogging=1 ++ while :; do ++ case "$1" in ++ shell) shift; do_shell "$@"; return;; ++ -nsc) _resultsdir_tag="${_resultsdir_tag}$1"; shift; _selfcheck=0;; ++ -ncl) _resultsdir_tag="${_resultsdir_tag}$1"; shift; _clientlogging=0;; ++ -nil) _resultsdir_tag="${_resultsdir_tag}$1"; shift; _interliblogging=0;; ++ -*) do_die "Uknown option: $1";; ++ *) break;; ++ esac ++ done ++ ++ if test -n "${_resultsdir_tag}"; then ++ _makevars="CPPFLAGS=\"$(test "${_selfcheck}" -eq 1 || printf %s ' -DNSELFCHECK') \ ++ $(test "${_clientlogging}" -eq 1 || printf %s ' -DNLOG') \ ++ $(test "${_interliblogging}" -eq 1 || printf %s ' -DNLIBLOG')\"" ++ _makevars=$(echo ${_makevars}) ++ fi + + test -s "$1" || do_die "Not an input file: $1" + _libqb_descriptor_path="$1" @@ -903,8 +957,7 @@ index 0000000..4489718 + -p "${_libqb_descriptor_path}" \ + | sed -n '/\.tar/{s|\.tar\.[^.]*$||;p;q}')" + -+ _resultsdir="_results/$(date '+%y%m%d_%H%M%S')_${_libqb_descriptor}" -+ test -z "${_makevars}" || _resultsdir="${_resultsdir}_nsc" ++ _resultsdir="_results/$(date '+%y%m%d_%H%M%S')_${_libqb_descriptor}${_resultsdir_tag}" + mkdir -p "${_resultsdir}" + rm -f -- "${_resultsdir}/*" + @@ -955,7 +1008,8 @@ index 0000000..4489718 + do_install "${_pkg_binutils_interlib}" + + do_progress "building interlib with ${_libqb_descriptor_archive}" \ -+ "+ ${_pkg_binutils_interlib} [${_outfile}]" ++ "+ ${_pkg_binutils_interlib} [${_outfile}]" \ ++ "{${_makevars}}" + do_compile_interlib "${_libqb_descriptor_archive}" "${_makevars}" + ;; + esac @@ -975,7 +1029,8 @@ index 0000000..4489718 + "so as to build ${_client} [${_outfile_client}]" + do_install "${_pkg_binutils_client}" + do_progress "building ${_client} with ${_libqb_descriptor_archive}" \ -+ "+ ${_pkg_binutils_client} [${_outfile_client}]" ++ "+ ${_pkg_binutils_client} [${_outfile_client}]" \ ++ "{${_makevars}}" + do_compile_and_test_client "${_libqb_descriptor_archive}" \ + "${_client}" "${_resultsdir}" \ + "${_outfile_client}" "${_makevars}" @@ -984,10 +1039,12 @@ index 0000000..4489718 + done +} + -+test $# -eq 0 \ -+ && printf '%s\n %s\n %s\n %s\n %s\n %s\n' \ -+ "usage: $0 {[-n] | shell}" \ -+ "- use '-n' to suppress optional self-check (\"see whole story\")" \ ++{ test $# -eq 0 || test "$1" = -h || test "$1" = --help; } \ ++ && printf '%s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n' \ ++ "usage: $0 {[-n{sc,cl,il}]* | shell}" \ ++ "- use '-nsc' to suppress optional self-check (\"see whole story\")" \ ++ "- use '-ncl' to suppress client-side logging" \ ++ "- use '-nil' to suppress interlib-side logging" \ + "- 'make -C ../.. srpm' (or so) can generate the requested input" \ + " (in that case, apparently, refer to '../../libqb-X.src.rpm')" \ + "- _pkgs dir caches (intermediate or not) packages to work with" \ diff --git a/04-Med-add-extra-run-time-client-libqb-checks-that-logg.patch b/04-Med-add-extra-run-time-client-libqb-checks-that-logg.patch index 74b077b..a1642b3 100644 --- a/04-Med-add-extra-run-time-client-libqb-checks-that-logg.patch +++ b/04-Med-add-extra-run-time-client-libqb-checks-that-logg.patch @@ -1,4 +1,4 @@ -From fd5eb6a3b137342f5f9594ab4c0e8ac34ec5fb80 Mon Sep 17 00:00:00 2001 +From 4f0fceaaf38a04e9f1c067a7b581265b9ceb81de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 6 Oct 2017 17:17:26 +0200 Subject: [PATCH 4/6] Med: add extra run-time (client, libqb) checks that @@ -170,15 +170,15 @@ quake is all about. Signed-off-by: Jan Pokorný --- configure.ac | 1 + - include/qb/qblog.h | 63 ++++++++++++++++++++++++++++--- + include/qb/qblog.h | 95 ++++++++++++++++++++++++------- lib/libqb.pc.in | 3 +- - lib/log.c | 44 +++++++++++++++++++++ + lib/log.c | 44 ++++++++++++++ tests/functional/Makefile.am | 3 +- tests/functional/log.am | 2 +- - tests/functional/log_external/Makefile.am | 8 +++- - tests/functional/log_test_mock.sh | 13 ++++++- - tests/functional/syslog-stdout.py | 49 ++++++++++++++++++++++++ - 9 files changed, 173 insertions(+), 13 deletions(-) + tests/functional/log_external/Makefile.am | 8 ++- + tests/functional/log_test_mock.sh | 13 ++++- + tests/functional/syslog-stdout.py | 49 ++++++++++++++++ + 9 files changed, 189 insertions(+), 29 deletions(-) create mode 100755 tests/functional/syslog-stdout.py diff --git a/configure.ac b/configure.ac @@ -194,7 +194,7 @@ index 274b49c..5769e60 100644 fi diff --git a/include/qb/qblog.h b/include/qb/qblog.h -index d39803f..9474c16 100644 +index 7b6db8b..10cd62c 100644 --- a/include/qb/qblog.h +++ b/include/qb/qblog.h @@ -44,6 +44,7 @@ extern "C" { @@ -205,11 +205,28 @@ index d39803f..9474c16 100644 #endif /** -@@ -283,20 +284,70 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs); +@@ -283,33 +284,83 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs); extern struct qb_log_callsite QB_ATTR_SECTION_START[]; extern struct qb_log_callsite QB_ATTR_SECTION_STOP[]; -/* optional on-demand self-check of (1) toolchain sanity (prerequisite for +- the logging subsystem to work properly) and (2) non-void active use of +- logging (satisfied with a justifying existence of a logging callsite as +- defined with a @c qb_logt invocation) at the target (but see below), which +- is presumably assured by it's author as of relying on this very macro +- [technically, the symbols that happen to be resolved under the respective +- identifiers do not necessarily come from the same compilation unit level +- as when it's not the end program (or by induction, a library higher in +- the symbol resolution fall-through) but a shared library, the former takes +- a precedence unless it lacks use of logging on its own making its very +- section empty and hence without such boundary symbols provided at the +- respective level and thus deferring to lower priority symbol resolution +- stop -- despite this fuzzily targeted attestation, the check remains +- reasonable and should not harm anything]; +- only effective when link-time ("run-time amortizing") callsite collection +- is; as a side effect, it can ensure the boundary-denoting symbols for the +- target collection area are kept alive with some otherwise unkind linkers; +- may be extended in future for more in-depth self-validation */ +/* Related to the next macro that is -- unlike this one -- a public API */ +#ifndef _GNU_SOURCE +#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \ @@ -235,18 +252,25 @@ index d39803f..9474c16 100644 +linkage at fault and logging would not work reliably" \ + && work_s1 != work_s2); \ + dlclose(work_handle); } -+#endif ++#endif /* _GNU_SOURCE */ + +/** + * Optional on-demand self-check of (1) toolchain sanity (prerequisite for - * the logging subsystem to work properly) and (2) non-void active use of - * logging (satisfied with a justifying existence of a logging callsite as - * defined with a @c qb_logt invocation) at the target binary, which is - * presumably assured by it's author as of relying on this very macro; - * only effective when link-time ("run-time amortizing") callsite collection - * is; as a side effect, it can ensure the boundary-denoting symbols for the -- * target collection area are kept alive with some otherwise unkind linkers; -- * may be extended in future for more in-depth self-validation */ ++ * the logging subsystem to work properly) and (2) non-void active use of ++ * logging (satisfied with a justifying existence of a logging callsite as ++ * defined with a @c qb_logt invocation) at the target (but see below), which ++ * is presumably assured by it's author as of relying on this very macro ++ * [technically, the symbols that happen to be resolved under the respective ++ * identifiers do not necessarily come from the same compilation unit level ++ * as when it's not the end program (or by induction, a library higher in ++ * the symbol resolution fall-through) but a shared library, the former takes ++ * a precedence unless it lacks use of logging on its own making its very ++ * section empty and hence without such boundary symbols provided at the ++ * respective level and thus deferring to lower priority symbol resolution ++ * stop -- despite this fuzzily targeted attestation, the check remains ++ * reasonable and should not harm anything]; ++ * only effective when link-time ("run-time amortizing") callsite collection ++ * is; as a side effect, it can ensure the boundary-denoting symbols for the + * target collection area are kept alive with some otherwise unkind linkers. + * + * Applying this macro in the target program/library is strongly recommended @@ -275,13 +299,18 @@ index d39803f..9474c16 100644 +reliably" \ + && work_s1 != NULL && work_s2 != NULL); } \ + QB_NONAPI_LOG_INIT_DATA_EXTRA_; \ -+ /* original "cherry on the cake" check */ \ ++ /* finally, original, straightforward check */ \ + assert("non-empty implicit callsite section, otherwise target's \ +linkage at fault and logging would not work reliably" \ + && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \ void __attribute__ ((constructor)) name(void); #else #define QB_LOG_INIT_DATA(name) +-#endif ++#endif /* QB_HAVE_ATTRIBUTE_SECTION */ + + /** + * Internal function: use qb_log() or qb_logt() diff --git a/lib/libqb.pc.in b/lib/libqb.pc.in index 8a8d0ba..37d27b7 100644 --- a/lib/libqb.pc.in @@ -364,24 +393,24 @@ index bfd218f..3e9972e 100644 void diff --git a/tests/functional/Makefile.am b/tests/functional/Makefile.am -index 72f551e..c079009 100644 +index 0d34ae8..522fb61 100644 --- a/tests/functional/Makefile.am +++ b/tests/functional/Makefile.am @@ -19,5 +19,6 @@ MAINTAINERCLEANFILES = Makefile.in - EXTRA_DIST = GNUmakefile log_client.err log_interlib_client.err \ + EXTRA_DIST = GNUmakefile log_test_client.err log_test_interlib_client.err \ - log_test_client.sh log_test_interlib_client.sh log_test_mock.sh + log_test_client.sh log_test_interlib_client.sh \ + log_test_mock.sh syslog-stdout.py SUBDIRS = log_external log_internal diff --git a/tests/functional/log.am b/tests/functional/log.am -index 5fe1ae7..0753fa5 100644 +index e8e4740..80bccb0 100644 --- a/tests/functional/log.am +++ b/tests/functional/log.am @@ -20,7 +20,7 @@ MAINTAINERCLEANFILES = Makefile.in - CLEANFILES = log_client.err.real log_interlib_client.err.real + CLEANFILES = log_test_client.err.real log_test_interlib_client.err.real -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include +AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_builddir)/include -I$(top_srcdir)/include @@ -405,10 +434,10 @@ index 36aa0af..ca1c8a5 100644 +log_client_LDFLAGS = -lqb @client_dlopen_LIBS@ +liblog_inter_la_LIBADD = -lqb @client_dlopen_LIBS@ diff --git a/tests/functional/log_test_mock.sh b/tests/functional/log_test_mock.sh -index 4489718..5900f6c 100755 +index 145b9f4..cdfce1f 100755 --- a/tests/functional/log_test_mock.sh +++ b/tests/functional/log_test_mock.sh -@@ -165,10 +165,19 @@ do_compile_and_test_client () { +@@ -166,10 +166,19 @@ do_compile_and_test_client () { -exec rm -- {} \;" ;; esac diff --git a/05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch b/05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch index 0eb46c6..b885632 100644 --- a/05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch +++ b/05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch @@ -1,4 +1,4 @@ -From 011085ef22f7ca94cb3c0492e735abeb43acef42 Mon Sep 17 00:00:00 2001 +From dbe771c0ab30ded6f1d82b6ed9d61ac04560e913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 6 Oct 2017 17:17:26 +0200 Subject: [PATCH 5/6] High: bare fix for libqb logging not working with @@ -52,9 +52,9 @@ to be applied in that case as well. So regarding the solution itself, the core of the fix was sketched at the original Fedora targeted bug against binutils[2]. In short, we are using a custom linker script that (re)describes the mentioned custom -orphan output section, or better yet, assuredly pushes that section, -and more importantly, it's own boundary denoting symbols, through into -the resulting binary when it's being linked (as in compile-time step). +orphan output section, or better yet, assuredly pushes that section, and +more importantly, it's own boundary denoting symbols, through into the +resulting executable when it's being linked (as in compile-time step). This solution alone, while working for the non-libqb (more on that below) logging participants, is not good enough, as it requires all @@ -121,6 +121,19 @@ other participants in the logging, possibly linked with a more friendly linker, do utilize this orphan section, logging may silently break (another reason to require an explicit sign-off). +Another note, the particular self-check change slightly touched in the +previous commit but otherwise predating this whole effort by far needs +to be modified now once again, this time because linker-script-based +workaround for newer linkers as stated causes the section boundary +symbols to be present regardless if that section is utilized, leading +to a self-inflicted breakage due to these empty section symbols suddenly +winning in the symbol resolution mechanism (previously the empty section +would be dropped incl. the boundary symbols), causing problems down the +line. It also makes this very check self-contained in the same +compilation unit that trigggers it, whereas previously it used to be the +said "arbitrary" winner and things kept silently working just because +failure condition -- empty section -- would be implicitly isolated. + Last but not least, libqb itself needs to be linked with the mentioned "-Wl,foo.t" equivalent for its own outgoing log messages to be honoured under all circumstances, which is already achieved with the arrangement @@ -175,13 +188,12 @@ Deficiencies: in any aspect Open questions: -* what about binutils 2.99.1 partially mitigating the impact of the - above commits -* should we enable attribute((__section__)) for powerpc platforms? - it seems to work well there -- and related to that, we need to figure - out how static and dynamic call sites can live together -- say what - will happen to logging programs compiled with libqb w/o attribute - sections when the underlying libqb is flipped to the one with them... +* should we enable attribute((__section__)) for powerpc and other minor + platforms if the feature is proved to be working there as well? + and related to that, we need to figure out how static and dynamic call + sites can live together -- say what will happen to logging programs + compiled with libqb w/o attribute sections when the underlying libqb is + flipped to the one with them... * * * @@ -196,20 +208,22 @@ References: Signed-off-by: Jan Pokorný --- - configure.ac | 146 +++++++++++++++++++++++++++++++++++++++++------ - lib/Makefile.am | 67 ++++++++++++++++++++++ - lib/libqb.pc.in | 6 ++ + configure.ac | 147 +++++++++++++++++++++++++++++++++++++++++------ + include/qb/qbconfig.h.in | 2 + + include/qb/qblog.h | 37 ++++++++---- + lib/Makefile.am | 67 +++++++++++++++++++++ + lib/libqb.pc.in | 8 +++ lib/log.c | 7 +++ lib/qblog_script.la.in | 15 +++++ - lib/qblog_script.ld.in | 25 ++++++++ + lib/qblog_script.ld.in | 27 +++++++++ lib/qblog_script_noop.ld | 1 + - 7 files changed, 249 insertions(+), 18 deletions(-) + 10 files changed, 281 insertions(+), 30 deletions(-) create mode 100644 lib/qblog_script.la.in create mode 100644 lib/qblog_script.ld.in create mode 100644 lib/qblog_script_noop.ld diff --git a/configure.ac b/configure.ac -index 5769e60..57875c8 100644 +index 5769e60..2b4ed32 100644 --- a/configure.ac +++ b/configure.ac @@ -501,6 +501,14 @@ AC_ARG_ENABLE([debug], @@ -247,7 +261,7 @@ index 5769e60..57875c8 100644 if test "x${enable_slow_tests}" = xyes ; then AC_DEFINE([HAVE_SLOW_TESTS], 1,[have slow tests]) AC_MSG_NOTICE([Enabling Slow tests]) -@@ -618,33 +639,120 @@ AC_SUBST(HAVE_SLOW_TESTS) +@@ -618,33 +639,121 @@ AC_SUBST(HAVE_SLOW_TESTS) # --- callsite sections --- if test "x${GCC}" = xyes; then @@ -294,9 +308,10 @@ index 5769e60..57875c8 100644 + + # in the failing case (e.g. with ld from binutils 2.29), it's likely the + # following will fail readily in linkage (hidden symbol `__stop___verbose' -+ # in conftest is referenced by DSO), but keep the sensible test (in-binary -+ # symbol is expected to be propagated into the library, and to draw the -+ # full circle back to binary through standard return value passing; ++ # in conftest is referenced by DSO), but keep the sensible test ++ # (in-executable symbol is expected to be propagated into the library, ++ # and to draw the full circle back to the executable through standard ++ # return value passing; + # -rpath passed because LD_LIBRARY_PATH exporting is unwieldy here); + # moreover, "my_var" == 3 assertion above is necessary so that binutils + # 2.29.1+ will not slip other parts of the overall is-workaround-needed @@ -311,9 +326,9 @@ index 5769e60..57875c8 100644 + extern int __start___verbose[], __stop___verbose[]; + int test(void);]], + [[static int my_var __attribute__((section("__verbose"))) = 5; -+ assert("P:non-empty data section" ++ assert("E:non-empty data section" + && __start___verbose != __stop___verbose); -+ assert("P:no data section value loss" ++ assert("E:no data section value loss" + && my_var == test() /*5?*/);]] + ), + [gcc_has_attribute_section_visible=yes], @@ -346,9 +361,9 @@ index 5769e60..57875c8 100644 + extern int __start___verbose[], __stop___verbose[]; + int test(void);]], + [[static int my_var __attribute__((section("__verbose"))) = 5; -+ assert("P:non-empty data section" ++ assert("E:non-empty data section" + && __start___verbose != __stop___verbose); -+ assert("P:no data section value loss" ++ assert("E:no data section value loss" + && my_var == 5);]] + )], + [], @@ -384,7 +399,7 @@ index 5769e60..57875c8 100644 # --- ansi --- if test "x${enable_ansi}" = xyes && \ -@@ -726,9 +834,11 @@ AC_CONFIG_FILES([Makefile +@@ -726,9 +835,11 @@ AC_CONFIG_FILES([Makefile docs/Makefile docs/common.dox docs/html.dox @@ -398,6 +413,97 @@ index 5769e60..57875c8 100644 AC_OUTPUT +diff --git a/include/qb/qbconfig.h.in b/include/qb/qbconfig.h.in +index c1852e1..b0bf428 100644 +--- a/include/qb/qbconfig.h.in ++++ b/include/qb/qbconfig.h.in +@@ -27,8 +27,10 @@ + /* need atomic memory barrier */ + #undef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED + ++#ifndef QB_KILL_ATTRIBUTE_SECTION + /* Enabling code using __attribute__((section)) */ + #undef QB_HAVE_ATTRIBUTE_SECTION ++#endif /* QB_KILL_ATTRIBUTE_SECTION */ + + /* versioning info: MAJOR, MINOR, MICRO, and REST components */ + #undef QB_VER_MAJOR +diff --git a/include/qb/qblog.h b/include/qb/qblog.h +index 10cd62c..07ae4c3 100644 +--- a/include/qb/qblog.h ++++ b/include/qb/qblog.h +@@ -286,15 +286,17 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[]; + + /* Related to the next macro that is -- unlike this one -- a public API */ + #ifndef _GNU_SOURCE +-#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \ ++#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \ + _Pragma(QB_PP_STRINGIFY(GCC warning QB_PP_STRINGIFY( \ + without "_GNU_SOURCE" defined (directly or not) \ +- qb_log_init_data cannot check sanity of libqb proper))) ++ qb_log_init_data cannot check sanity of libqb proper \ ++ nor ))) + #else +-#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \ ++#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \ + /* libqb sanity (locating libqb by it's relatively unique \ + -- and currently only such per-linkage global one -- \ + non-functional symbol, due to possible confusion otherwise) */ \ ++ { Dl_info work_dli; \ + if (dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli) \ + && (work_handle = dlopen(work_dli.dli_fname, \ + RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ +@@ -308,7 +310,22 @@ linkage at fault and logging would not work reliably" \ + assert("libqb's callsite section non-empty, otherwise libqb's \ + linkage at fault and logging would not work reliably" \ + && work_s1 != work_s2); \ +- dlclose(work_handle); } ++ dlclose(work_handle); } \ ++ /* finally, slightly modified original, straightforward check */ \ ++ if (dladdr(dlsym(RTLD_DEFAULT, QB_PP_STRINGIFY(name)), &work_dli) \ ++ && (work_handle = dlopen(work_dli.dli_fname, \ ++ RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ ++ work_s1 = (struct qb_log_callsite *) \ ++ dlsym(work_handle, QB_ATTR_SECTION_START_STR); \ ++ work_s2 = (struct qb_log_callsite *) \ ++ dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \ ++ assert("target's own callsite section observable, otherwise \ ++target's own linkage at fault and logging would not work reliably" \ ++ && work_s1 != NULL && work_s2 != NULL); \ ++ assert("target's own callsite section non-empty, otherwise \ ++target's own linkage at fault and logging would not work reliably" \ ++ && work_s1 != work_s2); \ ++ dlclose(work_handle); } } + #endif /* _GNU_SOURCE */ + + /** +@@ -341,22 +358,18 @@ linkage at fault and logging would not work reliably" \ + void name(void); \ + void name(void) { \ + void *work_handle; struct qb_log_callsite *work_s1, *work_s2; \ +- Dl_info work_dli; \ +- /* our own (target's) sanity */ \ ++ /* our own (target's) sanity, or possibly that of higher level \ ++ symbol resolution site */ \ + if ((work_handle = dlopen(NULL, RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ + work_s1 = (struct qb_log_callsite *) \ + dlsym(work_handle, QB_ATTR_SECTION_START_STR); \ + work_s2 = (struct qb_log_callsite *) \ + dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \ +- assert("target's callsite section self-observable, otherwise \ ++ assert("target's callsite section observable, otherwise \ + target's and/or libqb's linkage at fault and logging would not work \ + reliably" \ + && work_s1 != NULL && work_s2 != NULL); } \ +- QB_NONAPI_LOG_INIT_DATA_EXTRA_; \ +- /* finally, original, straightforward check */ \ +- assert("non-empty implicit callsite section, otherwise target's \ +-linkage at fault and logging would not work reliably" \ +- && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \ ++ QB_NONAPI_LOG_INIT_DATA_EXTRA_(name); } \ + void __attribute__ ((constructor)) name(void); + #else + #define QB_LOG_INIT_DATA(name) diff --git a/lib/Makefile.am b/lib/Makefile.am index 0bebeb5..ff5b3b4 100644 --- a/lib/Makefile.am @@ -494,10 +600,10 @@ index 0bebeb5..ff5b3b4 100644 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libqb.pc diff --git a/lib/libqb.pc.in b/lib/libqb.pc.in -index 37d27b7..bdcd3c8 100644 +index 37d27b7..65d3b8e 100644 --- a/lib/libqb.pc.in +++ b/lib/libqb.pc.in -@@ -8,5 +8,11 @@ Version: @PACKAGE_VERSION@ +@@ -8,5 +8,13 @@ Version: @PACKAGE_VERSION@ Description: libqb Requires: Libs: -L${libdir} -lqb @client_dlopen_LIBS@ @@ -507,6 +613,8 @@ index 37d27b7..bdcd3c8 100644 +# try "-l:libqb.so." link switch (right available, +# for example, directly within libqb.so plaintext) that bypasses +# said linker script -- but beware, logging problems may ensue. ++# That can be partially mitigated with QB_KILL_ATTRIBUTE_SECTION ++# macro defined when compiling, but testing remains a must. Libs.private: @LIBS@ Cflags: -I${includedir} diff --git a/lib/log.c b/lib/log.c @@ -550,10 +658,10 @@ index 0000000..f262df8 +inherited_linker_flags=-Wl,@abs_builddir@/qblog_script.ld diff --git a/lib/qblog_script.ld.in b/lib/qblog_script.ld.in new file mode 100644 -index 0000000..fed826b +index 0000000..2ee2da0 --- /dev/null +++ b/lib/qblog_script.ld.in -@@ -0,0 +1,25 @@ +@@ -0,0 +1,27 @@ +#include +/* GNU ld script + This atypical arrangement enforces global visibility of boundary symbols @@ -569,6 +677,8 @@ index 0000000..fed826b + try "-l:libqb.so." link switch (right available, + for example, directly within libqb.so plaintext) that bypasses + said linker script -- but beware, logging problems may ensue. ++ That can be partially mitigated with QB_KILL_ATTRIBUTE_SECTION ++ macro defined when compiling, but testing remains a must. + */ +SECTIONS { +#ifdef QB_HAVE_ATTRIBUTE_SECTION diff --git a/06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch b/06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch index 5ecb09e..f689f6e 100644 --- a/06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch +++ b/06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch @@ -1,4 +1,4 @@ -From d24e62a6b144a0532b1e472744ebbb13aa0221c4 Mon Sep 17 00:00:00 2001 +From eb0c29d0213784597b7fdffb24e79d9f0774b8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 6 Oct 2017 17:17:26 +0200 Subject: [PATCH 6/6] Low: fix internal object symbol's leak & expose run-time @@ -13,9 +13,9 @@ hence it's presumably safe to make it static as it's meant to be. On the other hand, QB_LOG_INIT_DATA macro from qblog.h has already started to depend on that symbol so as to locate the library handle for libqb itself correctly. This is trivially fixed by finally exposing -library versioning info in run-time through objects identified by the -compile-time/static counterparts from qbconfig.h header file, with -lower-casing applied on originally upper-cased macro identifiers. +library versioning info in run-time through objects a structure with +members corresponding to compile-time/static counterparts from +qbconfig.h header file, plus lower-cased equivalent of QB_VER_STR. Better than to roll out a futile data object serving as an artificial anchor for the above purpose, and this was a while due, afterall. @@ -24,68 +24,71 @@ In turn, also bump "current" and "age" of fields of the libtool's Signed-off-by: Jan Pokorný --- - include/qb/qbconfig.h.in | 5 ++++- - include/qb/qblog.h | 8 +++++--- - include/qb/qbutil.h | 11 +++++++++++ - lib/Makefile.am | 2 +- - lib/log.c | 10 ++++++---- - lib/log_format.c | 2 +- - lib/util.c | 7 +++++++ - tests/functional/log_client.c | 4 ++++ - tests/functional/log_client.err | 2 +- - 9 files changed, 40 insertions(+), 11 deletions(-) + include/qb/qbconfig.h.in | 7 ++++++- + include/qb/qblog.h | 8 +++++--- + include/qb/qbutil.h | 11 +++++++++++ + lib/Makefile.am | 2 +- + lib/log.c | 10 ++++++---- + lib/log_format.c | 2 +- + lib/util.c | 10 ++++++++++ + tests/functional/log_client.c | 4 ++++ + tests/functional/log_test_client.err | 2 +- + 9 files changed, 45 insertions(+), 11 deletions(-) diff --git a/include/qb/qbconfig.h.in b/include/qb/qbconfig.h.in -index c1852e1..1b92794 100644 +index b0bf428..19d14bf 100644 --- a/include/qb/qbconfig.h.in +++ b/include/qb/qbconfig.h.in -@@ -30,7 +30,10 @@ - /* Enabling code using __attribute__((section)) */ +@@ -32,7 +32,12 @@ #undef QB_HAVE_ATTRIBUTE_SECTION + #endif /* QB_KILL_ATTRIBUTE_SECTION */ -/* versioning info: MAJOR, MINOR, MICRO, and REST components */ +/* versioning info: MAJOR, MINOR, MICRO, and REST components; + note that static compile-time info is not that useful as consulting -+ the lower-cased counterparts directly from libqb in run-time -+ (see qbutil.h), but that was only introduced after v1.0.2 */ ++ the respectively named members of qb_version struct constant under ++ @c qb_ver identifier (or @qb_ver_str equivalent of the local ++ upper-cased value) directly from libqb in run-time (see qbutil.h), ++ but that was only introduced after v1.0.2 */ #undef QB_VER_MAJOR #undef QB_VER_MINOR #undef QB_VER_MICRO diff --git a/include/qb/qblog.h b/include/qb/qblog.h -index 9474c16..56fdd6a 100644 +index 07ae4c3..a059fb5 100644 --- a/include/qb/qblog.h +++ b/include/qb/qblog.h -@@ -293,9 +293,11 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[]; +@@ -294,10 +294,12 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[]; #else - #define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \ + #define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \ /* libqb sanity (locating libqb by it's relatively unique \ - -- and currently only such per-linkage global one -- \ - non-functional symbol, due to possible confusion otherwise) */ \ -- if (dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli) \ + non-functional symbols -- the two are mutually exclusive, the \ + ordinarily latter was introduced by accident, the former is \ + intentional -- due to possible confusion otherwise) */ \ + { Dl_info work_dli; \ +- if (dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli) \ + if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli) \ + || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli)) \ && (work_handle = dlopen(work_dli.dli_fname, \ RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ work_s1 = (struct qb_log_callsite *) \ diff --git a/include/qb/qbutil.h b/include/qb/qbutil.h -index bfce349..a03bdf8 100644 +index bfce349..b02ce8d 100644 --- a/include/qb/qbutil.h +++ b/include/qb/qbutil.h @@ -289,6 +289,17 @@ uint64_t qb_util_stopwatch_time_split_get(qb_util_stopwatch_t *sw, uint32_t receint, uint32_t older); -+/** Major component of the library version */ -+extern const uint8_t qb_ver_major; -+/** Minor component of the library version */ -+extern const uint8_t qb_ver_minor; -+/** Micro component of the library version */ -+extern const uint8_t qb_ver_micro; -+/** Rest (pertaining the mid-release-point) component of the library version */ -+extern const char *const qb_ver_rest; ++/** Structured library versioning info */ ++extern const struct qb_version { ++ uint8_t major; /**< Major component */ ++ uint8_t minor; /**< Minor component */ ++ uint8_t micro; /**< Micro component */ ++ const char *rest; /**< Rest (pertaining the mid-release-point) */ ++} qb_ver; ++ +/** Complete library versioning info as a string */ +extern const char *const qb_ver_str; + @@ -106,7 +109,7 @@ index ff5b3b4..a428975 100644 source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \ array.c loop.c loop_poll.c loop_job.c \ diff --git a/lib/log.c b/lib/log.c -index e4b77d5..df5ce5c 100644 +index 514103f..37f1e4e 100644 --- a/lib/log.c +++ b/lib/log.c @@ -892,10 +892,12 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority) @@ -140,7 +143,7 @@ index 712f447..e7e1f40 100644 #if defined(LOG_AUTHPRIV) {"authpriv", LOG_AUTHPRIV}, diff --git a/lib/util.c b/lib/util.c -index 6181a25..4693e58 100644 +index 6181a25..a510bd1 100644 --- a/lib/util.c +++ b/lib/util.c @@ -23,6 +23,7 @@ @@ -151,18 +154,21 @@ index 6181a25..4693e58 100644 #include #include -@@ -372,3 +373,9 @@ qb_util_stopwatch_time_split_get(qb_util_stopwatch_t *sw, +@@ -372,3 +373,12 @@ qb_util_stopwatch_time_split_get(qb_util_stopwatch_t *sw, } return (time_start - time_end) / QB_TIME_NS_IN_USEC; } + -+const uint8_t qb_ver_major = QB_VER_MAJOR; -+const uint8_t qb_ver_minor = QB_VER_MINOR; -+const uint8_t qb_ver_micro = QB_VER_MICRO; -+const char *const qb_ver_rest = QB_VER_REST; ++const struct qb_version qb_ver = { ++ .major = QB_VER_MAJOR, ++ .minor = QB_VER_MINOR, ++ .micro = QB_VER_MICRO, ++ .rest = QB_VER_REST, ++}; ++ +const char *const qb_ver_str = QB_VER_STR; diff --git a/tests/functional/log_client.c b/tests/functional/log_client.c -index aa6ebe1..3612dab 100644 +index c60d657..cb3e20b 100644 --- a/tests/functional/log_client.c +++ b/tests/functional/log_client.c @@ -53,6 +53,10 @@ main(int32_t argc, char *argv[]) @@ -176,13 +182,13 @@ index aa6ebe1..3612dab 100644 #if 0 printf("--\n"); qb_log_callsites_dump(); -diff --git a/tests/functional/log_client.err b/tests/functional/log_client.err -index 0ae7665..c9c955c 100644 ---- a/tests/functional/log_client.err -+++ b/tests/functional/log_client.err +diff --git a/tests/functional/log_test_client.err b/tests/functional/log_test_client.err +index cb0ff3c..29b9db0 100644 +--- a/tests/functional/log_test_client.err ++++ b/tests/functional/log_test_client.err @@ -1,2 +1,2 @@ --[MAIN |debug] ../log_client.c:63:hello -+[MAIN |debug] ../log_client.c:67:hello +-[MAIN |debug] ../log_client.c:64:hello ++[MAIN |debug] ../log_client.c:68:hello [libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2) -- 2.14.2 diff --git a/libqb.spec b/libqb.spec index b41f8cf..01e2f6b 100644 --- a/libqb.spec +++ b/libqb.spec @@ -2,7 +2,7 @@ Name: libqb Version: 1.0.2 -Release: 10%{?dist} +Release: 11%{?dist} Summary: An IPC library for high performance servers Group: System Environment/Libraries @@ -77,6 +77,9 @@ developing applications that use %{name}. %{_mandir}/man3/qb*3* %changelog +* Wed Oct 18 2017 Jan Pokorný - 1.0.2-11 +- Evolution of the previous (rhbz#1478089, rhbz#1487787) + * Fri Oct 13 2017 Jan Pokorný - 1.0.2-10 - Evolution of the previous (rhbz#1478089, rhbz#1487787)