1.0.2-10 - Evolution of the previous (rhbz#1478089, rhbz#1487787)

Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
This commit is contained in:
Jan Pokorný 2017-10-13 23:01:29 +02:00
parent c61edd4d30
commit 95877b0e29
No known key found for this signature in database
GPG Key ID: 61BBB23A9E8F8DE2
8 changed files with 830 additions and 380 deletions

View File

@ -1,4 +1,4 @@
From 8bfe49d79c1b7ae1aa4b7b22b627afa40a4a08d2 Mon Sep 17 00:00:00 2001
From a7014f6d411685a5691be0f59c0634e165771811 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 1/6] Med: qblog.h: better explanation + behaviour of
@ -12,7 +12,10 @@ put a better description for the macro. Also based on poor user
experience in case that feature does not work well, say because
the linker deliberately changes the previously settled visibility
of the section boundary symbols (happened in ld from binutils-2.29,
fix is forthcoming), tweak the assertion message a bit:
fix is forthcoming), tweak the assertion message a bit, together
with an extension of the general intro to point that macro out.
Also play fair, include the <assert.h> header, which this macro
requires.
- use case:
/usr/sbin/pacemakerd --features
@ -23,21 +26,59 @@ fix is forthcoming), tweak the assertion message a bit:
- after:
pacemakerd: utils.c:69: common:
Assertion `("non-empty callsite section", QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP)' failed.
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).
And regarding:
> as a side effect, it can ensure the boundary-denoting symbols for
> the target collection area are kept alive with some otherwise unkind
> linkers
this was actually empirically discovered in one particular combination
with ld.bfd @ binutils 2.29, and extensively with 2.29.1 (placing here
a forward reference for the following commits that elaborate on the
libqb-target cross-combination matrix and the findings).
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
include/qb/qblog.h | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
include/qb/qblog.h | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
index 3cb4eef..d38449d 100644
index 3cb4eef..d39803f 100644
--- a/include/qb/qblog.h
+++ b/include/qb/qblog.h
@@ -268,11 +268,18 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs);
@@ -42,6 +42,10 @@ extern "C" {
#undef QB_HAVE_ATTRIBUTE_SECTION
#endif /* S_SPLINT_S */
+#ifdef QB_HAVE_ATTRIBUTE_SECTION
+#include <assert.h> /* possibly needed for QB_LOG_INIT_DATA */
+#endif
+
/**
* @file qblog.h
* The logging API provides four main parts (basics, filtering, threading & blackbox).
@@ -64,6 +68,17 @@ extern "C" {
* }
* @endcode
*
+ * @note
+ * In practice, such a minimalistic approach hardly caters real use cases.
+ * 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
+ * linker-assisted collection of callsite data silently fails, which
+ * could otherwise go unnoticed, causing troubles down the road.
+ *
+ *
* @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);
extern struct qb_log_callsite QB_ATTR_SECTION_START[];
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
@ -46,18 +87,20 @@ index 3cb4eef..d38449d 100644
- void name(void); \
- void name(void) \
- { if (QB_ATTR_SECTION_START == QB_ATTR_SECTION_STOP) assert(0); } \
+/* optional on-demand self-check of (1) toolchain sanity and (2) non-void
+ * (implied by the justifying existence of at least a single logging callsite
+ * ~ qb_logt invocation) employment of logging subsystem in the target binary,
+ * which is presumably assured by it's author as of relying on this macro;
+/* 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 available and may be extended in future for more in-depth self-validation
+ */
+ * 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) \
+ { assert(("non-empty callsite section", \
+ QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP)); } \
+ { assert("non-empty callsite section" \
+ && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \
void __attribute__ ((constructor)) name(void);
#else
#define QB_LOG_INIT_DATA(name)

View File

@ -1,4 +1,4 @@
From d6491970c1e050dae3fc9b65fd34e4c170ca50a0 Mon Sep 17 00:00:00 2001
From ccfe20a89b3099f17f22971995ace787356ed5f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 2/6] build: configure: run attribute section test through
@ -15,14 +15,14 @@ of the run-time error signalling through assertions.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
configure.ac | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
configure.ac | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/configure.ac b/configure.ac
index 22630ba..727b8f0 100644
index 22630ba..478194c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -620,15 +620,17 @@ AC_SUBST(HAVE_SLOW_TESTS)
@@ -620,15 +620,19 @@ AC_SUBST(HAVE_SLOW_TESTS)
if test "x${GCC}" = xyes; then
AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections])
if test "x${ac_cv_link_attribute_section}" = x ; then
@ -40,9 +40,11 @@ index 22630ba..727b8f0 100644
+ [[#include <assert.h>
+ extern void * __start___verbose, * __stop___verbose;]],
+ [[static int my_var __attribute__((section("__verbose"))) = 5;
+ assert(("non-empty data section", __start___verbose != __stop___verbose));
+ assert(("no data section value loss", my_var == 5));
+ ]]),
+ assert("non-empty data section"
+ && __start___verbose != __stop___verbose);
+ assert("no data section value loss"
+ && my_var == 5);]]
+ ),
+ [gcc_has_attribute_section=yes],
+ [gcc_has_attribute_section=no]
+ )

View File

@ -1,4 +1,4 @@
From 9e0f0f6d8045a1bd5482a6e704300a324458a96a Mon Sep 17 00:00:00 2001
From c489cb378cd8ad7a7a089067e39b65b0c359c60b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 3/6] tests: new sort of tests dubbed "functional", cover
@ -14,7 +14,9 @@ checking harness, usually available through "make check", but not to be
confused with regular unit + broader tests). These test are meant to be
compiled on demand only, not during the standard building routine, for
which a trick leveraging GNUmakefile-Makefile precedence with GNU make
was devised.
was devised (GNU make/gmake already required by configure script for
other reasons [some pattern-based matching not available with FreeBSD's
default "make", IIRC], so this introduces no new build dependency).
The respective new tests are meant to simulate logging variants in two
different library consumption models:
@ -56,7 +58,7 @@ Current state for this matrix, in which participants 1. - 3. map like:
3. ~ libX(Y) [a.k.a. interlib]
and where "X(Y)" denotes "X linked with linker Y":
X(a) .. ld.bfd < 2.29
X(b) .. ld.bfd = 2.29 (and likely on),
X(b) .. ld.bfd = 2.29 (and only 2.29),
goes like this:
+=========+=========+=========+=========+=========+=========+=========+
@ -68,6 +70,18 @@ goes like this:
# x = b # BAD[*A] | BAD[*B] : BAD[*C] # BAD[*1] | BAD[*C] : BAD[*3] #
+=========+=========+=========+=========+=========+=========+=========+
whereas if we swap 2.29 for 2.29.1, i.e., X(b) .. ld.bfd = 2.29.1, we
can observe a somewhat simpler story (DEP ~ "depends"):
+=========+=========+=========+=========+=========+=========+=========+
#client(x)# libqb(a) usage # libqb(b) usage #
# vvv #---------+---------+---------+---------+---------+---------+
# V # direct | libX(a) : libX(b) # direct | libX(a) : libX(b) #
+=========+=========+=========+=========+=========+=========+=========+
# x = a # OK | OK : DEP[*J] # BAD[*1] | BAD[*1] : BAD[*L] #
# x = b # DEP[*I] | DEP[*I] : DEP[*K] # BAD[*1] | BAD[*1] : BAD[*L] #
+=========+=========+=========+=========+=========+=========+=========+
[*1] client logging not working
[*2] interlib logging not working
[*3] both client and interlib logging not working
@ -81,15 +95,29 @@ goes like this:
[*D] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which makes it boil down just to [*1] (hypothesis: mere internal
self-reference to the section's boundary symbols makes them
overcome some kind of garbage collection at the linkage stage,
so they are exposed even they wouldn't be otherwise as demonstrated
with the initial, plain case of [*3])
overcome some kind of symbol garbage collection at the linkage
stage, so they are exposed even they wouldn't be otherwise as
demonstrated with the initial, plain case of [*3])
[*I] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
which makes it, likely through self-reference keepalive (see
below) work OK
[*J] boils down to [*2], unless QB_LOG_INIT_DATA used on interlib side,
which makes it, likely through self-reference keepalive (see
below) work OK
[*K] boils down to [*3], unless QB_LOG_INIT_DATA used on both client
and interlib side, which makes it, likely through self-reference
keepalive (see below) work OK (it's expected that this a mere
composite of situations [*I] and [*J] with consequences as stated)
[*L] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side
(sufficient?), which makes it, likely through self-reference
keepalive (see below) boil down just to [*1]
Note: as observed with [*D] case (libqb linked with ld.bfd < 2.29
whereas interlib and its client linked with ld.bfd = 2.29), the exact
availability of a working logging doesn't depend solely on the linkers
in question, but generally (further investigation out of scope) the
conclusion is that when 2.29+ ld.bfd is involved somewhere in the chain
conclusion is that when 2.29 ld.bfd is involved somewhere in the chain
of logging-related discrete compilation units, also (self-)referencing
of the section's boundary denoting symbols is a deciding factor whether
particular logging source will be honored. This may be a result of
@ -114,10 +142,10 @@ Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
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 | 285 +++++++++++++++++++++++++++
18 files changed, 704 insertions(+), 2 deletions(-)
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(-)
create mode 100644 tests/functional/GNUmakefile
create mode 100644 tests/functional/Makefile.am
create mode 100644 tests/functional/log.am
@ -133,7 +161,7 @@ Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
create mode 100755 tests/functional/log_test_mock.sh
diff --git a/configure.ac b/configure.ac
index 727b8f0..db7bc68 100644
index 478194c..274b49c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([lib/ringbuffer.c])
@ -145,7 +173,7 @@ index 727b8f0..db7bc68 100644
dnl automake >= 1.11 offers --enable-silent-rules for suppressing the output from
dnl normal compilation. When a failure occurs, it will then display the full
dnl command line
@@ -715,6 +715,9 @@ AC_CONFIG_FILES([Makefile
@@ -717,6 +717,9 @@ AC_CONFIG_FILES([Makefile
lib/libqb.pc
tools/Makefile
tests/Makefile
@ -155,7 +183,7 @@ index 727b8f0..db7bc68 100644
tests/test.conf
examples/Makefile
docs/Makefile
@@ -722,6 +725,8 @@ AC_CONFIG_FILES([Makefile
@@ -724,6 +727,8 @@ AC_CONFIG_FILES([Makefile
docs/html.dox
docs/man.dox])
@ -672,10 +700,10 @@ index 0000000..59c5555
+diff -u ../log_interlib_client.err log_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..fb2c02c
index 0000000..4489718
--- /dev/null
+++ b/tests/functional/log_test_mock.sh
@@ -0,0 +1,285 @@
@@ -0,0 +1,289 @@
+#!/bin/sh
+# Copyright 2017 Red Hat, Inc.
+#
@ -736,6 +764,7 @@ index 0000000..fb2c02c
+mock_args="-r fedora-27-${arch}"
+pkg_binutils_228=binutils-2.28-14.fc27
+pkg_binutils_229=binutils-2.29-6.fc27
+#pkg_binutils_229=binutils-2.29.1-2.fc28 # alternatively test with 2.29.1
+
+#
+# prettified reporters
@ -875,7 +904,7 @@ index 0000000..fb2c02c
+ | sed -n '/\.tar/{s|\.tar\.[^.]*$||;p;q}')"
+
+ _resultsdir="_results/$(date '+%y%m%d_%H%M%S')_${_libqb_descriptor}"
+ test -z "${_makevars}" || _resultsdir="${_resultsdir}_sc"
+ test -z "${_makevars}" || _resultsdir="${_resultsdir}_nsc"
+ mkdir -p "${_resultsdir}"
+ rm -f -- "${_resultsdir}/*"
+
@ -895,16 +924,19 @@ index 0000000..fb2c02c
+ esac
+
+ do_progress "installing ${_pkg_binutils_libqb} so as to build" \
+ " libqb [${_outfile_qb}]"
+ "libqb [${_outfile_qb}]"
+ do_install "${_pkg_binutils_libqb}"
+
+ do_progress "building ${_libqb_descriptor_path} with" \
+ " ${_pkg_binutils_libqb} [${_outfile_qb}]"
+ "${_pkg_binutils_libqb} [${_outfile_qb}]"
+ do_buildsrpm "${_libqb_descriptor_path}" "${_dist}"
+
+ do_progress "installing ${_libqb_descriptor}-based packages" \
+ " built with ${_pkg_binutils_libqb} [${_outfile_qb}]"
+ "built with ${_pkg_binutils_libqb} [${_outfile_qb}]"
+ do_install "${_libqb_descriptor}"
+ # from now on, we can work fully offline, also to speed
+ # the whole thing up (and not to bother the mirrors)
+ mock_args="${mock_args} --offline"
+
+ for _pkg_binutils_interlib in none "${pkg_binutils_228}" "${pkg_binutils_229}"; do
+
@ -919,11 +951,11 @@ index 0000000..fb2c02c
+ none) ;;
+ *)
+ do_progress "installing ${_pkg_binutils_interlib}" \
+ " so as to build interlib [${_outfile}]"
+ "so as to build interlib [${_outfile}]"
+ do_install "${_pkg_binutils_interlib}"
+
+ do_progress "building interlib with ${_libqb_descriptor_archive}" \
+ " + ${_pkg_binutils_interlib} [${_outfile}]"
+ "+ ${_pkg_binutils_interlib} [${_outfile}]"
+ do_compile_interlib "${_libqb_descriptor_archive}" "${_makevars}"
+ ;;
+ esac
@ -940,10 +972,10 @@ index 0000000..fb2c02c
+ esac
+
+ do_progress "installing ${_pkg_binutils_client}" \
+ " so as to build ${_client} [${_outfile_client}]"
+ "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}]"
+ do_compile_and_test_client "${_libqb_descriptor_archive}" \
+ "${_client}" "${_resultsdir}" \
+ "${_outfile_client}" "${_makevars}"

View File

@ -0,0 +1,490 @@
From 0c8500a0c15f54250ce93c724451c36cde8b4499 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 4/6] Med: add extra run-time (client, libqb) checks that
logging will work
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The table at the bottom concludes how the test matrix overview
introduced with a message for the preceding commit (also introducing
log_test_mock.sh runner which got reused here) looks as of this
refreshed sanity check, once QB_LOG_INIT_DATA macro at hand gets
applied (meaning "for non-libqb logging participants" so as not
complicate the matrix further). That macro is nothing triggered
directly, it will just plant a constructor-like function (to be
invoked automatically early in the execution) that will run through
the checks (one original and couple of new ones as of this changeset).
Note that for libqb users, this implies a new link dependency on libdl,
because they may opt-in for refreshed QB_LOG_INIT_DATA sanity check that
calls out to dlopen/dlsym/dladdr directly in case of "attribute section"
being available for the particular platform, and hence immediately needs
those symbols resolved in link time. Hence, add this conditional link
dependency to libqb.pc pkg-config file under Libs variable -- we
actually restore the occurrence of "-ldl" there as it used to be present
until commit 56754d0. While doing so, also move immediate link
dependencies of libqb (if any, currently not but that may be
a regression arising from the cleanup related to the mentioned commit)
represented with the LIBS autoconf variable under Libs.private variable
in libqb.pc, where it belongs per pkg-config documentation.
The promised table follows, but first as a recap, "X(Y)" denotes
"X linked with linker Y":
X(a) .. ld.bfd < 2.29
X(b) .. ld.bfd = 2.29 (and only 2.29)
goes like this (values in <angle brackets> denote non-trivial change
[not mere rewording] introduced as of this commit, in comparison to
the table stated in the preceding commit):
+=========+=========+=========+=========+=========+=========+=========+
#client(x)# libqb(a) usage # libqb(b) usage #
# vvv #---------+---------+---------+---------+---------+---------+
# V # direct | libX(a) : libX(b) # direct | libX(a) : libX(b) #
+=========+=========+=========+=========+=========+=========+=========+
# x = a # OK | OK : BAD[*2] #<BAD[*E]>|<BAD[*F]>:<BAD[*G]>#
# x = b # BAD[*A] | BAD[*B] : BAD[*C] #<BAD[*E]>|<BAD[*F]>:<BAD[*G]>#
+=========+=========+=========+=========+=========+=========+=========+
whereas if we swap 2.29 for 2.29.1, i.e., X(b) .. ld.bfd = 2.29.1, we
can observe a somewhat simpler story (DEP ~ "depends"):
Woefully, nothing changes if we swap binutils 2.29.1 for 2.29, i.e.,
X(b) .. ld.bfd = 2.29.1. The second table from the previous commit
hence remains the same. The added sanity checks are useful nonetheless,
consider for example, that attribute-section-less libqb is what gets
run-time linked to an attribute-section-full target. The most precise
check we could use -- a custom logger function applied in a self-test
scheme -- is not available at the point the macro-defined function gets
invoked, simply because qb_log_init hasn't been invoked by the time
that constructor gets triggered. However, what we can do is to add
a non-trapping libqb-residing reverse-testing of the client space that
invokes qb_log_init (being intrusive all of a sudden at some unknown
execution point, as opposed to constructor-like function, seems pretty
bad idea + libqb as a library is a mere helper, not an undertaker :)
-- this check can at least announce, via syslog (the only
initially enabled logging target) that the target logging won't work.
After incorporating such a change (and extending log_test_mock.sh so as
to capture syslog stream within the container), nothing changes with the
table above, but desirably changes with "X(b) .. ld.bfd = 2.29.1" one:
+=========+=========+=========+=========+=========+=========+=========+
#client(x)# libqb(a) usage # libqb(b) usage #
# vvv #---------+---------+---------+---------+---------+---------+
# V # direct | libX(a) : libX(b) # direct | libX(a) : libX(b) #
+=========+=========+=========+=========+=========+=========+=========+
# x = a # OK | OK : DEP[*J] #<BAD[*M]>|<BAD[*M]>:<BAD[*L]>#
# x = b #<DEP[*N]>| DEP[*I] :<DEP[*O]>#<BAD[*M]>|<BAD[*M]>:<BAD[*L]>#
+=========+=========+=========+=========+=========+=========+=========+
[*1] client logging not working
[*2] interlib logging not working
[*3] both client and interlib logging not working
[*A] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
which then fails on
"non-empty implicit callsite section, otherwise target's linkage at
fault and logging would not work reliably"
assertion
[*B] boils down to [*1], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"non-empty implicit callsite section, otherwise target's linkage at
fault and logging would not work reliably"
assertion
[*C] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"non-empty implicit callsite section, otherwise target's linkage at
fault and logging would not work reliably"
assertion
[*E] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
which then fails on
"target's callsite section self-observable, otherwise target's
and/or libqb's linkage at fault and logging would not work reliably"
assertion
[*F] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"libqb's callsite section non-empty, otherwise libqb's linkage at
fault and logging would not work reliably"
assertion
[*G] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"target's callsite section self-observable, otherwise target's and/or
libqb's linkage at fault and logging would not work reliably"
assertion
[*I] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
which makes it, likely through self-reference keepalive (see
below) work OK
[*J] boils down to [*2], unless QB_LOG_INIT_DATA used on interlib side,
which makes it, likely through self-reference keepalive (see
below) work OK
[*K] boils down to [*3]
in addition, syslog carries this error:
"target chain supplied section not observed by libqb, target's and/or
libqb's linkage at fault and logging of the target will not work
reliably"
logged by libqb proper
[*L] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side
(sufficient?), which makes it, likely through self-reference
keepalive (see below) boil down just to [*1];
in addition, syslog carries this error:
"target chain supplied section not observed by libqb, target's and/or
libqb's linkage at fault and logging of the target will not work
reliably"
logged by libqb proper
[*M] boils down to [*1];
in addition, syslog carries this error:
"target chain supplied section not observed by libqb, target's and/or
libqb's linkage at fault and logging of the target will not work
reliably"
logged by libqb proper
[*N] boils down to [*M], unless QB_LOG_INIT_DATA used on client side,
which makes it, likely through self-reference keepalive (see
below) work OK
[*O] boils down to [*K], unless QB_LOG_INIT_DATA used on both client
and interlib side, which makes it, likely through self-reference
keepalive (see below) work OK (it's expected that this a mere
composite of situations [*I] and [*J] with consequences as stated)
Note: the only problematic (i.e. not captured automatically by the
QB_LOG_INIT_DATA macro presumably utilized at every non-libqb logging
system participant in the form of a discrete compilation unit)
combination with 2.29 is the one intersecting at "BAD[*2]" pertaining
"everything but interlib compiled with ld.bfd < 2.29". It would, of
course, be solvable as well, but presumably not in an easy way, and
that use case should not be as frequent.
Takeway: whenever your target (library or client program) actively
utilizes logging (meaning it emits at least a single log message),
YOU ARE strongly ENCOURAGED TO USE QB_LOG_INIT_DATA macro function
at (exactly) one of the source code files (presumably the main one)
per respective target's compilation unit. It will alleviate the
hassles possibly caused by downgrading libqb to the linker-vs-libqb
incompatibly compiled one or in similar circumstances arising merely
from the linker behaviour change, which the current build system/code
quake is all about.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
configure.ac | 1 +
include/qb/qblog.h | 63 ++++++++++++++++++++++++++++---
lib/libqb.pc.in | 3 +-
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(-)
create mode 100755 tests/functional/syslog-stdout.py
diff --git a/configure.ac b/configure.ac
index 274b49c..5769e60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -642,6 +642,7 @@ if test "x${GCC}" = xyes; then
AC_DEFINE([QB_HAVE_ATTRIBUTE_SECTION], 1,
[Enabling code using __attribute__((section))])
PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section"
+ AC_SUBST([client_dlopen_LIBS],[$dlopen_LIBS])
fi
fi
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
index d39803f..9474c16 100644
--- a/include/qb/qblog.h
+++ b/include/qb/qblog.h
@@ -44,6 +44,7 @@ extern "C" {
#ifdef QB_HAVE_ATTRIBUTE_SECTION
#include <assert.h> /* possibly needed for QB_LOG_INIT_DATA */
+#include <dlfcn.h>
#endif
/**
@@ -283,20 +284,70 @@ 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
+/* Related to the next macro that is -- unlike this one -- a public API */
+#ifndef _GNU_SOURCE
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
+ _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)))
+#else
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
+ /* 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) \
+ && (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("libqb's callsite section observable, otherwise libqb's \
+linkage at fault and logging would not work reliably" \
+ && work_s1 != NULL && work_s2 != NULL); \
+ 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); }
+#endif
+
+/**
+ * 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 */
+ * target collection area are kept alive with some otherwise unkind linkers.
+ *
+ * Applying this macro in the target program/library is strongly recommended
+ * whenever the logging as framed by this header file is in use.
+ * Moreover, it's important to state that using this check while not ensuring
+ * @c _GNU_SOURCE macro definition is present at compile-time means only half
+ * of the available sanity checking will be performed, possibly resulting
+ * in libqb's own internally logged messages being lost without warning.
+ */
#define QB_LOG_INIT_DATA(name) \
void name(void); \
- void name(void) \
- { assert("non-empty callsite section" \
- && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \
+ void name(void) { \
+ void *work_handle; struct qb_log_callsite *work_s1, *work_s2; \
+ Dl_info work_dli; \
+ /* our own (target's) sanity */ \
+ 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 \
+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_; \
+ /* original "cherry on the cake" 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)
diff --git a/lib/libqb.pc.in b/lib/libqb.pc.in
index 8a8d0ba..37d27b7 100644
--- a/lib/libqb.pc.in
+++ b/lib/libqb.pc.in
@@ -7,5 +7,6 @@ Name: libqb
Version: @PACKAGE_VERSION@
Description: libqb
Requires:
-Libs: -L${libdir} -lqb @LIBS@
+Libs: -L${libdir} -lqb @client_dlopen_LIBS@
+Libs.private: @LIBS@
Cflags: -I${includedir}
diff --git a/lib/log.c b/lib/log.c
index bfd218f..f30b8d8 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -853,6 +853,18 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
{
int32_t l;
enum qb_log_target_slot i;
+#ifdef QB_HAVE_ATTRIBUTE_SECTION
+ void *work_handle; struct qb_log_callsite *work_s1, *work_s2;
+ Dl_info work_dli;
+#endif /* QB_HAVE_ATTRIBUTE_SECTION */
+ /* cannot reuse single qb_log invocation in various contexts
+ through the variables (when section attribute in use),
+ hence this indirection */
+ enum {
+ preinit_err_none,
+ preinit_err_target_sec,
+ preinit_err_target_empty,
+ } preinit_err = preinit_err_none;
l = pthread_rwlock_init(&_listlock, NULL);
assert(l == 0);
@@ -871,6 +883,25 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
qb_log_dcs_init();
#ifdef QB_HAVE_ATTRIBUTE_SECTION
+ /* sanity check that target chain supplied QB_ATTR_SECTION_ST{ART,OP}
+ symbols and hence the local references to them are not referencing
+ the proper libqb's ones (locating libqb-self 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)
+ && (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);
+ if (work_s1 == QB_ATTR_SECTION_START
+ || work_s2 == QB_ATTR_SECTION_STOP) {
+ preinit_err = preinit_err_target_sec;
+ } else if (work_s1 == work_s2) {
+ preinit_err = preinit_err_target_empty;
+ }
+ }
qb_log_callsites_register(QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP);
dl_iterate_phdr(_log_so_walk_callback, NULL);
_log_so_walk_dlnames();
@@ -884,6 +915,19 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
_log_target_state_set(&conf[QB_LOG_SYSLOG], QB_LOG_STATE_ENABLED);
(void)qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
QB_LOG_FILTER_FILE, "*", priority);
+
+ if (preinit_err == preinit_err_target_sec)
+ qb_util_log(LOG_ERR, "target chain supplied section not"
+ " observed by libqb, target's and/or"
+ " libqb's linkage at fault and"
+ " logging of the target will not"
+ " work reliably");
+ else if (preinit_err == preinit_err_target_empty) {
+ qb_util_log(LOG_WARNING, "target chain supplied section empty,"
+ " target's linkage at fault and"
+ " logging of the target will not"
+ " work reliably");
+ }
}
void
diff --git a/tests/functional/Makefile.am b/tests/functional/Makefile.am
index 72f551e..c079009 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 \
- 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
--- 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
-AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_PROGRAMS = log_client log_interlib_client
# cannot use {check,noinst}_LTLIBRARIES because it leads to solely static lib
diff --git a/tests/functional/log_external/Makefile.am b/tests/functional/log_external/Makefile.am
index 36aa0af..ca1c8a5 100644
--- a/tests/functional/log_external/Makefile.am
+++ b/tests/functional/log_external/Makefile.am
@@ -19,5 +19,9 @@
include ../log.am
-log_client_LDFLAGS = -lqb
-liblog_inter_la_LIBADD = -lqb
+# while linking with system-wide version of libqb, we are still pursuing
+# local in-tree header file, hence we need to link with dynamic linking
+# library (which is a prerequisite for using QB_LOG_INIT_DATA defined
+# in qblog.h) explicitly
+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
--- a/tests/functional/log_test_mock.sh
+++ b/tests/functional/log_test_mock.sh
@@ -165,10 +165,19 @@ do_compile_and_test_client () {
-exec rm -- {} \;"
;;
esac
+ mock ${mock_args} --copyin "syslog-stdout.py" "builddir"
mock ${mock_args} --shell "( cd \"builddir/build/BUILD/$1\"; ./configure )"
mock ${mock_args} --shell \
- "make -C \"builddir/build/BUILD/$1/tests/functional/log_external\" \
- check-TESTS \"TESTS=../${_logfile}.sh\" $5" \
+ "python3 builddir/syslog-stdout.py \
+ >\"builddir/build/BUILD/$1/tests/functional/log_external/.syslog\" & \
+ { sleep 2; make -C \"builddir/build/BUILD/$1/tests/functional/log_external\" \
+ check-TESTS \"TESTS=../${_logfile}.sh\" $5; } \
+ && ! test -s \"builddir/build/BUILD/$1/tests/functional/log_external/.syslog\"; \
+ ret_ec=\$?; \
+ ( cd \"builddir/build/BUILD/$1/tests/functional/log_external\"; \
+ cat .syslog >> test-suite.log; \
+ echo SYSLOG-begin; cat .syslog; echo SYSLOG-end ); \
+ ret () { return \$1; }; ret \${ret_ec}" \
&& _result="${_result}_good" \
|| _result="${_result}_bad"
mock ${mock_args} --copyout \
diff --git a/tests/functional/syslog-stdout.py b/tests/functional/syslog-stdout.py
new file mode 100755
index 0000000..a0a761b
--- /dev/null
+++ b/tests/functional/syslog-stdout.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python3
+# Copyright 2017 Red Hat, Inc.
+#
+# Author: Jan Pokorny <jpokorny@redhat.com>
+#
+# This file is part of libqb.
+#
+# libqb is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# libqb is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with libqb. If not, see <http://www.gnu.org/licenses/>.
+
+import socket
+from atexit import register
+from os import remove
+from sys import argv
+
+# no locking, but anyway
+try:
+ remove("/dev/log")
+except FileNotFoundError:
+ pass
+sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+sock.bind("/dev/log")
+
+def shutdown():
+ sock.close()
+ remove("/dev/log")
+
+def main(*argv):
+ register(shutdown)
+ while True:
+ try:
+ b = sock.recv(4096)
+ # flushing is crucial here
+ print(">>> " + str(b, 'ascii').split(' ', 3)[-1], flush=True)
+ except IOError:
+ pass
+
+if __name__ == '__main__':
+ main(*argv)
--
2.14.2

View File

@ -1,257 +0,0 @@
From b883cc548ff1d487af6cd5bee49c5b386f91df4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 4/6] Med: add extra run-time client-side sanity check that
logging will work
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The table at the bottom concludes how the test matrix overview
introduced with a message for the preceding commit (also introducing
log_test_mock.sh runner which got reused here) looks as of this
refreshed sanity check, once it (QB_LOG_INIT_DATA macro) gets applied
(meaning "for non-libqb logging participants" so as not complicate
the matrix further).
Note that for libqb users, this implies a new link dependency on libdl,
because they may opt-in for refreshed QB_LOG_INIT_DATA sanity check that
calls out to dlopen/dlsym/dladdr directly in case of "attribute section"
being available for the particular platform, and hence immediately needs
those symbols resolved in link time. Hence, add this conditional link
dependency to libqb.pc pkg-config file under Libs variable -- we
actually restore the occurrence of "-ldl" there as it used to be present
until commit 56754d0. While doing so, also move immediate link
dependencies of libqb (if any, currently not but that may be
a regression arising from the cleanup related to the mentioned commit)
represented with the LIBS autoconf variable under Libs.private variable
in libqb.pc, where it belongs per pkg-config documentation.
The promised table follows, but first as a recap, "X(Y)" denotes
"X linked with linker Y":
X(a) .. ld.bfd < 2.29
X(b) .. ld.bfd = 2.29 (and likely on)
goes like this (values in <angle brackets> denote non-trivial change
[not mere rewording] introduced as of this commit, in comparison to
the table stated in the preceding commit):
+=========+=========+=========+=========+=========+=========+=========+
#client(x)# libqb(a) usage # libqb(b) usage #
# vvv #---------+---------+---------+---------+---------+---------+
# V # direct | libX(a) : libX(b) # direct | libX(a) : libX(b) #
+=========+=========+=========+=========+=========+=========+=========+
# x = a # OK | OK : BAD[*2] #<BAD[*E]>|<BAD[*F]>:<BAD[*G]>#
# x = b # BAD[*A] | BAD[*B] : BAD[*C] #<BAD[*E]>|<BAD[*F]>:<BAD[*G]>#
+=========+=========+=========+=========+=========+=========+=========+
[*1] client logging not working
[*2] interlib logging not working
[*3] both client and interlib logging not working
[*A] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
which then fails on
"non-empty implicit callsite section, otherwise target's linkage at
fault and logging would not work reliably"
assertion
[*B] boils down to [*1], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"non-empty implicit callsite section, otherwise target's linkage at
fault and logging would not work reliably"
assertion
[*C] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"non-empty implicit callsite section, otherwise target's linkage at
fault and logging would not work reliably"
assertion
[*E] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
which then fails on
"target's callsite section self-observable, otherwise target's
linkage at fault and logging would not work reliably"
assertion
[*F] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"libqb's callsite section non-empty, otherwise libqb's linkage at
fault and logging would not work reliably"
assertion
[*G] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
which then fails on
"target's callsite section self-observable, otherwise target's linkage
at fault and logging would not work reliably"
assertion
Note: the only problematic (i.e. not captured automatically by the
QB_LOG_INIT_DATA macro presumably utilized at every non-libqb logging
system participant in the form of a discrete compilation unit)
combination is the one intersecting at "BAD[*2]" pertaining "everything
but interlib compiled with ld.bfd < 2.29". It would, of course, be
solvable as well, but presumably not in an easy way, and that use case
should not be as frequent.
Takeway: whenever your target (library or client program) actively
utilizes logging (meaning it emits at least a single log message),
YOU ARE strongly ENCOURAGED TO USE QB_LOG_INIT_DATA macro function
at (exactly) one of the source code files (presumably the main one)
per respective target's compilation unit. It will alleviate the
hassles possibly caused by downgrading libqb to the linker-vs-libqb
incompatibly compiled one or in similar circumstances arising merely
from the linker behaviour change, which the current build system/code
quake is all about.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
configure.ac | 1 +
include/qb/qblog.h | 67 ++++++++++++++++++++++++++++---
lib/libqb.pc.in | 3 +-
tests/functional/log.am | 2 +-
tests/functional/log_external/Makefile.am | 8 +++-
5 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/configure.ac b/configure.ac
index db7bc68..5601302 100644
--- a/configure.ac
+++ b/configure.ac
@@ -640,6 +640,7 @@ if test "x${GCC}" = xyes; then
AC_DEFINE([QB_HAVE_ATTRIBUTE_SECTION], 1,
[Enabling code using __attribute__((section))])
PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section"
+ AC_SUBST([client_dlopen_LIBS],[$dlopen_LIBS])
fi
fi
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
index d38449d..e49c86c 100644
--- a/include/qb/qblog.h
+++ b/include/qb/qblog.h
@@ -42,6 +42,11 @@ extern "C" {
#undef QB_HAVE_ATTRIBUTE_SECTION
#endif /* S_SPLINT_S */
+#ifdef QB_HAVE_ATTRIBUTE_SECTION
+#include <assert.h>
+#include <dlfcn.h>
+#endif
+
/**
* @file qblog.h
* The logging API provides four main parts (basics, filtering, threading & blackbox).
@@ -268,18 +273,70 @@ 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 and (2) non-void
+/* Related to the next macro, which is -- contrary to this -- public API */
+#ifndef _GNU_SOURCE
+#warning "without _GNU_SOURCE defined (directly or not), QB_LOG_INIT_DATA cannot check libqb's own sanity"
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_
+#else
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
+ /* 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) \
+ && (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); \
+ assert(("libqb's callsite section not 1st in global resolution, \
+otherwise target's linkage at fault and logging would not work reliably",\
+ work_s2 != work_s1)); \
+ work_s2 = (struct qb_log_callsite *) \
+ dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \
+ 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); }
+#endif
+
+/**
+ * Optional on-demand self-check of (1) toolchain sanity and (2) non-void
* (implied by the justifying existence of at least a single logging callsite
* ~ qb_logt invocation) employment of logging subsystem in the target binary,
* which is presumably assured by it's author as of relying on this macro;
* only effective when link-time ("run-time amortizing") callsite collection
- * is available and may be extended in future for more in-depth self-validation
+ * is.
+ *
+ * Applying this macro in the target program/library is strongly recommended
+ * whenever the logging as framed by this header file is in use. Moreover,
+ * it's important to state that using this check while not ensuring _GNU_SOURCE
+ * macro definition is present at compile-time means only half of the available
+ * sanity checking will be performed, possibly resulting in libqb's own
+ * internally logged messages being lost.
*/
#define QB_LOG_INIT_DATA(name) \
void name(void); \
- void name(void) \
- { assert(("non-empty callsite section", \
- QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP)); } \
+ void name(void) { \
+ void *work_handle; struct qb_log_callsite *work_s1, *work_s2; \
+ Dl_info work_dli; \
+ /* our own (target's) sanity */ \
+ 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 \
+target's linkage at fault and logging would not work reliably", \
+ work_s1 != NULL && work_s2 != NULL)); \
+ work_s2 = (struct qb_log_callsite *) \
+ dlsym(RTLD_DEFAULT, QB_ATTR_SECTION_START_STR); \
+ assert(("target's callsite section 1st in global resolution, \
+otherwise target's linkage at fault and logging would not work reliably",\
+ work_s1 == work_s2)); } \
+ QB_NONAPI_LOG_INIT_DATA_EXTRA_; \
+ /* original "cherry on the cake" check, possibly expendable */ \
+ 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)
diff --git a/lib/libqb.pc.in b/lib/libqb.pc.in
index 8a8d0ba..37d27b7 100644
--- a/lib/libqb.pc.in
+++ b/lib/libqb.pc.in
@@ -7,5 +7,6 @@ Name: libqb
Version: @PACKAGE_VERSION@
Description: libqb
Requires:
-Libs: -L${libdir} -lqb @LIBS@
+Libs: -L${libdir} -lqb @client_dlopen_LIBS@
+Libs.private: @LIBS@
Cflags: -I${includedir}
diff --git a/tests/functional/log.am b/tests/functional/log.am
index 5fe1ae7..0753fa5 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
-AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_PROGRAMS = log_client log_interlib_client
# cannot use {check,noinst}_LTLIBRARIES because it leads to solely static lib
diff --git a/tests/functional/log_external/Makefile.am b/tests/functional/log_external/Makefile.am
index 36aa0af..ca1c8a5 100644
--- a/tests/functional/log_external/Makefile.am
+++ b/tests/functional/log_external/Makefile.am
@@ -19,5 +19,9 @@
include ../log.am
-log_client_LDFLAGS = -lqb
-liblog_inter_la_LIBADD = -lqb
+# while linking with system-wide version of libqb, we are still pursuing
+# local in-tree header file, hence we need to link with dynamic linking
+# library (which is a prerequisite for using QB_LOG_INIT_DATA defined
+# in qblog.h) explicitly
+log_client_LDFLAGS = -lqb @client_dlopen_LIBS@
+liblog_inter_la_LIBADD = -lqb @client_dlopen_LIBS@
--
2.14.2

View File

@ -1,4 +1,4 @@
From 509beb47f2494e7fe207180266401288da1b6b6d Mon Sep 17 00:00:00 2001
From e911aae9c4474cc16d06be02fabcacde9f8d54b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 5/6] High: bare fix for libqb logging not working with
@ -34,7 +34,10 @@ above.
And then for 2.29.1 release of binutils once again, as someone actually
noticed something went overboard with the 2.29 changes:
https://sourceware.org/bugzilla/show_bug.cgi?id=21964
http://lists.gnu.org/archive/html/bug-binutils/2017-08/msg00195.html
(overview of the original bug discussion, rather than directly
https://sourceware.org/bugzilla/show_bug.cgi?id=21964, which is
a result of a conflct resolution when restoring bugzilla backup)
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=487b6440dad57440939fab7afdd84a218b612796
At least that change doesn't invalidate all the effort being put into
@ -87,7 +90,8 @@ So further extensions were devised to cover both consumption models:
libqb_la_LIBADD, and with a little bit of further fiddling, it works
as desired (note that double occurrence of "-Wl,foo.t" equivalent
present at some stages of sorting this trick turned out to be,
surprisingly, counter-productive);
surprisingly, counter-productive, which should now demistify the
very existence of effectively empty qblog_script_noop.ld file);
NOTE: some forms of libtool distribution (debian + derivatives ones
in particular) undermine natural transitive dependency propagation
@ -99,12 +103,30 @@ So further extensions were devised to cover both consumption models:
of consuming libqb outside of it's own playground is hardly
the Right Thing) if portability is important, nonetheless!
On the address of linker script workaround, there are linkers out there
that do not support the trick, for instance:
- ld.gold from binutils (but it has hardly ever been working with
orphan sections, anyway:
https://sourceware.org/bugzilla/show_bug.cgi?id=22291)
- ancient versions of ld.bfd, e.g. 10+ years old one used as a native
system linker even in the most recent releases of FreeBSD, unless
GCC toolchain is used instead
If these are hit when (because) the compiler has already demonstrated it
supports section attribute, the build system configuration is forcibly
stopped, simply to stay conceptually compatible with the prior state in
which the affinity to leverage that feature hasn't been called off
under any circumstances. One is, however, able to achieve exactly
this behaviour with --enable-nosection-fallback switch, but if some
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).
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,
which is already achieved with the arrangement for b. above, and by
experiments, further redefinition of those boundary denoting symbols
as weak was necessary so as to make them truly global within libqb.so
proper (at least with binutils 2.29).
"-Wl,foo.t" equivalent for its own outgoing log messages to be honoured
under all circumstances, which is already achieved with the arrangement
for b. above, and by experiments, further redefinition of those boundary
denoting symbols as weak was necessary so as to make them truly global
within libqb.so proper (at least with binutils 2.29).
* * *
@ -112,7 +134,7 @@ Finally, let's have a look how the already well-known test matrix
overview changes as of this commit, but first as a recap,
"X(Y)" denotes "X linked with linker Y":
X(a) .. ld.bfd < 2.29
X(b) .. ld.bfd = 2.29 (and likely on)
X(b) .. ld.bfd = 2.29 (+ 2.29.1 and hopefully on)
and here you are (values in <angle brackets> denote non-trivial change
[not mere rewording] introduced as of this commit, in comparison to the
@ -174,35 +196,38 @@ References:
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
configure.ac | 90 +++++++++++++++++++++++++++++++++++++++++-------
lib/Makefile.am | 67 +++++++++++++++++++++++++++++++++++
lib/log.c | 7 ++++
lib/qblog_script.la.in | 15 ++++++++
lib/qblog_script.ld.in | 17 +++++++++
lib/qblog_script_noop.ld | 1 +
7 files changed, 184 insertions(+), 13 deletions(-)
configure.ac | 146 +++++++++++++++++++++++++++++++++++++++++------
lib/Makefile.am | 67 ++++++++++++++++++++++
lib/libqb.pc.in | 6 ++
lib/log.c | 7 +++
lib/qblog_script.la.in | 15 +++++
lib/qblog_script.ld.in | 25 ++++++++
lib/qblog_script_noop.ld | 1 +
7 files changed, 249 insertions(+), 18 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 5601302..6eda2dd 100644
index 5769e60..57875c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -501,6 +501,12 @@ AC_ARG_ENABLE([debug],
@@ -501,6 +501,14 @@ AC_ARG_ENABLE([debug],
AC_ARG_ENABLE([coverage],
[AS_HELP_STRING([--enable-coverage],[coverage analysis of the codebase])])
+AC_ARG_ENABLE([interlib-deps],
+ [AS_HELP_STRING([--disable-interlib-deps],
+ [disable inter-library dependencies (might break builds)])],
+ [enable_interlib_deps="$enableval"],
+ [enable_interlib_deps="yes"])
+ [disable inter-library dependencies (might break builds)])])
+
+AC_ARG_ENABLE([nosection-fallback],
+ [AS_HELP_STRING([--enable-nosection-fallback],
+ [allow (logging compat-breaking?) fallback when orphan section dead-ended])])
+
AC_ARG_ENABLE([slow-tests],
[AS_HELP_STRING([--enable-slow-tests],[build and run slow tests])])
@@ -609,6 +615,19 @@ else
@@ -609,6 +617,19 @@ else
COVERAGE_LDFLAGS=""
fi
@ -212,17 +237,17 @@ index 5601302..6eda2dd 100644
+# override the libtool variable by force because the current
+# arrangement relies on transitive dependency propagation
+AC_MSG_NOTICE([Enabling inter-library dependencies: $enable_interlib_deps])
+if test "${enable_interlib_deps}" == "yes"; then
+ link_all_deplibs=yes
+else
+if test "x${enable_interlib_deps}" = xno; then
+ link_all_deplibs=no
+else
+ link_all_deplibs=yes
+fi
+
+# --- slow tests ---
if test "x${enable_slow_tests}" = xyes ; then
AC_DEFINE([HAVE_SLOW_TESTS], 1,[have slow tests])
AC_MSG_NOTICE([Enabling Slow tests])
@@ -618,31 +637,74 @@ AC_SUBST(HAVE_SLOW_TESTS)
@@ -618,33 +639,120 @@ AC_SUBST(HAVE_SLOW_TESTS)
# --- callsite sections ---
if test "x${GCC}" = xyes; then
@ -237,18 +262,22 @@ index 5601302..6eda2dd 100644
[[#include <assert.h>
- extern void * __start___verbose, * __stop___verbose;]],
- [[static int my_var __attribute__((section("__verbose"))) = 5;
- assert(("non-empty data section", __start___verbose != __stop___verbose));
- assert(("no data section value loss", my_var == 5));
- ]]),
- assert("non-empty data section"
- && __start___verbose != __stop___verbose);
- assert("no data section value loss"
- && my_var == 5);]]
- ),
- [gcc_has_attribute_section=yes],
+ extern int __start___verbose[], __stop___verbose[];
+ int test(void) {
+ static int my_var __attribute__((section("__verbose"))) = 3;
+ assert(("L:non-empty data section", __start___verbose != __stop___verbose));
+ assert(("L:no data section value loss", my_var == 3 /* for 2.29.1+ */));
+ return *((int *) __start___verbose);
+ }]])],
+ [gcc_has_attribute_section=yes; cp "conftest${EXEEXT}" "lib_conftest.so"],
+ extern int __start___verbose[], __stop___verbose[];
+ int test(void) {
+ static int my_var __attribute__((section("__verbose"))) = 3;
+ assert("L:non-empty data section"
+ && __start___verbose != __stop___verbose);
+ assert("L:no data section value loss"
+ && my_var == 3 /* for 2.29.1+ */);
+ return *((int *) __start___verbose); }]]
+ )],
+ [gcc_has_attribute_section=yes; cp "conftest${EXEEXT}" "conftest.so"],
[gcc_has_attribute_section=no]
)
+ AX_RESTORE_FLAGS
@ -258,6 +287,10 @@ index 5601302..6eda2dd 100644
-
AC_MSG_RESULT($gcc_has_attribute_section)
- if test $gcc_has_attribute_section = yes; then
- AC_DEFINE([QB_HAVE_ATTRIBUTE_SECTION], 1,
- [Enabling code using __attribute__((section))])
- PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section"
- AC_SUBST([client_dlopen_LIBS],[$dlopen_LIBS])
+
+ # 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'
@ -271,33 +304,76 @@ index 5601302..6eda2dd 100644
+ # but the workaround is still provably needed
+ if test "x${gcc_has_attribute_section}" = xyes; then
+ AC_MSG_CHECKING([whether linker emits global boundary symbols for orphan sections])
+ LIBS="${LIBS} -L. -l_conftest -Wl,-rpath=$(pwd)"
+ LIBS="${LIBS} -L. -l:conftest.so -Wl,-rpath=$(pwd)"
+ AC_TRY_RUN(
+ AC_LANG_PROGRAM(
+ [[#include <assert.h>
+ extern int __start___verbose[], __stop___verbose[];
+ int test(void);]],
+ extern int __start___verbose[], __stop___verbose[];
+ int test(void);]],
+ [[static int my_var __attribute__((section("__verbose"))) = 5;
+ assert(("P:non-empty data section", __start___verbose != __stop___verbose));
+ assert(("P:no data section value loss", my_var == test() /*5?*/));
+ ]]),
+ assert("P:non-empty data section"
+ && __start___verbose != __stop___verbose);
+ assert("P:no data section value loss"
+ && my_var == test() /*5?*/);]]
+ ),
+ [gcc_has_attribute_section_visible=yes],
+ [gcc_has_attribute_section_visible=no]
+ )
+ AX_RESTORE_FLAGS
+ AC_MSG_RESULT($gcc_has_attribute_section_visible)
+ rm -f "lib_conftest.so"
+ rm -f "conftest.so"
+
AC_DEFINE([QB_HAVE_ATTRIBUTE_SECTION], 1,
[Enabling code using __attribute__((section))])
- PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section"
AC_SUBST([client_dlopen_LIBS],[$dlopen_LIBS])
+ if test "x${gcc_has_attribute_section_visible}" = xyes; then
+ PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section"
+ else
+ AC_DEFINE([QB_NEED_ATTRIBUTE_SECTION_WORKAROUND], 1,
+ if test "x${gcc_has_attribute_section_visible}" = xno; then
+ # check if the linker script based workaround is
+ # feasible at all, otherwise fallback to using no
+ # section attribute while making some noise about it
+ # as combining with-without accustomed logging
+ # participants is currently uncharted waters
+ AC_MSG_CHECKING([whether linker workaround for orphan sections usable])
+ >conftest.ld cat <<-EOF
+ SECTIONS {
+ __verbose : {
+ __start___verbose = .;
+ *(__verbose);
+ __stop___verbose = .;
+ }
+ }
+ EOF
+ LDFLAGS="${LDFLAGS} -Wl,conftest.ld"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <assert.h>
+ extern int __start___verbose[], __stop___verbose[];
+ int test(void);]],
+ [[static int my_var __attribute__((section("__verbose"))) = 5;
+ assert("P:non-empty data section"
+ && __start___verbose != __stop___verbose);
+ assert("P:no data section value loss"
+ && my_var == 5);]]
+ )],
+ [],
+ [gcc_has_attribute_section=no]
+ )
+ AX_RESTORE_FLAGS
+ AC_MSG_RESULT([$gcc_has_attribute_section])
+ rm -f "conftest.ld"
+ fi
+
+ if test "x${gcc_has_attribute_section}" = xyes; then
+ AC_DEFINE([QB_HAVE_ATTRIBUTE_SECTION], 1,
+ [Enabling code using __attribute__((section))])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section-workaround"
+ AC_SUBST([client_dlopen_LIBS],[$dlopen_LIBS])
+ if test "x${gcc_has_attribute_section_visible}" = xyes; then
+ PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section"
+ else
+ AC_DEFINE([QB_NEED_ATTRIBUTE_SECTION_WORKAROUND], 1,
+ [Enabling code using __attribute__((section))])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section-workaround"
+ fi
+ elif test "x${enable_nosection_fallback}" = xyes; then
+ AC_MSG_NOTICE([Falling back to not using orphan section])
+ else
+ AC_MSG_ERROR([Would use section attribute, cannot; see --enable-nosection-fallback])
+ fi
fi
fi
@ -308,7 +384,7 @@ index 5601302..6eda2dd 100644
# --- ansi ---
if test "x${enable_ansi}" = xyes && \
@@ -724,9 +786,11 @@ AC_CONFIG_FILES([Makefile
@@ -726,9 +834,11 @@ AC_CONFIG_FILES([Makefile
docs/Makefile
docs/common.dox
docs/html.dox
@ -323,7 +399,7 @@ index 5601302..6eda2dd 100644
AC_OUTPUT
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0bebeb5..340cd85 100644
index 0bebeb5..ff5b3b4 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,6 +19,7 @@
@ -389,7 +465,7 @@ index 0bebeb5..340cd85 100644
+qblog_script.ld: %.ld: %.ld.in
+ $(AM_V_GEN)$(CPP) -xc -I$(top_srcdir)/include -D_GNU_SOURCE -C -P $< \
+ | sed -n "/$$(sed -n '/^[^#]/{s/[*\/]/\\\0/g;p;q}' $<)/{:r;p;n;br}" \
+ | sed -n "/$$(sed -n '/^[^#]/{s/[*\/]/\\&/g;p;q;}' $<)/,$$ p" \
+ > $@
+
+# find the libqb.so symlink's target, if so, try to find out, iteratively,
@ -417,8 +493,24 @@ index 0bebeb5..340cd85 100644
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libqb.pc
diff --git a/lib/libqb.pc.in b/lib/libqb.pc.in
index 37d27b7..bdcd3c8 100644
--- a/lib/libqb.pc.in
+++ b/lib/libqb.pc.in
@@ -8,5 +8,11 @@ Version: @PACKAGE_VERSION@
Description: libqb
Requires:
Libs: -L${libdir} -lqb @client_dlopen_LIBS@
+# NOTE: If -lqb not usable for linking (e.g. linker not compatible with
+# linker scripts ad-hoc modifying output sections), try recent
+# ld.bfd/binutils linker first when available, otherwise you can
+# try "-l:libqb.so.<digit>" link switch (right <digit> available,
+# for example, directly within libqb.so plaintext) that bypasses
+# said linker script -- but beware, logging problems may ensue.
Libs.private: @LIBS@
Cflags: -I${includedir}
diff --git a/lib/log.c b/lib/log.c
index bfd218f..4ed432f 100644
index f30b8d8..e4b77d5 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -40,6 +40,13 @@
@ -458,10 +550,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..1f37976
index 0000000..fed826b
--- /dev/null
+++ b/lib/qblog_script.ld.in
@@ -0,0 +1,17 @@
@@ -0,0 +1,25 @@
+#include <qb/qblog.h>
+/* GNU ld script
+ This atypical arrangement enforces global visibility of boundary symbols
@ -469,7 +561,15 @@ index 0000000..1f37976
+ QB_ATTR_SECTION used for compile-time offloading of the logging call sites
+ tracking. While libqb relies on these being global, default linker from
+ binutils change the visibility as of version 2.29, making the logging
+ unusable without artificial stimulus: https://bugzilla.redhat.com/1477354 */
+ unusable without artificial stimulus: https://bugzilla.redhat.com/1477354
+
+ NOTE: If -lqb not usable for linking (e.g. linker not compatible with
+ linker scripts ad-hoc modifying output sections), try recent
+ ld.bfd/binutils linker first when available, otherwise you can
+ try "-l:libqb.so.<digit>" link switch (right <digit> available,
+ for example, directly within libqb.so plaintext) that bypasses
+ said linker script -- but beware, logging problems may ensue.
+ */
+SECTIONS {
+#ifdef QB_HAVE_ATTRIBUTE_SECTION
+ QB_ATTR_SECTION : {

View File

@ -1,4 +1,4 @@
From e6833567cd834cbbd182c48327b7e8ce3a8fc2bc Mon Sep 17 00:00:00 2001
From d24e62a6b144a0532b1e472744ebbb13aa0221c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 6 Oct 2017 17:17:26 +0200
Subject: [PATCH 6/6] Low: fix internal object symbol's leak & expose run-time
@ -19,19 +19,24 @@ lower-casing applied on originally upper-cased macro identifiers.
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.
In turn, also bump "current" and "age" of fields of the libtool's
"-version-info" versioning system.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
include/qb/qbconfig.h.in | 5 ++++-
include/qb/qblog.h | 10 ++++++----
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 +-
7 files changed, 34 insertions(+), 7 deletions(-)
9 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/include/qb/qbconfig.h.in b/include/qb/qbconfig.h.in
index c1852e1..789fff3 100644
index c1852e1..1b92794 100644
--- a/include/qb/qbconfig.h.in
+++ b/include/qb/qbconfig.h.in
@@ -30,7 +30,10 @@
@ -40,28 +45,26 @@ index c1852e1..789fff3 100644
-/* 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 run-time
+ querying the lower-cased symbolic constants directly from libqb
+ 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 */
#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 e49c86c..7ca236d 100644
index 9474c16..56fdd6a 100644
--- a/include/qb/qblog.h
+++ b/include/qb/qblog.h
@@ -279,10 +279,12 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
#define QB_NONAPI_LOG_INIT_DATA_EXTRA_
@@ -293,9 +293,11 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
#else
#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
- /* libqb sanity (locating libqb by it's relatively unique \
#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
/* 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) \
+ /* libqb sanity (locating libqb by it's relatively unique \
+ non-functional symbol (the two are mutually exclusive, the \
+ non-functional symbols -- the two are mutually exclusive, the \
+ ordinarily latter was introduced by accident, the former is \
+ intentional), due to possible confusion otherwise) */ \
+ intentional -- due to possible confusion otherwise) */ \
+ if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli) \
+ || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli)) \
&& (work_handle = dlopen(work_dli.dli_fname, \
@ -89,6 +92,40 @@ index bfce349..a03bdf8 100644
/* *INDENT-OFF* */
#ifdef __cplusplus
}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index ff5b3b4..a428975 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -30,7 +30,7 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
lib_LTLIBRARIES = libqb.la
-libqb_la_LDFLAGS = -version-info 18:2:18
+libqb_la_LDFLAGS = -version-info 19:0:19
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
--- a/lib/log.c
+++ b/lib/log.c
@@ -892,10 +892,12 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
#ifdef QB_HAVE_ATTRIBUTE_SECTION
/* sanity check that target chain supplied QB_ATTR_SECTION_ST{ART,OP}
symbols and hence the local references to them are not referencing
- the proper libqb's ones (locating libqb-self 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)
+ the proper libqb's ones (locating libqb by it's relatively unique
+ non-functional symbols -- the two are mutually exclusive, the
+ ordinarily latter was introduced by accident, the former is
+ intentional -- due to possible confusion otherwise) */
+ 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/lib/log_format.c b/lib/log_format.c
index 712f447..e7e1f40 100644
--- a/lib/log_format.c

View File

@ -2,7 +2,7 @@
Name: libqb
Version: 1.0.2
Release: 9%{?dist}
Release: 10%{?dist}
Summary: An IPC library for high performance servers
Group: System Environment/Libraries
@ -12,7 +12,7 @@ Source0: https://github.com/ClusterLabs/libqb/releases/download/v%{versio
Patch0: 01-Med-qblog.h-better-explanation-behaviour-of-QB_LOG_I.patch
Patch1: 02-build-configure-run-attribute-section-test-through-r.patch
Patch2: 03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch
Patch3: 04-Med-add-extra-run-time-client-side-sanity-check-that.patch
Patch3: 04-Med-add-extra-run-time-client-libqb-checks-that-logg.patch
Patch4: 05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch
Patch5: 06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch
@ -77,6 +77,9 @@ developing applications that use %{name}.
%{_mandir}/man3/qb*3*
%changelog
* Fri Oct 13 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-10
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
* Mon Oct 09 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-9
- Evolution of the previous (rhbz#1478089, rhbz#1487787)