1.0.2-8 - Evolution of the previous (rhbz#1478089, rhbz#1487787)
- New test included in check phase (as per upsteam) Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
This commit is contained in:
parent
b5b22505a5
commit
b933a4c6ac
@ -1,336 +0,0 @@
|
|||||||
From 10cd5db8821e4d313ae5245b33061e02ba8d3ff5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
|
|
||||||
Date: Thu, 3 Aug 2017 17:40:09 +0200
|
|
||||||
Subject: [PATCH] WIP 5: Experimental fix for libqb logging not working with
|
|
||||||
ld.bfd 2.29
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
What's missing:
|
|
||||||
* cross-testing programs vs. libqb prior/after this fix with ld.bfd 2.29
|
|
||||||
* program vs. library sanity attestation for good measure
|
|
||||||
- code header-included in the program could/shall run-time one-off
|
|
||||||
self-test the library code actually logs anything via custom callback
|
|
||||||
log handler
|
|
||||||
- library could/shall attest in qb_log_init that QB_ATTR_SECTION_START
|
|
||||||
+ STOP symbols belong to other address space than its own (dladdr?)
|
|
||||||
* related to that, we should really 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...
|
|
||||||
|
|
||||||
Version 2:
|
|
||||||
Simplify the compilation against libqb for its users that now no
|
|
||||||
longer need to worry to use a new flag for compilation with the
|
|
||||||
affected ld version, as semantically the same is already contained
|
|
||||||
in libqb.so itself (it's now a linker script instead of a common
|
|
||||||
symlink to the end versioned so file, which something known as an
|
|
||||||
implicit linker script:
|
|
||||||
https://sourceware.org/binutils/docs/ld/Implicit-Linker-Scripts.html).
|
|
||||||
|
|
||||||
Version 3:
|
|
||||||
Ditto for direct libqb.la users (incl. native examples and tests for
|
|
||||||
which the original Makefile.am form could have been restored thanks
|
|
||||||
to this -- not a subject of one-time configure check anymore),
|
|
||||||
to capture the case someone is using that libtool indirection directly
|
|
||||||
through a private checkout underneath the actual library user's repo.
|
|
||||||
The solutions is to slightly abuse libtool's library archive handling
|
|
||||||
and it's implicit dependency propagation within "dependency_libs"
|
|
||||||
variable, where we inject a reference to our own artificial library
|
|
||||||
archive that in turn eventually resolves to the discussed linker script.
|
|
||||||
|
|
||||||
Version 4:
|
|
||||||
Overcomes some unintended RPATH occurrences in qb-blackbox binary
|
|
||||||
or possibly libqb.so.*. That's definitely not desired:
|
|
||||||
https://fedoraproject.org/wiki/Packaging:Guidelines#Beware_of_Rpath
|
|
||||||
|
|
||||||
Version 5:
|
|
||||||
Overcomes issues when HAVE_GCC_ATTRIBUTE_SECTION is not defined, hence
|
|
||||||
qblog_script.ld script used to carry unresolved symbolic references as
|
|
||||||
a consequence: https://bugzilla.redhat.com/show_bug.cgi?id=1487787
|
|
||||||
Now the script is not used at all in that case, and if accidentally was,
|
|
||||||
there is an extra guard conditionalizing the content referring to those
|
|
||||||
values to only the case they are expected to be defined.
|
|
||||||
Plus some more, missing in retrospect, conditionalizing is added.
|
|
||||||
|
|
||||||
Deficiencies of version 5 (some carried over, apparently):
|
|
||||||
- see What's missing above
|
|
||||||
- possibly needs and overhaul regarding documentation of the arrangement
|
|
||||||
(now scattered throughout the files)
|
|
||||||
|
|
||||||
Deficiencies that are not solvable as long as we use the linker script
|
|
||||||
to participate in restoring boundary section symbols being global again:
|
|
||||||
- /usr/bin/ld: warning: ../lib/qblog_script.ld contains output sections; did you forget -T?
|
|
||||||
|
|
||||||
References:
|
|
||||||
http://oss.clusterlabs.org/pipermail/developers/2017-July/000503.html
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1477354#c8
|
|
||||||
|
|
||||||
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
|
||||||
---
|
|
||||||
configure.ac | 62 +++++++++++++++++++++++++++++++++++++---------
|
|
||||||
lib/Makefile.am | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
lib/log.c | 7 ++++++
|
|
||||||
lib/qblog_script.la.in | 15 +++++++++++
|
|
||||||
lib/qblog_script.ld.in | 17 +++++++++++++
|
|
||||||
6 files changed, 156 insertions(+), 12 deletions(-)
|
|
||||||
create mode 100644 lib/qblog_script.la.in
|
|
||||||
create mode 100644 lib/qblog_script.ld.in
|
|
||||||
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index fd37466..f94af71 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -618,31 +618,68 @@ AC_SUBST(HAVE_SLOW_TESTS)
|
|
||||||
|
|
||||||
# --- callsite sections ---
|
|
||||||
if test "x${GCC}" = xyes; then
|
|
||||||
+ LDFLAGS_save="${LDFLAGS}"
|
|
||||||
AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections])
|
|
||||||
if test "x${ac_cv_link_attribute_section}" = x ; then
|
|
||||||
+ LDFLAGS="${LDFLAGS_save} -shared -fPIC"
|
|
||||||
+ AC_LINK_IFELSE(
|
|
||||||
+ [AC_LANG_SOURCE(
|
|
||||||
+ [[#include <assert.h>
|
|
||||||
+ extern int __start___verbose[], __stop___verbose[];
|
|
||||||
+ int test(void) {
|
|
||||||
+ static int my_var __attribute__((section("__verbose"))) = 3;
|
|
||||||
+ if (__start___verbose == __stop___verbose) assert(0);
|
|
||||||
+ return *((int *) __start___verbose);
|
|
||||||
+ }]])],
|
|
||||||
+ [gcc_has_attribute_section=yes; cp "conftest${EXEEXT}" "lib_conftest.so"],
|
|
||||||
+ [gcc_has_attribute_section=no]
|
|
||||||
+ )
|
|
||||||
+ LDFLAGS="${LDFLAGS_save}"
|
|
||||||
+ else
|
|
||||||
+ gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
|
||||||
+ fi
|
|
||||||
+ AC_MSG_RESULT($gcc_has_attribute_section)
|
|
||||||
+
|
|
||||||
+ # in the failing case (e.g. with ld from binutils 2.29), it's probable
|
|
||||||
+ # linking will fail readily (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 draw the
|
|
||||||
+ # full circle back to binary through standard return value passing
|
|
||||||
+ # (-rpath passed because LD_LIBRARY_PATH exporting is unwieldy here)
|
|
||||||
+ if test "x${gcc_has_attribute_section}" = xyes; then
|
|
||||||
+ AC_MSG_CHECKING([whether linker emits global symbols for orphan sections])
|
|
||||||
+ LDFLAGS="${LDFLAGS_save} -L. -l_conftest -Wl,-rpath=$(pwd)"
|
|
||||||
AC_TRY_RUN(
|
|
||||||
AC_LANG_PROGRAM(
|
|
||||||
[[#include <assert.h>
|
|
||||||
- extern void * __start___verbose, * __stop___verbose;]],
|
|
||||||
+ extern int __start___verbose[], __stop___verbose[];
|
|
||||||
+ int test(void);]],
|
|
||||||
[[static int my_var __attribute__((section("__verbose"))) = 5;
|
|
||||||
if (__start___verbose == __stop___verbose) assert(0);
|
|
||||||
- if (my_var == 5) return 0;
|
|
||||||
- else return -1;
|
|
||||||
+ return !(my_var == test() /*5?*/);
|
|
||||||
]]),
|
|
||||||
- [gcc_has_attribute_section=yes],
|
|
||||||
- [gcc_has_attribute_section=no]
|
|
||||||
+ [gcc_has_attribute_section_visible=yes],
|
|
||||||
+ [gcc_has_attribute_section_visible=no]
|
|
||||||
)
|
|
||||||
- else
|
|
||||||
- gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
|
||||||
- fi
|
|
||||||
+ LDFLAGS="${LDFLAGS_save}"
|
|
||||||
+ AC_MSG_RESULT($gcc_has_attribute_section_visible)
|
|
||||||
+ rm -f "lib_conftest.so"
|
|
||||||
|
|
||||||
- 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"
|
|
||||||
+ 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
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
+AM_CONDITIONAL(HAVE_GCC_ATTRIBUTE_SECTION, [test "x${gcc_has_attribute_section}" = xyes])
|
|
||||||
+AM_CONDITIONAL(NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND,
|
|
||||||
+ [test "x${gcc_has_attribute_section}" = xyes \
|
|
||||||
+ && test "x${gcc_has_attribute_section_visible}" != xyes])
|
|
||||||
|
|
||||||
# --- ansi ---
|
|
||||||
if test "x${enable_ansi}" = xyes && \
|
|
||||||
@@ -721,7 +758,8 @@ AC_CONFIG_FILES([Makefile
|
|
||||||
docs/Makefile
|
|
||||||
docs/common.dox
|
|
||||||
docs/html.dox
|
|
||||||
- docs/man.dox])
|
|
||||||
+ docs/man.dox
|
|
||||||
+ lib/qblog_script.la:lib/qblog_script.la.in])
|
|
||||||
|
|
||||||
AC_OUTPUT
|
|
||||||
|
|
||||||
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
|
||||||
index 0bebeb5..85dd434 100644
|
|
||||||
--- a/lib/Makefile.am
|
|
||||||
+++ b/lib/Makefile.am
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
+CLEANFILES = qblog_script.ld
|
|
||||||
MAINTAINERCLEANFILES = Makefile.in
|
|
||||||
|
|
||||||
noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \
|
|
||||||
@@ -39,9 +40,48 @@ source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
|
|
||||||
log_syslog.c log_dcs.c log_format.c \
|
|
||||||
map.c skiplist.c hashtable.c trie.c
|
|
||||||
|
|
||||||
+# Following two files related to linkage using classic ld from binutils 2.29+
|
|
||||||
+# with which we cannot afford to lose public access to section boundary symbols
|
|
||||||
+# (as the mentioned version started to scope them privately by default, see
|
|
||||||
+# the comment within the first of the files, ultimately leading to broken
|
|
||||||
+# logging functionality of libqb) deserve a bit of explanation:
|
|
||||||
+# * qblog_script.ld
|
|
||||||
+# - linker script that instructs the output section that those symbols should
|
|
||||||
+# be visible, i.e. supports the same behaviour regardless of ld version
|
|
||||||
+# - serves two purposes:
|
|
||||||
+# . local: libqb itself and its "private" (cf. examples) users need those
|
|
||||||
+# symbols visible, which is achieved with a help of the other file
|
|
||||||
+# . system-wide: whenever the non-private library users link against libqb
|
|
||||||
+# (it's development files), this linker script with
|
|
||||||
+# prepended INPUT command so as to refer to the actual
|
|
||||||
+# libqb library (it's numbered alias that is eventually
|
|
||||||
+# resolved to proper shared library) is masked as libqb.so,
|
|
||||||
+# this arrangement achieves the libqb's user will have
|
|
||||||
+# the discussed symbols visible alike
|
|
||||||
+# * qblog_script.la
|
|
||||||
+# - as mentioned earlier, this indirectly hooks into libtool machinery, with
|
|
||||||
+# the only true intention of injecting "-Wl,<path to qblog_script.ld>"
|
|
||||||
+# into "inherited_linker_flags" libtool archive variable, from where it's
|
|
||||||
+# subsequently spread into the build process of all the internal library
|
|
||||||
+# users, assuming they have their dep arranged as "user_LIBADD=libqb.la"
|
|
||||||
+# (this also alleviates the burden on getting things right if, e.g., any
|
|
||||||
+# libqb user consumes it directly like this from its own sub-checkout tree)
|
|
||||||
+# - it indirectly, once libtool prechew the original link command
|
|
||||||
+# originally referring to this file, it turns such reference into the
|
|
||||||
+# "real" library reference (here combining libdir and old_library
|
|
||||||
+# variables within the file), also ensures libqb itself will visibly
|
|
||||||
+# expose the discussed symbols, because such references point again to
|
|
||||||
+# the (not enriched) linker script file that will get interpreted just
|
|
||||||
+# like that during the last build step of the library
|
|
||||||
+EXTRA_libqb_la_DEPENDENCIES = qblog_script.ld qblog_script.la
|
|
||||||
+EXTRA_DIST = qblog_script.ld.in qblog_script.la.in
|
|
||||||
+
|
|
||||||
libqb_la_SOURCES = $(source_to_lint) unix.c
|
|
||||||
libqb_la_CFLAGS = $(PTHREAD_CFLAGS)
|
|
||||||
libqb_la_LIBADD = $(LTLIBOBJS) $(dlopen_LIBS) $(PTHREAD_LIBS) $(socket_LIBS)
|
|
||||||
+if NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND
|
|
||||||
+libqb_la_LIBADD += qblog_script.la
|
|
||||||
+endif
|
|
||||||
|
|
||||||
AM_LDFLAGS = $(LDFLAGS_COPY:-Bsymbolic-functions=)
|
|
||||||
|
|
||||||
@@ -60,6 +100,33 @@ else
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
+qblog_script.ld: %.ld: %.ld.in
|
|
||||||
+ $(AM_V_GEN)$(CPP) -xc -I$(top_srcdir)/include -C -P $< \
|
|
||||||
+ | sed -n "/$$(sed -n '/^[^#]/{s/[*\/]/\\\0/g;p;q}' $<)/{:r;p;n;br}" \
|
|
||||||
+ > $@
|
|
||||||
+
|
|
||||||
+# find the libqb.so symlink's target, if so, try to find out, iteratively,
|
|
||||||
+# its gradually shorter forms that likewise symlinks the same target as the
|
|
||||||
+# original libqb.so path, point to that file from the linker script using
|
|
||||||
+# qblog_script.ld as a template, storing result in place of original libqb.so
|
|
||||||
+# (e.g., libqb.so := "INPUT(libqb.so.0) " [...] "SECTIONS { " [...] "}")
|
|
||||||
+# NOTE: readlink nor realpath are POSIX; not chained links ready
|
|
||||||
+# NOTE: conservative check, i.e., not per NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND
|
|
||||||
+if HAVE_GCC_ATTRIBUTE_SECTION
|
|
||||||
+install-exec-hook: qblog_script.ld
|
|
||||||
+ target=$$(ls -l "$(DESTDIR)$(libdir)/libqb.so" || :); \
|
|
||||||
+ target=$${target#* -> }; t1_bn=$$(basename "$${target}" || :); \
|
|
||||||
+ while test -n "$${t1_bn}"; do t2_bn=$${t1_bn%.*[0-9]*}; \
|
|
||||||
+ test "$${t2_bn}" != libqb.so || break; \
|
|
||||||
+ test -L "$${t2_bn}" || { t1_bn=$${t2_bn}; continue; }; \
|
|
||||||
+ t2_target=$$(ls -l "$${t2_bn}" || break); t2_target=$${t2_target#* -> }; \
|
|
||||||
+ test "$${t2_target}" = "$${target}" || break; \
|
|
||||||
+ t1_bn=$${t2_bn}; done; test -n "$${t1_bn}" || \
|
|
||||||
+ { echo "only applicable to SO symlink scheme"; exit 1; }; \
|
|
||||||
+ echo "INPUT($${t1_bn})" > "$(DESTDIR)$(libdir)/libqb.so-t"
|
|
||||||
+ cat $< >> "$(DESTDIR)$(libdir)/libqb.so-t"
|
|
||||||
+ mv -f "$(DESTDIR)$(libdir)/libqb.so-t" "$(DESTDIR)$(libdir)/libqb.so"
|
|
||||||
+endif
|
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
|
||||||
pkgconfig_DATA = libqb.pc
|
|
||||||
diff --git a/lib/log.c b/lib/log.c
|
|
||||||
index bfd218f..4ed432f 100644
|
|
||||||
--- a/lib/log.c
|
|
||||||
+++ b/lib/log.c
|
|
||||||
@@ -40,6 +40,13 @@
|
|
||||||
#include "util_int.h"
|
|
||||||
#include <regex.h>
|
|
||||||
|
|
||||||
+#if defined(QB_NEED_ATTRIBUTE_SECTION_WORKAROUND) && !defined(S_SPLINT_S)
|
|
||||||
+/* following only needed to force these symbols be global
|
|
||||||
+ with ld 2.29: https://bugzilla.redhat.com/1477354 */
|
|
||||||
+struct qb_log_callsite __attribute__((weak)) QB_ATTR_SECTION_START[] = { 0 };
|
|
||||||
+struct qb_log_callsite __attribute__((weak)) QB_ATTR_SECTION_STOP[] = { 0 };
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static struct qb_log_target conf[QB_LOG_TARGET_MAX];
|
|
||||||
static uint32_t conf_active_max = 0;
|
|
||||||
static int32_t in_logger = QB_FALSE;
|
|
||||||
diff --git a/lib/qblog_script.la.in b/lib/qblog_script.la.in
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..b475835
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/lib/qblog_script.la.in
|
|
||||||
@@ -0,0 +1,15 @@
|
|
||||||
+# Generated by libtool
|
|
||||||
+# NOTE: above line is just to pass func_ltwrapper_script_p sanity check of
|
|
||||||
+# libtool script, as we are basically sort of abusing it so as to inject
|
|
||||||
+# our custom linker script to "private" (cf. examples) users of libqb.la
|
|
||||||
+
|
|
||||||
+# shall rather carry a location of old_library (possibly libdir or something
|
|
||||||
+# else, but installed=no needed to suppress 'library moved' warning then) as
|
|
||||||
+# it's together (with libtool implied prefix otherwise) used for linking libqb
|
|
||||||
+libdir=@abs_builddir@
|
|
||||||
+
|
|
||||||
+# avoids issues with library_names (spurious rpath emitting, relink-on-install)
|
|
||||||
+old_library=qblog_script.ld
|
|
||||||
+
|
|
||||||
+# subject of our injection into libqb.la impacting build time for private users
|
|
||||||
+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
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/lib/qblog_script.ld.in
|
|
||||||
@@ -0,0 +1,17 @@
|
|
||||||
+#include <qb/qblog.h>
|
|
||||||
+/* GNU ld script
|
|
||||||
+ This atypical arrangement enforces global visibility of boundary symbols
|
|
||||||
+ (QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP) for the custom section
|
|
||||||
+ 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 */
|
|
||||||
+SECTIONS {
|
|
||||||
+#ifdef QB_HAVE_ATTRIBUTE_SECTION
|
|
||||||
+ QB_ATTR_SECTION : {
|
|
||||||
+ QB_ATTR_SECTION_START = .;
|
|
||||||
+ *(QB_ATTR_SECTION);
|
|
||||||
+ QB_ATTR_SECTION_STOP = .;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.14.1
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
From 8bfe49d79c1b7ae1aa4b7b22b627afa40a4a08d2 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
|
||||||
|
QB_LOG_INIT_DATA
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Based on better understanding how link-time callsite collection works,
|
||||||
|
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:
|
||||||
|
|
||||||
|
- use case:
|
||||||
|
/usr/sbin/pacemakerd --features
|
||||||
|
|
||||||
|
- before:
|
||||||
|
pacemakerd: utils.c:69: common:
|
||||||
|
Assertion `0' failed
|
||||||
|
|
||||||
|
- after:
|
||||||
|
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).
|
||||||
|
|
||||||
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
|
---
|
||||||
|
include/qb/qblog.h | 17 ++++++++++++-----
|
||||||
|
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
||||||
|
index 3cb4eef..d38449d 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);
|
||||||
|
extern struct qb_log_callsite QB_ATTR_SECTION_START[];
|
||||||
|
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
||||||
|
|
||||||
|
-/* mere linker sanity check, possible future extension for internal purposes */
|
||||||
|
-#define QB_LOG_INIT_DATA(name) \
|
||||||
|
- 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;
|
||||||
|
+ * only effective when link-time ("run-time amortizing") callsite collection
|
||||||
|
+ * is available and 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)); } \
|
||||||
|
void __attribute__ ((constructor)) name(void);
|
||||||
|
#else
|
||||||
|
#define QB_LOG_INIT_DATA(name)
|
||||||
|
--
|
||||||
|
2.14.2
|
||||||
|
|
@ -1,42 +1,47 @@
|
|||||||
From 37923941f659b1d264e33da188a1c0624cbd204b Mon Sep 17 00:00:00 2001
|
From d6491970c1e050dae3fc9b65fd34e4c170ca50a0 Mon Sep 17 00:00:00 2001
|
||||||
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
|
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
|
||||||
Date: Thu, 10 Aug 2017 17:13:32 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 1/2] build: configure: run attribute section test through
|
Subject: [PATCH 2/6] build: configure: run attribute section test through
|
||||||
run-time assertion
|
run-time assertion
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain; charset=UTF-8
|
Content-Type: text/plain; charset=UTF-8
|
||||||
Content-Transfer-Encoding: 8bit
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
It unclear why the apparently run-time test hasn't been set to that
|
It's unclear why the apparently run-time test hasn't been set to that
|
||||||
effect, but only the compilability was tested so far.
|
effect, mere compilability was tested so far.
|
||||||
|
|
||||||
|
Also, based on feedback by Ferenc Wágner, unify and increase usability
|
||||||
|
of the run-time error signalling through assertions.
|
||||||
|
|
||||||
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
---
|
---
|
||||||
configure.ac | 15 +++++++++------
|
configure.ac | 20 +++++++++++---------
|
||||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
diff --git a/configure.ac b/configure.ac
|
||||||
index 5ba4f99..fd37466 100644
|
index 22630ba..727b8f0 100644
|
||||||
--- a/configure.ac
|
--- a/configure.ac
|
||||||
+++ b/configure.ac
|
+++ b/configure.ac
|
||||||
@@ -620,15 +620,18 @@ AC_SUBST(HAVE_SLOW_TESTS)
|
@@ -620,15 +620,17 @@ AC_SUBST(HAVE_SLOW_TESTS)
|
||||||
if test "x${GCC}" = xyes; then
|
if test "x${GCC}" = xyes; then
|
||||||
AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections])
|
AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections])
|
||||||
if test "x${ac_cv_link_attribute_section}" = x ; then
|
if test "x${ac_cv_link_attribute_section}" = x ; then
|
||||||
- AC_TRY_LINK([#include <assert.h>
|
- AC_TRY_LINK([#include <assert.h>
|
||||||
- extern void * __start___verbose, * __stop___verbose;],
|
- extern void * __start___verbose, * __stop___verbose;],
|
||||||
- [static int my_var __attribute__((section("__verbose"))) = 5;
|
- [static int my_var __attribute__((section("__verbose"))) = 5;
|
||||||
|
- if (__start___verbose == __stop___verbose) assert(0);
|
||||||
|
- if (my_var == 5) return 0;
|
||||||
|
- else return -1;
|
||||||
|
- ],
|
||||||
|
- [gcc_has_attribute_section=yes],
|
||||||
|
- [gcc_has_attribute_section=no])
|
||||||
+ AC_TRY_RUN(
|
+ AC_TRY_RUN(
|
||||||
+ AC_LANG_PROGRAM(
|
+ AC_LANG_PROGRAM(
|
||||||
+ [[#include <assert.h>
|
+ [[#include <assert.h>
|
||||||
+ extern void * __start___verbose, * __stop___verbose;]],
|
+ extern void * __start___verbose, * __stop___verbose;]],
|
||||||
+ [[static int my_var __attribute__((section("__verbose"))) = 5;
|
+ [[static int my_var __attribute__((section("__verbose"))) = 5;
|
||||||
if (__start___verbose == __stop___verbose) assert(0);
|
+ assert(("non-empty data section", __start___verbose != __stop___verbose));
|
||||||
if (my_var == 5) return 0;
|
+ assert(("no data section value loss", my_var == 5));
|
||||||
else return -1;
|
|
||||||
- ],
|
|
||||||
- [gcc_has_attribute_section=yes],
|
|
||||||
- [gcc_has_attribute_section=no])
|
|
||||||
+ ]]),
|
+ ]]),
|
||||||
+ [gcc_has_attribute_section=yes],
|
+ [gcc_has_attribute_section=yes],
|
||||||
+ [gcc_has_attribute_section=no]
|
+ [gcc_has_attribute_section=no]
|
||||||
@ -45,5 +50,5 @@ index 5ba4f99..fd37466 100644
|
|||||||
gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
||||||
fi
|
fi
|
||||||
--
|
--
|
||||||
2.14.0
|
2.14.2
|
||||||
|
|
964
03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch
Normal file
964
03-tests-new-sort-of-tests-dubbed-functional-cover-link.patch
Normal file
@ -0,0 +1,964 @@
|
|||||||
|
From d9ed1dbcd9d58cac8573b75e6db323757f39e27b 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
|
||||||
|
linker vs. logging
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
These are for quick manual sanity checking, assuming the target audience
|
||||||
|
-- maintainers -- are clear on the context of use and the purpose
|
||||||
|
(perhaps with the help of static files for comparison and/or additional
|
||||||
|
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.
|
||||||
|
|
||||||
|
The respective new tests are meant to simulate logging variants in two
|
||||||
|
different library consumption models:
|
||||||
|
a. regular: linking against system-wide library
|
||||||
|
b. developmental: consuming library from a local sub-checkout tree,
|
||||||
|
using libtool conventions and hence attaching the
|
||||||
|
library through libqb.la intermediate library
|
||||||
|
descriptor of libtool
|
||||||
|
and between up to three possibly affected logging system participants
|
||||||
|
(discrete compilation units):
|
||||||
|
1. libqb itself will emit log messages in boundary conditions or
|
||||||
|
for tracing purposes
|
||||||
|
2. client program that consumes libqb's logging API directly
|
||||||
|
3. ditto, but the client program furthermore links with a library
|
||||||
|
(referred to as "interlib") that itself exercises the logging
|
||||||
|
API (it's also linked with libqb) -- through induction, this
|
||||||
|
should cover whole class of N interlib cases
|
||||||
|
|
||||||
|
Especially the latter perspective makes for a test matrix to possibly
|
||||||
|
(hopefully) demonstrate a fix allowing to cope with the changed
|
||||||
|
behaviour of ld from binutils 2.29+ wrt. boundaries denoting symbols for
|
||||||
|
a (custom) orphan section that are no longer externally visible. Such
|
||||||
|
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
|
||||||
|
-- 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
|
||||||
|
of the problem (see table below), and subsequently b/ that the fix is
|
||||||
|
effective in all these situations (updated table will be provided as
|
||||||
|
well) once it lands.
|
||||||
|
|
||||||
|
Current state for this matrix, in which participants 1. - 3. map like:
|
||||||
|
1. ~ libqb(Y)
|
||||||
|
2. ~ "direct"
|
||||||
|
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),
|
||||||
|
goes like this:
|
||||||
|
|
||||||
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
|
#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[*1] | BAD[*D] : BAD[*3] #
|
||||||
|
# x = b # BAD[*A] | BAD[*B] : BAD[*C] # BAD[*1] | BAD[*C] : BAD[*3] #
|
||||||
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
|
|
||||||
|
[*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 fails on 'non-empty callsite section' assertion
|
||||||
|
[*B] boils down to [*1], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
|
which fails on 'non-empty callsite section' assertion
|
||||||
|
[*C] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
|
which fails on 'non-empty callsite section' assertion
|
||||||
|
[*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])
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
some internal linkage garbage collection mechanisms involved.
|
||||||
|
Anyway, it is supposed that the fix to broken-by-linkage logging can be
|
||||||
|
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.
|
||||||
|
|
||||||
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
|
---
|
||||||
|
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 | 283 +++++++++++++++++++++++++++
|
||||||
|
18 files changed, 700 insertions(+), 2 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 100755 tests/functional/log_test_client.sh
|
||||||
|
create mode 100755 tests/functional/log_test_interlib_client.sh
|
||||||
|
create mode 100755 tests/functional/log_test_mock.sh
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 727b8f0..db7bc68 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([lib/ringbuffer.c])
|
||||||
|
AC_CONFIG_HEADERS([include/config.h include/qb/qbconfig.h])
|
||||||
|
AC_USE_SYSTEM_EXTENSIONS
|
||||||
|
|
||||||
|
-AM_INIT_AUTOMAKE([-Wno-portability dist-xz])
|
||||||
|
+AM_INIT_AUTOMAKE([-Wno-portability dist-xz subdir-objects])
|
||||||
|
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
|
||||||
|
lib/libqb.pc
|
||||||
|
tools/Makefile
|
||||||
|
tests/Makefile
|
||||||
|
+ tests/functional/Makefile
|
||||||
|
+ tests/functional/log_external/Makefile
|
||||||
|
+ tests/functional/log_internal/Makefile
|
||||||
|
tests/test.conf
|
||||||
|
examples/Makefile
|
||||||
|
docs/Makefile
|
||||||
|
@@ -722,6 +725,8 @@ AC_CONFIG_FILES([Makefile
|
||||||
|
docs/html.dox
|
||||||
|
docs/man.dox])
|
||||||
|
|
||||||
|
+AC_CONFIG_LINKS([tests/functional/GNUmakefile:tests/functional/GNUmakefile])
|
||||||
|
+
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
|
AC_MSG_RESULT([])
|
||||||
|
diff --git a/libqb.spec.in b/libqb.spec.in
|
||||||
|
index 8320982..cd7fd0f 100644
|
||||||
|
--- a/libqb.spec.in
|
||||||
|
+++ b/libqb.spec.in
|
||||||
|
@@ -31,7 +31,8 @@ make %{?_smp_mflags}
|
||||||
|
|
||||||
|
%if 0%{?with_check}
|
||||||
|
%check
|
||||||
|
-VERBOSE=1 make check
|
||||||
|
+make V=1 check \
|
||||||
|
+ && make -C tests/functional/log_internal V=1 check
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%install
|
||||||
|
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||||
|
index fe54741..df1af81 100644
|
||||||
|
--- a/tests/Makefile.am
|
||||||
|
+++ b/tests/Makefile.am
|
||||||
|
@@ -20,6 +20,9 @@
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
EXTRA_DIST =
|
||||||
|
CLEANFILES =
|
||||||
|
+
|
||||||
|
+SUBDIRS = functional
|
||||||
|
+
|
||||||
|
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
noinst_PROGRAMS = bmc bmcpt bms rbreader rbwriter \
|
||||||
|
diff --git a/tests/functional/GNUmakefile b/tests/functional/GNUmakefile
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1b9de81
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/GNUmakefile
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+all check:
|
||||||
|
+ # do not trigger automatically, it's for on-demand use
|
||||||
|
+ @echo "Use 'make $@' within particular subdirectories"
|
||||||
|
+install: force
|
||||||
|
+ # definitely not desired to install anything from this subtree
|
||||||
|
+distclean:
|
||||||
|
+ # following is a nasty hack to keep "make distclean" succeeding
|
||||||
|
+ # (problem mostly arises from shared object files and hence shared
|
||||||
|
+ # compiler-generated makefile includes which are swiped when
|
||||||
|
+ # processing one subdir and missing as hard error for the other)
|
||||||
|
+ @$(MAKE) -C log_external $@
|
||||||
|
+ @mkdir .deps
|
||||||
|
+ @touch .deps/log_client.Po .deps/log_interlib.Plo .deps/log_interlib_client.Po
|
||||||
|
+ @$(MAKE) -C log_internal $@
|
||||||
|
+ @$(MAKE) -f Makefile $@ SUBDIRS=
|
||||||
|
+%: force
|
||||||
|
+ @$(MAKE) -f Makefile $@
|
||||||
|
+force: ;
|
||||||
|
+
|
||||||
|
+.PHONY: check distclean force install
|
||||||
|
diff --git a/tests/functional/Makefile.am b/tests/functional/Makefile.am
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..72f551e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/Makefile.am
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+# Copyright 2017 Red Hat, Inc.
|
||||||
|
+#
|
||||||
|
+# Authors: 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/>.
|
||||||
|
+
|
||||||
|
+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
|
||||||
|
+SUBDIRS = log_external log_internal
|
||||||
|
diff --git a/tests/functional/log.am b/tests/functional/log.am
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..5fe1ae7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log.am
|
||||||
|
@@ -0,0 +1,49 @@
|
||||||
|
+# 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/>.
|
||||||
|
+
|
||||||
|
+MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
+CLEANFILES = log_client.err.real log_interlib_client.err.real
|
||||||
|
+
|
||||||
|
+AM_CPPFLAGS = -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
|
||||||
|
+# (this won't get installed anyway, thanks to GNUmakefile rule)
|
||||||
|
+lib_LTLIBRARIES = liblog_inter.la
|
||||||
|
+
|
||||||
|
+log_client_SOURCES = ../log_client.c
|
||||||
|
+# log_client_LDFLAGS/log_client_LDADD to be delivered by the base Makefile.am
|
||||||
|
+
|
||||||
|
+liblog_inter_la_SOURCES = ../log_interlib.c
|
||||||
|
+liblog_inter_la_LDFLAGS = -shared
|
||||||
|
+# liblog_inter_la_LIBADD to be delivered by the base Makefile.am
|
||||||
|
+
|
||||||
|
+log_interlib_client_SOURCES = ../log_interlib_client.c
|
||||||
|
+# this transitively shares link dependencies with liblog_inter.la itself
|
||||||
|
+log_interlib_client_LDADD = $(builddir)/liblog_inter.la
|
||||||
|
+
|
||||||
|
+# actual 'make check' auxiliary definitions
|
||||||
|
+TESTS = ../log_test_client.sh ../log_test_interlib_client.sh
|
||||||
|
+TEST_EXTENSIONS = .sh
|
||||||
|
+log_test.log: $(check_PROGRAMS)
|
||||||
|
+
|
||||||
|
+../log_test_client.log: log_client
|
||||||
|
+../log_test_interlib_client.log: log_interlib_client
|
||||||
|
+
|
||||||
|
+# vim: ft=automake
|
||||||
|
diff --git a/tests/functional/log_client.c b/tests/functional/log_client.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..aa6ebe1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_client.c
|
||||||
|
@@ -0,0 +1,86 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright 2017 Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * 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/>.
|
||||||
|
+ */
|
||||||
|
+#include "os_base.h"
|
||||||
|
+#include <qb/qblog.h>
|
||||||
|
+
|
||||||
|
+#ifndef NSELFCHECK
|
||||||
|
+QB_LOG_INIT_DATA(linker_contra_log);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static const char *
|
||||||
|
+my_tags_stringify(uint32_t tags)
|
||||||
|
+{
|
||||||
|
+ if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT)) {
|
||||||
|
+ return "libqb";
|
||||||
|
+ } else {
|
||||||
|
+ return "MAIN";
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int32_t
|
||||||
|
+main(int32_t argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ int tmpfile_fd;
|
||||||
|
+ struct stat tmpfile_stat;
|
||||||
|
+ char *tmpfile_buf = strdup("linker-log-XXXXXX");
|
||||||
|
+
|
||||||
|
+ qb_log_init("linker-contra-log", LOG_USER, LOG_INFO);
|
||||||
|
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||||
|
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
|
||||||
|
+ QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
|
||||||
|
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||||
|
+
|
||||||
|
+ qb_log_tags_stringify_fn_set(my_tags_stringify);
|
||||||
|
+ qb_log_format_set(QB_LOG_STDERR, "[%5g|%p] %f:%l:%b");
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+ printf("--\n");
|
||||||
|
+ qb_log_callsites_dump();
|
||||||
|
+ printf("--\n");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Casual test of "user-space" logging. */
|
||||||
|
+ qb_log(LOG_DEBUG, "hello");
|
||||||
|
+
|
||||||
|
+ /* 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
|
||||||
|
+ logged at all, second if it will be distinguished properly.
|
||||||
|
+ The trigger here is as simple as trying to print non-existing
|
||||||
|
+ blackbox file. */
|
||||||
|
+ tmpfile_fd = mkstemp(tmpfile_buf);
|
||||||
|
+ if (tmpfile_fd == -1) {
|
||||||
|
+ qb_perror(LOG_ERR, "creating temporary file");
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+ unlink(tmpfile_buf);
|
||||||
|
+ close(tmpfile_fd);
|
||||||
|
+#if 0
|
||||||
|
+ if (stat(tmpfile_buf, &tmpfile_stat) == -1) {
|
||||||
|
+ qb_perror(LOG_ERR, "stat'ing nonexistent temporary file");
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ qb_log_blackbox_print_from_file(tmpfile_buf);
|
||||||
|
+ 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
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_external/Makefile.am
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+# 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/>.
|
||||||
|
+
|
||||||
|
+include ../log.am
|
||||||
|
+
|
||||||
|
+log_client_LDFLAGS = -lqb
|
||||||
|
+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
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_interlib.c
|
||||||
|
@@ -0,0 +1,68 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright 2017 Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * 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/>.
|
||||||
|
+ */
|
||||||
|
+#include "os_base.h"
|
||||||
|
+#include <qb/qblog.h>
|
||||||
|
+
|
||||||
|
+#ifndef NSELFCHECK
|
||||||
|
+QB_LOG_INIT_DATA(linker_contra_log_lib);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+void foo(void);
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+foo(void)
|
||||||
|
+{
|
||||||
|
+ int tmpfile_fd;
|
||||||
|
+ struct stat tmpfile_stat;
|
||||||
|
+ char *tmpfile_buf = strdup("linker-log-XXXXXX");
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+ printf("--\n");
|
||||||
|
+ qb_log_callsites_dump();
|
||||||
|
+ printf("--\n");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Casual test of "user-space" logging. */
|
||||||
|
+ qb_log(LOG_INFO, "hello");
|
||||||
|
+
|
||||||
|
+ /* 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
|
||||||
|
+ logged at all, second if it will be distinguished properly.
|
||||||
|
+ The trigger here is as simple as trying to print non-existing
|
||||||
|
+ blackbox file. */
|
||||||
|
+ tmpfile_fd = mkstemp(tmpfile_buf);
|
||||||
|
+ if (tmpfile_fd == -1) {
|
||||||
|
+ qb_perror(LOG_ERR, "creating temporary file");
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+ unlink(tmpfile_buf);
|
||||||
|
+ close(tmpfile_fd);
|
||||||
|
+#if 0
|
||||||
|
+ if (stat(tmpfile_buf, &tmpfile_stat) == -1) {
|
||||||
|
+ qb_perror(LOG_ERR, "stat'ing nonexistent temporary file");
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ qb_log_blackbox_print_from_file(tmpfile_buf);
|
||||||
|
+ free(tmpfile_buf);
|
||||||
|
+}
|
||||||
|
diff --git a/tests/functional/log_interlib_client.c b/tests/functional/log_interlib_client.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..c669703
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_interlib_client.c
|
||||||
|
@@ -0,0 +1,64 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright 2017 Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * 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/>.
|
||||||
|
+ */
|
||||||
|
+#include "os_base.h"
|
||||||
|
+#include <qb/qblog.h>
|
||||||
|
+
|
||||||
|
+#ifndef NSELFCHECK
|
||||||
|
+QB_LOG_INIT_DATA(linker_contra_log_lib_user);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+void foo(void);
|
||||||
|
+
|
||||||
|
+static const char *
|
||||||
|
+my_tags_stringify(uint32_t tags)
|
||||||
|
+{
|
||||||
|
+ if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT)) {
|
||||||
|
+ return "libqb";
|
||||||
|
+ } else {
|
||||||
|
+ return "MAIN";
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main(int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ qb_log_init("linker-contra-log", LOG_USER, LOG_INFO);
|
||||||
|
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||||
|
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
|
||||||
|
+ QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
|
||||||
|
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||||
|
+
|
||||||
|
+ qb_log_tags_stringify_fn_set(my_tags_stringify);
|
||||||
|
+ qb_log_format_set(QB_LOG_STDERR, "[%5g|%p] %f:%l:%b");
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+ printf("--\n");
|
||||||
|
+ qb_log_callsites_dump();
|
||||||
|
+ printf("--\n");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ qb_log(LOG_INFO, "BEFORE");
|
||||||
|
+ foo();
|
||||||
|
+ qb_log(LOG_INFO, "AFTER");
|
||||||
|
+ 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
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_internal/Makefile.am
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+# 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/>.
|
||||||
|
+
|
||||||
|
+include ../log.am
|
||||||
|
+
|
||||||
|
+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.sh b/tests/functional/log_test_client.sh
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000..875871e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_test_client.sh
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+# 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/>.
|
||||||
|
+
|
||||||
|
+./log_client >/dev/null 2>log_client.err.real
|
||||||
|
+diff -u ../log_client.err log_client.err.real
|
||||||
|
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
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_test_interlib_client.sh
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+# 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/>.
|
||||||
|
+
|
||||||
|
+./log_interlib_client >/dev/null 2>log_interlib_client.err.real
|
||||||
|
+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..cc3519d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/functional/log_test_mock.sh
|
||||||
|
@@ -0,0 +1,283 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+# 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/>.
|
||||||
|
+
|
||||||
|
+# Given the source RPM for libqb, this will run through the basic test matrix
|
||||||
|
+# so as to figure out the outcomes for particular linker (pre-2.29 and 2.29+
|
||||||
|
+# differing in visibility of orphan section delimiting boundary symbols and
|
||||||
|
+# hence possibly causing harm to the logging facility of libqb) being used
|
||||||
|
+# for particular part of the composite logging system (libqb itself,
|
||||||
|
+# it's direct client / (client library + it's own client that uses logging)
|
||||||
|
+# as well). While this is tailored to Fedora, it should be possible to
|
||||||
|
+# run this testsuite wherever following is present:
|
||||||
|
+#
|
||||||
|
+# - rpm (for parsing archive name embedded in libqb.src.rpm [note that
|
||||||
|
+# rpm2cpio is part of rpm package as well] because the extracted dir
|
||||||
|
+# follows the same naming, which we need to know)
|
||||||
|
+# - mock + dependencies + fedora-27-${arch} configuration for mock
|
||||||
|
+# (or whatever other configuration if some variables below are
|
||||||
|
+# changed appropriately)
|
||||||
|
+# - koji + dependencies (but binutils packages can be precached when
|
||||||
|
+# downloaded from https://koji.fedoraproject.org/ manually)
|
||||||
|
+# - internet connection (but see the above statement for koji, and
|
||||||
|
+# possibly the full package set within the build'n'test underlying
|
||||||
|
+# container can be precached without further details on "how")
|
||||||
|
+# - commons (coreutils, findutils, sed, ...)
|
||||||
|
+#
|
||||||
|
+# The testsuite will not mangle with your host system as mock spawns
|
||||||
|
+# it's somewhat private container for be worked with under the hood.
|
||||||
|
+#
|
||||||
|
+# Note that in order not to get mad when entering the root password anytime
|
||||||
|
+# mock is invoked, you can add the user initiating the test run to the
|
||||||
|
+# 'mock' group. Be aware of the associated security risks, though:
|
||||||
|
+# https://github.com/rpm-software-management/mock/wiki#setup
|
||||||
|
+
|
||||||
|
+set -eu
|
||||||
|
+
|
||||||
|
+# change following as suitable
|
||||||
|
+
|
||||||
|
+arch=x86_64
|
||||||
|
+mock_args="-r fedora-27-${arch}"
|
||||||
|
+pkg_binutils_228=binutils-2.28-14.fc27
|
||||||
|
+pkg_binutils_229=binutils-2.29-6.fc27
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# prettified reporters
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+do_progress () { printf "\x1b[7m%s\x1b[0m\n" "$*"; }
|
||||||
|
+do_info () { printf "\x1b[36mINFO: %s\x1b[0m\n" "$*"; }
|
||||||
|
+do_warn () { printf "\x1b[31mWARNING: %s\x1b[0m\n" "$*"; }
|
||||||
|
+do_die () { printf "\x1b[31mFATAL: %s\x1b[0m\n" "$*"; exit 1; }
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# actual building blocks
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# $1, ... $N: packages (and possibly related subpackages) to be downloaded
|
||||||
|
+do_download () {
|
||||||
|
+ while test $# -gt 0; do
|
||||||
|
+ if test -d "_pkgs/$1" 2>/dev/null; then
|
||||||
|
+ do_info "$1 already downloaded"
|
||||||
|
+ shift; continue
|
||||||
|
+ fi
|
||||||
|
+ mkdir -p "_pkgs/$1"
|
||||||
|
+ ( cd "_pkgs/$1" && koji download-build --arch="${arch}" "$1" )
|
||||||
|
+ shift
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# $1, ... $N: descriptors of packages to be installed
|
||||||
|
+do_install () {
|
||||||
|
+ while test $# -gt 0; do
|
||||||
|
+ if test -d "_pkgs/$1" 2>/dev/null; then
|
||||||
|
+ do_install_inner "_pkgs/$1"/*.rpm
|
||||||
|
+ else
|
||||||
|
+ do_warn "$1 is not downloaded, hence skipped"
|
||||||
|
+ fi
|
||||||
|
+ shift
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# $1, ... $N: concrete packages to be installed
|
||||||
|
+do_install_inner () {
|
||||||
|
+ _remove_cmd="mock ${mock_args} -- shell \"rpm --nodeps --erase"
|
||||||
|
+ _install_cmd="mock ${mock_args}"
|
||||||
|
+ while test $# -gt 0; do
|
||||||
|
+ case "$1" in
|
||||||
|
+ *.src.rpm|*-debuginfo*|*-debugsource*) ;;
|
||||||
|
+ *)
|
||||||
|
+ _pkg_name="$(basename "$1" | sed 's|\(-[0-9].*\)||')"
|
||||||
|
+ _remove_cmd="${_remove_cmd} \'${_pkg_name}\'"
|
||||||
|
+ _install_cmd="${_install_cmd} --install \"$1\"";;
|
||||||
|
+ esac
|
||||||
|
+ shift
|
||||||
|
+ done
|
||||||
|
+ eval "${_remove_cmd}\"" || : # extra quotation mark intentional
|
||||||
|
+ eval "${_install_cmd}"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# $1: full path of srpm to be rebuilt
|
||||||
|
+# $2: %{dist} macro for rpmbuild (distinguishing the builds)
|
||||||
|
+do_buildsrpm () {
|
||||||
|
+ _pkg_descriptor="$(basename "$1" | sed 's|\.src\.rpm$||')"
|
||||||
|
+ # need to prune due to possible duplicates caused by differing %{dist}
|
||||||
|
+ rm -f -- "_pkgs/${_pkg_descriptor}"/*
|
||||||
|
+ mock ${mock_args} -Nn --define "dist $2" --define '_without_check 1' \
|
||||||
|
+ --resultdir "_pkgs/${_pkg_descriptor}" --rebuild "$1"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# $1: full path srpm to be rebuilt
|
||||||
|
+# $2: extra (presumably) variable assignments for the make goal invocation
|
||||||
|
+do_compile_interlib () {
|
||||||
|
+ mock ${mock_args} --shell \
|
||||||
|
+ "find \"builddir/build/BUILD/$1/tests/functional\" \
|
||||||
|
+ \( -name log_internal -o -name '*.c' \) -prune \
|
||||||
|
+ -o -name '*liblog_inter*' \
|
||||||
|
+ -exec rm -- {} \;"
|
||||||
|
+ mock ${mock_args} --shell "( cd \"builddir/build/BUILD/$1\"; ./configure )"
|
||||||
|
+ mock ${mock_args} --shell \
|
||||||
|
+ "make -C \"builddir/build/BUILD/$1/tests/functional/log_external\" \
|
||||||
|
+ liblog_inter.la $2"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# $1: full path srpm to be rebuilt
|
||||||
|
+# $2: which type of client to work with (client/interclient)
|
||||||
|
+# $3: base (on-host) directory for test results
|
||||||
|
+# $4: output file to capture particular test result
|
||||||
|
+# $5: extra (presumably) variable assignments for the make goal invocation
|
||||||
|
+do_compile_and_test_client () {
|
||||||
|
+ _result=$4
|
||||||
|
+ case "$2" in
|
||||||
|
+ interclient)
|
||||||
|
+ _logfile=log_test_interlib_client
|
||||||
|
+ mock ${mock_args} --shell \
|
||||||
|
+ "find \"builddir/build/BUILD/$1/tests/functional\" \
|
||||||
|
+ \( -name log_internal -o -name '*.err' -o -name '*.c' \) -prune \
|
||||||
|
+ -o \( -name '*log_interlib_client*' -o -name \"${_logfile}.log\" \) \
|
||||||
|
+ -exec rm -- {} \;"
|
||||||
|
+ ;;
|
||||||
|
+ client|*)
|
||||||
|
+ _logfile=log_test_client
|
||||||
|
+ mock ${mock_args} --shell \
|
||||||
|
+ "find \"builddir/build/BUILD/$1/tests/functional\" \
|
||||||
|
+ \( -name log_internal -o -name '*.err' -o -name '*.c' \) -prune \
|
||||||
|
+ -o \( -name '*log_client*' -o -name \"${_logfile}.log\" \) \
|
||||||
|
+ -exec rm -- {} \;"
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+ 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" \
|
||||||
|
+ && _result="${_result}_good" \
|
||||||
|
+ || _result="${_result}_bad"
|
||||||
|
+ mock ${mock_args} --copyout \
|
||||||
|
+ "builddir/build/BUILD/$1/tests/functional/log_external/test-suite.log" \
|
||||||
|
+ "$3/${_result}"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+do_shell () {
|
||||||
|
+ mock ${mock_args} --shell
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# $1, ... $N: "argv"
|
||||||
|
+do_proceed () {
|
||||||
|
+
|
||||||
|
+ _makevars=
|
||||||
|
+ case "$1" in
|
||||||
|
+ shell) shift; do_shell "$@"; return;;
|
||||||
|
+ -n) shift; _makevars='CPPFLAGS=-DNSELFCHECK';;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ test -s "$1" || do_die "Not an input file: $1"
|
||||||
|
+ _libqb_descriptor_path="$1"
|
||||||
|
+ _libqb_descriptor="$(basename "${_libqb_descriptor_path}" \
|
||||||
|
+ | sed 's|\.src\.rpm$||')"
|
||||||
|
+ _libqb_descriptor_archive="$(rpm -q --qf '[%{FILENAMES}\n]' \
|
||||||
|
+ -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}_sc"
|
||||||
|
+ mkdir -p "${_resultsdir}"
|
||||||
|
+ rm -f -- "${_resultsdir}/*"
|
||||||
|
+
|
||||||
|
+ _dist=
|
||||||
|
+ _outfile=
|
||||||
|
+ _outfile_client=
|
||||||
|
+ _outfile_qb=
|
||||||
|
+
|
||||||
|
+ do_download "${pkg_binutils_228}" "${pkg_binutils_229}"
|
||||||
|
+
|
||||||
|
+ for _pkg_binutils_libqb in "${pkg_binutils_228}" "${pkg_binutils_229}"; do
|
||||||
|
+
|
||||||
|
+ case "${_pkg_binutils_libqb}" in
|
||||||
|
+ ${pkg_binutils_228}) _outfile_qb="qb+"; _dist=.binutils228;;
|
||||||
|
+ ${pkg_binutils_229}) _outfile_qb="qb-"; _dist=.binutils229;;
|
||||||
|
+ *) _outfile_qb="?";;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ do_progress "installing ${_pkg_binutils_libqb} so as to build" \
|
||||||
|
+ " libqb [${_outfile_qb}]"
|
||||||
|
+ do_install "${_pkg_binutils_libqb}"
|
||||||
|
+
|
||||||
|
+ do_progress "building ${_libqb_descriptor_path} with" \
|
||||||
|
+ " ${_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}]"
|
||||||
|
+ do_install "${_libqb_descriptor}"
|
||||||
|
+
|
||||||
|
+ for _pkg_binutils_interlib in none "${pkg_binutils_228}" "${pkg_binutils_229}"; do
|
||||||
|
+
|
||||||
|
+ case "${_pkg_binutils_interlib}" in
|
||||||
|
+ none) _outfile="${_outfile_qb}";;
|
||||||
|
+ ${pkg_binutils_228}) _outfile="${_outfile_qb}_il+";;
|
||||||
|
+ ${pkg_binutils_229}) _outfile="${_outfile_qb}_il-";;
|
||||||
|
+ *) _outfile="${_outfile_qb}_?";;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ case "${_pkg_binutils_interlib}" in
|
||||||
|
+ none) ;;
|
||||||
|
+ *)
|
||||||
|
+ do_progress "installing ${_pkg_binutils_interlib}" \
|
||||||
|
+ " so as to build interlib [${_outfile}]"
|
||||||
|
+ do_install "${_pkg_binutils_interlib}"
|
||||||
|
+
|
||||||
|
+ do_progress "building interlib with ${_libqb_descriptor_archive}" \
|
||||||
|
+ " + ${_pkg_binutils_interlib} [${_outfile}]"
|
||||||
|
+ do_compile_interlib "${_libqb_descriptor_archive}" "${_makevars}"
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ for _pkg_binutils_client in "${pkg_binutils_228}" "${pkg_binutils_229}"; do
|
||||||
|
+
|
||||||
|
+ _client=client
|
||||||
|
+ test "${_pkg_binutils_interlib}" = none || _client=interclient
|
||||||
|
+
|
||||||
|
+ case "${_pkg_binutils_client}" in
|
||||||
|
+ ${pkg_binutils_228}) _outfile_client="${_outfile}_c+";;
|
||||||
|
+ ${pkg_binutils_229}) _outfile_client="${_outfile}_c-";;
|
||||||
|
+ *) _outfile_client="${_outfile}_?";;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ do_progress "installing ${_pkg_binutils_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}]"
|
||||||
|
+ do_compile_and_test_client "${_libqb_descriptor_archive}" \
|
||||||
|
+ "${_client}" "${_resultsdir}" \
|
||||||
|
+ "${_outfile_client}" "${_makevars}"
|
||||||
|
+ done
|
||||||
|
+ done
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+test $# -eq 0 \
|
||||||
|
+ && printf '%s\n %s\n %s\n %s\n %s\n %s\n' \
|
||||||
|
+ "usage: $0 {[-n] <libqb.src.rpm> | shell}" \
|
||||||
|
+ "- use '-n' to suppress optional self-check (\"see whole story\")" \
|
||||||
|
+ "- '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" \
|
||||||
|
+ "- results stored in '_results/<timestamp>_<input_name>[_<tag>]'" \
|
||||||
|
+ || do_proceed "$@"
|
||||||
|
--
|
||||||
|
2.14.2
|
||||||
|
|
257
04-Med-add-extra-run-time-client-side-sanity-check-that.patch
Normal file
257
04-Med-add-extra-run-time-client-side-sanity-check-that.patch
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
From 82835b453ac212937592c5a47e992d70b6f2d82b 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
|
||||||
|
|
446
05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch
Normal file
446
05-High-bare-fix-for-libqb-logging-not-working-with-ld..patch
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
From a76c1d7c3466746c96dffd6406017d438bb22018 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
|
||||||
|
ld.bfd/binutils 2.29+
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Initially with the help of the internal test suite and the failing log
|
||||||
|
test, it was eventually discovered[1] that these binutils commits going
|
||||||
|
to the recent 2.29 release affected the treatment of _start_SECNAME
|
||||||
|
and __stop_SECNAME symbols denoting the boundary start/stop addresses
|
||||||
|
of a SECNAME orphan section -- specifically in libqb context a custom
|
||||||
|
section (SECNAME=__verbose) used for link-time ("run-time amortizing")
|
||||||
|
callsite collection when there's a support in the toolchain[*]:
|
||||||
|
|
||||||
|
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cbd0eecf261c2447781f8c89b0d955ee66fae7e9
|
||||||
|
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b27685f2016c510d03ac9a64f7b04ce8efcf95c4
|
||||||
|
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7dba9362c172f1073487536eb137feb2da30b0ff
|
||||||
|
|
||||||
|
The first one explicitly states:
|
||||||
|
> Also __start_SECNAME and __stop_SECNAME symbols are marked as hidden
|
||||||
|
> by ELF linker so that __start_SECNAME and __stop_SECNAME symbols for
|
||||||
|
> section SECNAME in different modules are unique.
|
||||||
|
|
||||||
|
The problem is that libqb silently depends on the previous status quo
|
||||||
|
ld.bfd linker behaviour of keeping those symbols externally visible,
|
||||||
|
which was apparently not granted as it has deliberately changed per
|
||||||
|
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
|
||||||
|
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
|
||||||
|
the original version of the changeset, only the configure script check
|
||||||
|
had to be refined so as not to miss the "orphan section magic not
|
||||||
|
working properly out of the box, without a bandaid" obseration (see the
|
||||||
|
inline comment) -- the workaround arrangement needs 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).
|
||||||
|
|
||||||
|
This solution alone, while working for the non-libqb (more on that
|
||||||
|
below) logging participants, is not good enough, as it requires all
|
||||||
|
libqb targets to start using new incantation (namely "-Wl,foo.t" switch)
|
||||||
|
in the final link step during compilation, which might be solvable
|
||||||
|
with a tweak in libqb's pkg-config file under assumption that practice
|
||||||
|
of using "pkg-config --libs libqb" is rigidly followed. Which is likely
|
||||||
|
a false expectation, and furthermore only for the regular consumption
|
||||||
|
model, as it doesn't cover the least bit the developmental one (refer
|
||||||
|
to previous-but-one "tests" commit message), e.g. applied for internal
|
||||||
|
examples + tests (but no local sub-checkout tree usage can be excluded).
|
||||||
|
|
||||||
|
So further extensions were devised to cover both consumption models:
|
||||||
|
|
||||||
|
- a. regular:
|
||||||
|
courtesy of binutils maintainer[3], we follow an idea to make libqb.so
|
||||||
|
(i.e. what the targets link against) rather a linker script on its
|
||||||
|
own, which first include the version-specified (e.g. libqb.so.0) file
|
||||||
|
into the link, then lists, in situ, the content of the linker script
|
||||||
|
per above, hence -lqb linking has the same effect as having both
|
||||||
|
"-lqb -Wl,foo.t" explicitly in the link command prior to this trick
|
||||||
|
|
||||||
|
- b. developmental:
|
||||||
|
to eliminate any kind of race condition arising from the attempt
|
||||||
|
to post-modify libqb.la libtool archive file generated internally
|
||||||
|
by libtool, we sort of abuse "inherited_linker_flags" variable
|
||||||
|
within this file format, as it forms an accumulative value across
|
||||||
|
the whole transitive dependencies chain, which serves exactly our
|
||||||
|
purpose of injecting "-Wl,foo.t" switch equivalent for those
|
||||||
|
libtool-linking by L{D,IB}ADDing libqb.la; it's then enough to
|
||||||
|
craft a custom libtool archive file declaring that value, and
|
||||||
|
hook it into such dependency chain through libqb_la_LIBADD, and
|
||||||
|
with a little bit of further fiddling, it works as desired
|
||||||
|
(note that double occurrence of "-Wl,foo.t" equivalent achieved
|
||||||
|
at some point when developing this trick turned to be, surprisingly,
|
||||||
|
counter-productive)
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
and here you are (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 : <OK> # <OK> | <OK> : <OK> #
|
||||||
|
# x = b # <OK> | <OK> : <OK> # <OK> | <OK> : <OK> #
|
||||||
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
|
|
||||||
|
Everything is green \o/
|
||||||
|
|
||||||
|
Note: as of this fix, it is assumed that the non-green counterpart of
|
||||||
|
this table in the message for the preceding commit doubles as an
|
||||||
|
indicator how will mixing the logging participants wrt. linker+libqb
|
||||||
|
version work out, when "X(Y)" becomes read as "X linked with linker
|
||||||
|
Y under additional restriction on libqb version when compile-time link
|
||||||
|
is performed of the particular part":
|
||||||
|
X(a) .. ld.bfd < 2.29 OR [arbitrary ld.bfd AND libqb after this fix)
|
||||||
|
X(b) .. ld.bfd = 2.29 (and likely on) AND libqb up to, but excluding
|
||||||
|
this fix
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
Let's also state some imperfections and loops kept open:
|
||||||
|
|
||||||
|
Deficiencies:
|
||||||
|
* whenever anything is compiled against our install-time-modified
|
||||||
|
libqb.so so as to force the visibility of the discussed symbols
|
||||||
|
(or when compiling [with] libqb internally):
|
||||||
|
> /usr/bin/ld: warning: ../lib/qblog_script.ld contains output sections; did you forget -T?
|
||||||
|
- not solvable as long as we use the linker script, and there's
|
||||||
|
hardly any other way not requiring the libqb consumers to adapt
|
||||||
|
in any way
|
||||||
|
|
||||||
|
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...
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
[*] basically GCC's section("SECNAME") __attribute__ annotation of the
|
||||||
|
global variables + linker described behaviour previously mistakenly
|
||||||
|
taken for granted
|
||||||
|
|
||||||
|
References:
|
||||||
|
[1] http://oss.clusterlabs.org/pipermail/developers/2017-July/000503.html
|
||||||
|
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1477354#c2 + comment 8
|
||||||
|
[3] https://bugzilla.redhat.com/show_bug.cgi?id=1477354#c9
|
||||||
|
|
||||||
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
|
---
|
||||||
|
configure.ac | 71 +++++++++++++++++++++++++++++++++++++++---------
|
||||||
|
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, 165 insertions(+), 13 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..5d17443 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -618,31 +618,74 @@ AC_SUBST(HAVE_SLOW_TESTS)
|
||||||
|
|
||||||
|
# --- callsite sections ---
|
||||||
|
if test "x${GCC}" = xyes; then
|
||||||
|
+ LDFLAGS_save="${LDFLAGS}"
|
||||||
|
AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections])
|
||||||
|
if test "x${ac_cv_link_attribute_section}" = x ; then
|
||||||
|
- AC_TRY_RUN(
|
||||||
|
- AC_LANG_PROGRAM(
|
||||||
|
+ LDFLAGS="${LDFLAGS_save} -shared -fPIC"
|
||||||
|
+ AC_LINK_IFELSE(
|
||||||
|
+ [AC_LANG_SOURCE(
|
||||||
|
[[#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));
|
||||||
|
- ]]),
|
||||||
|
- [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"],
|
||||||
|
[gcc_has_attribute_section=no]
|
||||||
|
)
|
||||||
|
+ LDFLAGS="${LDFLAGS_save}"
|
||||||
|
else
|
||||||
|
gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
||||||
|
fi
|
||||||
|
-
|
||||||
|
AC_MSG_RESULT($gcc_has_attribute_section)
|
||||||
|
- if test $gcc_has_attribute_section = yes; then
|
||||||
|
+
|
||||||
|
+ # 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;
|
||||||
|
+ # -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
|
||||||
|
+ # harness, as it restored some (but not all) of the original behaviour,
|
||||||
|
+ # 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])
|
||||||
|
+ LDFLAGS="${LDFLAGS_save} -L. -l_conftest -Wl,-rpath=$(pwd)"
|
||||||
|
+ AC_TRY_RUN(
|
||||||
|
+ 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 == test() /*5?*/));
|
||||||
|
+ ]]),
|
||||||
|
+ [gcc_has_attribute_section_visible=yes],
|
||||||
|
+ [gcc_has_attribute_section_visible=no]
|
||||||
|
+ )
|
||||||
|
+ LDFLAGS="${LDFLAGS_save}"
|
||||||
|
+ AC_MSG_RESULT($gcc_has_attribute_section_visible)
|
||||||
|
+ rm -f "lib_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,
|
||||||
|
+ [Enabling code using __attribute__((section))])
|
||||||
|
+ PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section-workaround"
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
+AM_CONDITIONAL(HAVE_GCC_ATTRIBUTE_SECTION, [test "x${gcc_has_attribute_section}" = xyes])
|
||||||
|
+AM_CONDITIONAL(NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND,
|
||||||
|
+ [test "x${gcc_has_attribute_section}" = xyes \
|
||||||
|
+ && test "x${gcc_has_attribute_section_visible}" != xyes])
|
||||||
|
|
||||||
|
# --- ansi ---
|
||||||
|
if test "x${enable_ansi}" = xyes && \
|
||||||
|
@@ -724,9 +767,11 @@ AC_CONFIG_FILES([Makefile
|
||||||
|
docs/Makefile
|
||||||
|
docs/common.dox
|
||||||
|
docs/html.dox
|
||||||
|
- docs/man.dox])
|
||||||
|
+ docs/man.dox
|
||||||
|
+ lib/qblog_script.la:lib/qblog_script.la.in])
|
||||||
|
|
||||||
|
-AC_CONFIG_LINKS([tests/functional/GNUmakefile:tests/functional/GNUmakefile])
|
||||||
|
+AC_CONFIG_LINKS([lib/qblog_script_noop.ld:lib/qblog_script_noop.ld
|
||||||
|
+ tests/functional/GNUmakefile:tests/functional/GNUmakefile])
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
|
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
||||||
|
index 0bebeb5..cc7417c 100644
|
||||||
|
--- a/lib/Makefile.am
|
||||||
|
+++ b/lib/Makefile.am
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
+CLEANFILES = qblog_script.ld
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
|
noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \
|
||||||
|
@@ -39,9 +40,48 @@ source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
|
||||||
|
log_syslog.c log_dcs.c log_format.c \
|
||||||
|
map.c skiplist.c hashtable.c trie.c
|
||||||
|
|
||||||
|
+# Following two files related to linkage using classic ld from binutils 2.29+
|
||||||
|
+# with which we cannot afford to lose public access to section boundary symbols
|
||||||
|
+# (as the mentioned version started to scope them privately by default, see
|
||||||
|
+# the comment within the first of the files, ultimately leading to broken
|
||||||
|
+# logging functionality of libqb) deserve a bit of explanation:
|
||||||
|
+# * qblog_script.ld
|
||||||
|
+# - linker script that instructs the output section that those symbols should
|
||||||
|
+# be visible, i.e. supports the same behaviour regardless of ld version
|
||||||
|
+# - serves two purposes:
|
||||||
|
+# . local: libqb itself and its "private" (cf. examples) users need those
|
||||||
|
+# symbols visible, which is achieved with a help of the other file
|
||||||
|
+# . system-wide: whenever the non-private library users link against libqb
|
||||||
|
+# (it's development files), this linker script with
|
||||||
|
+# prepended INPUT command so as to refer to the actual
|
||||||
|
+# libqb library (it's numbered alias that is eventually
|
||||||
|
+# resolved to proper shared library) is masked as libqb.so,
|
||||||
|
+# this arrangement achieves the libqb's user will have
|
||||||
|
+# the discussed symbols visible alike
|
||||||
|
+# * qblog_script.la
|
||||||
|
+# - as mentioned earlier, this indirectly hooks into libtool machinery, with
|
||||||
|
+# the only true intention of injecting "-Wl,<path to qblog_script.ld>"
|
||||||
|
+# into "inherited_linker_flags" libtool archive variable, from where it's
|
||||||
|
+# subsequently spread into the build process of all the internal library
|
||||||
|
+# users, assuming they have their dep arranged as "user_LIBADD=libqb.la"
|
||||||
|
+# (this also alleviates the burden on getting things right if, e.g., any
|
||||||
|
+# libqb user consumes it directly like this from its own sub-checkout tree)
|
||||||
|
+# - it indirectly, once libtool prechew the original link command
|
||||||
|
+# originally referring to this file, it turns such reference into the
|
||||||
|
+# "real" library reference (here combining libdir and old_library
|
||||||
|
+# variables within the file), also ensures libqb itself will visibly
|
||||||
|
+# expose the discussed symbols, because such references point again to
|
||||||
|
+# the (not enriched) linker script file that will get interpreted just
|
||||||
|
+# like that during the last build step of the library
|
||||||
|
+EXTRA_libqb_la_DEPENDENCIES = qblog_script.ld qblog_script.la
|
||||||
|
+EXTRA_DIST = qblog_script.ld.in qblog_script.la.in qblog_script_noop.ld
|
||||||
|
+
|
||||||
|
libqb_la_SOURCES = $(source_to_lint) unix.c
|
||||||
|
libqb_la_CFLAGS = $(PTHREAD_CFLAGS)
|
||||||
|
libqb_la_LIBADD = $(LTLIBOBJS) $(dlopen_LIBS) $(PTHREAD_LIBS) $(socket_LIBS)
|
||||||
|
+if NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND
|
||||||
|
+libqb_la_LIBADD += qblog_script.la
|
||||||
|
+endif
|
||||||
|
|
||||||
|
AM_LDFLAGS = $(LDFLAGS_COPY:-Bsymbolic-functions=)
|
||||||
|
|
||||||
|
@@ -60,6 +100,33 @@ else
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+qblog_script.ld: %.ld: %.ld.in
|
||||||
|
+ $(AM_V_GEN)$(CPP) -xc -I$(top_srcdir)/include -C -P $< \
|
||||||
|
+ | sed -n "/$$(sed -n '/^[^#]/{s/[*\/]/\\\0/g;p;q}' $<)/{:r;p;n;br}" \
|
||||||
|
+ > $@
|
||||||
|
+
|
||||||
|
+# find the libqb.so symlink's target, if so, try to find out, iteratively,
|
||||||
|
+# its gradually shorter forms that likewise symlinks the same target as the
|
||||||
|
+# original libqb.so path, point to that file from the linker script using
|
||||||
|
+# qblog_script.ld as a template, storing result in place of original libqb.so
|
||||||
|
+# (e.g., libqb.so := "INPUT(libqb.so.0) " [...] "SECTIONS { " [...] "}")
|
||||||
|
+# NOTE: readlink nor realpath are POSIX; not chained links ready
|
||||||
|
+# NOTE: conservative check, i.e., not per NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND
|
||||||
|
+if HAVE_GCC_ATTRIBUTE_SECTION
|
||||||
|
+install-exec-hook: qblog_script.ld
|
||||||
|
+ target=$$(ls -l "$(DESTDIR)$(libdir)/libqb.so" || :); \
|
||||||
|
+ target=$${target#* -> }; t1_bn=$$(basename "$${target}" || :); \
|
||||||
|
+ while test -n "$${t1_bn}"; do t2_bn=$${t1_bn%.*[0-9]*}; \
|
||||||
|
+ test "$${t2_bn}" != libqb.so || break; \
|
||||||
|
+ test -L "$${t2_bn}" || { t1_bn=$${t2_bn}; continue; }; \
|
||||||
|
+ t2_target=$$(ls -l "$${t2_bn}" || break); t2_target=$${t2_target#* -> }; \
|
||||||
|
+ test "$${t2_target}" = "$${target}" || break; \
|
||||||
|
+ t1_bn=$${t2_bn}; done; test -n "$${t1_bn}" || \
|
||||||
|
+ { echo "only applicable to SO symlink scheme"; exit 1; }; \
|
||||||
|
+ echo "INPUT($${t1_bn})" > "$(DESTDIR)$(libdir)/libqb.so-t"
|
||||||
|
+ cat $< >> "$(DESTDIR)$(libdir)/libqb.so-t"
|
||||||
|
+ mv -f "$(DESTDIR)$(libdir)/libqb.so-t" "$(DESTDIR)$(libdir)/libqb.so"
|
||||||
|
+endif
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libqb.pc
|
||||||
|
diff --git a/lib/log.c b/lib/log.c
|
||||||
|
index bfd218f..4ed432f 100644
|
||||||
|
--- a/lib/log.c
|
||||||
|
+++ b/lib/log.c
|
||||||
|
@@ -40,6 +40,13 @@
|
||||||
|
#include "util_int.h"
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
|
+#if defined(QB_NEED_ATTRIBUTE_SECTION_WORKAROUND) && !defined(S_SPLINT_S)
|
||||||
|
+/* following only needed to force these symbols be global
|
||||||
|
+ with ld 2.29: https://bugzilla.redhat.com/1477354 */
|
||||||
|
+struct qb_log_callsite __attribute__((weak)) QB_ATTR_SECTION_START[] = { 0 };
|
||||||
|
+struct qb_log_callsite __attribute__((weak)) QB_ATTR_SECTION_STOP[] = { 0 };
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static struct qb_log_target conf[QB_LOG_TARGET_MAX];
|
||||||
|
static uint32_t conf_active_max = 0;
|
||||||
|
static int32_t in_logger = QB_FALSE;
|
||||||
|
diff --git a/lib/qblog_script.la.in b/lib/qblog_script.la.in
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..f262df8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/lib/qblog_script.la.in
|
||||||
|
@@ -0,0 +1,15 @@
|
||||||
|
+# Generated by libtool
|
||||||
|
+# NOTE: above line is just to pass func_ltwrapper_script_p sanity check of
|
||||||
|
+# libtool script, as we are basically sort of abusing it so as to inject
|
||||||
|
+# our custom linker script to "private" (cf. examples) users of libqb.la
|
||||||
|
+
|
||||||
|
+# shall rather carry a location of old_library (possibly libdir or something
|
||||||
|
+# else, but installed=no needed to suppress 'library moved' warning then) as
|
||||||
|
+# it's together (with libtool implied prefix otherwise) used for linking libqb
|
||||||
|
+libdir=@abs_builddir@
|
||||||
|
+
|
||||||
|
+# avoids issues with library_names (spurious rpath emitting, relink-on-install)
|
||||||
|
+old_library=qblog_script_noop.ld
|
||||||
|
+
|
||||||
|
+# subject of our injection into libqb.la impacting build time for private users
|
||||||
|
+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
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/lib/qblog_script.ld.in
|
||||||
|
@@ -0,0 +1,17 @@
|
||||||
|
+#include <qb/qblog.h>
|
||||||
|
+/* GNU ld script
|
||||||
|
+ This atypical arrangement enforces global visibility of boundary symbols
|
||||||
|
+ (QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP) for the custom section
|
||||||
|
+ 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 */
|
||||||
|
+SECTIONS {
|
||||||
|
+#ifdef QB_HAVE_ATTRIBUTE_SECTION
|
||||||
|
+ QB_ATTR_SECTION : {
|
||||||
|
+ QB_ATTR_SECTION_START = .;
|
||||||
|
+ *(QB_ATTR_SECTION);
|
||||||
|
+ QB_ATTR_SECTION_STOP = .;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
diff --git a/lib/qblog_script_noop.ld b/lib/qblog_script_noop.ld
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..f037fca
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/lib/qblog_script_noop.ld
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+/* this is an empty linker script having a role of a NO-OP link object */
|
||||||
|
--
|
||||||
|
2.14.2
|
||||||
|
|
152
06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch
Normal file
152
06-Low-fix-internal-object-symbol-s-leak-expose-run-tim.patch
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
From 1854db8ec1e3b246eff303b716495bafd90ded49 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
|
||||||
|
lib version
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The object in question has never been published through the header file,
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
|
||||||
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
|
---
|
||||||
|
include/qb/qbconfig.h.in | 5 ++++-
|
||||||
|
include/qb/qblog.h | 10 ++++++----
|
||||||
|
include/qb/qbutil.h | 11 +++++++++++
|
||||||
|
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(-)
|
||||||
|
|
||||||
|
diff --git a/include/qb/qbconfig.h.in b/include/qb/qbconfig.h.in
|
||||||
|
index c1852e1..789fff3 100644
|
||||||
|
--- a/include/qb/qbconfig.h.in
|
||||||
|
+++ b/include/qb/qbconfig.h.in
|
||||||
|
@@ -30,7 +30,10 @@
|
||||||
|
/* Enabling code using __attribute__((section)) */
|
||||||
|
#undef QB_HAVE_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 run-time
|
||||||
|
+ querying the lower-cased symbolic constants directly from libqb
|
||||||
|
+ (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
|
||||||
|
--- 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_
|
||||||
|
#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) \
|
||||||
|
+ /* libqb sanity (locating libqb by it's relatively unique \
|
||||||
|
+ non-functional symbol (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/include/qb/qbutil.h b/include/qb/qbutil.h
|
||||||
|
index bfce349..a03bdf8 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;
|
||||||
|
+/** Complete library versioning info as a string */
|
||||||
|
+extern const char *const qb_ver_str;
|
||||||
|
+
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
diff --git a/lib/log_format.c b/lib/log_format.c
|
||||||
|
index 712f447..e7e1f40 100644
|
||||||
|
--- a/lib/log_format.c
|
||||||
|
+++ b/lib/log_format.c
|
||||||
|
@@ -49,7 +49,7 @@ static struct syslog_names prioritynames[] = {
|
||||||
|
{NULL, -1}
|
||||||
|
};
|
||||||
|
|
||||||
|
-struct syslog_names facilitynames[] = {
|
||||||
|
+static struct syslog_names facilitynames[] = {
|
||||||
|
{"auth", LOG_AUTH},
|
||||||
|
#if defined(LOG_AUTHPRIV)
|
||||||
|
{"authpriv", LOG_AUTHPRIV},
|
||||||
|
diff --git a/lib/util.c b/lib/util.c
|
||||||
|
index 6181a25..4693e58 100644
|
||||||
|
--- a/lib/util.c
|
||||||
|
+++ b/lib/util.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include "util_int.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
+#include <qb/qbconfig.h>
|
||||||
|
#include <qb/qbdefs.h>
|
||||||
|
#include <qb/qbutil.h>
|
||||||
|
|
||||||
|
@@ -372,3 +373,9 @@ 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 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
|
||||||
|
--- a/tests/functional/log_client.c
|
||||||
|
+++ b/tests/functional/log_client.c
|
||||||
|
@@ -53,6 +53,10 @@ main(int32_t argc, char *argv[])
|
||||||
|
qb_log_tags_stringify_fn_set(my_tags_stringify);
|
||||||
|
qb_log_format_set(QB_LOG_STDERR, "[%5g|%p] %f:%l:%b");
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
+ printf("\n==%s==\n\n", qb_ver_str);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#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
|
||||||
|
@@ -1,2 +1,2 @@
|
||||||
|
-[MAIN |debug] ../log_client.c:63:hello
|
||||||
|
+[MAIN |debug] ../log_client.c:67:hello
|
||||||
|
[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2)
|
||||||
|
--
|
||||||
|
2.14.2
|
||||||
|
|
17
libqb.spec
17
libqb.spec
@ -2,15 +2,19 @@
|
|||||||
|
|
||||||
Name: libqb
|
Name: libqb
|
||||||
Version: 1.0.2
|
Version: 1.0.2
|
||||||
Release: 7%{?dist}
|
Release: 8%{?dist}
|
||||||
Summary: An IPC library for high performance servers
|
Summary: An IPC library for high performance servers
|
||||||
|
|
||||||
Group: System Environment/Libraries
|
Group: System Environment/Libraries
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://github.com/ClusterLabs/libqb
|
URL: https://github.com/ClusterLabs/libqb
|
||||||
Source0: https://github.com/ClusterLabs/libqb/releases/download/v%{version}/%{name}-%{version}.tar.xz
|
Source0: https://github.com/ClusterLabs/libqb/releases/download/v%{version}/%{name}-%{version}.tar.xz
|
||||||
Patch0: 0001-build-configure-run-attribute-section-test-through-r.patch
|
Patch0: 01-Med-qblog.h-better-explanation-behaviour-of-QB_LOG_I.patch
|
||||||
Patch1: 0002-WIP-5-Experimental-fix-for-libqb-logging-not-working.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
|
||||||
|
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
|
||||||
|
|
||||||
BuildRequires: autoconf automake libtool doxygen procps check-devel
|
BuildRequires: autoconf automake libtool doxygen procps check-devel
|
||||||
# https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B#BuildRequires_and_Requires
|
# https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B#BuildRequires_and_Requires
|
||||||
@ -36,7 +40,8 @@ make %{?_smp_mflags} V=1
|
|||||||
|
|
||||||
%if 0%{?with_check}
|
%if 0%{?with_check}
|
||||||
%check
|
%check
|
||||||
make -j1 check
|
make V=1 check \
|
||||||
|
&& make -C tests/functional/log_internal V=1 check
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%install
|
%install
|
||||||
@ -72,6 +77,10 @@ developing applications that use %{name}.
|
|||||||
%{_mandir}/man3/qb*3*
|
%{_mandir}/man3/qb*3*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Oct 06 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-8
|
||||||
|
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
||||||
|
- New test included in check phase (as per upsteam)
|
||||||
|
|
||||||
* Mon Sep 04 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-7
|
* Mon Sep 04 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-7
|
||||||
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user