1.0.2-12 - Evolution of the previous (rhbz#1478089)
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
This commit is contained in:
parent
8bf1fa94fc
commit
e3be0a5f65
@ -1,4 +1,4 @@
|
|||||||
From 3f9ccfc3b291196657edb2e920327f2d26804d6a Mon Sep 17 00:00:00 2001
|
From 47f007a9bbdbfcdb1df6736dddde64f9c6381b58 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: Fri, 6 Oct 2017 17:17:26 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 1/6] Med: qblog.h: better explanation + behaviour of
|
Subject: [PATCH 1/6] Med: qblog.h: better explanation + behaviour of
|
||||||
@ -26,7 +26,7 @@ requires.
|
|||||||
|
|
||||||
- after:
|
- after:
|
||||||
pacemakerd: utils.c:69: common:
|
pacemakerd: utils.c:69: common:
|
||||||
Assertion `"non-empty callsite section" && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP' failed.
|
Assertion `"non-empty implicit callsite section" && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP' failed.
|
||||||
|
|
||||||
Restructuring of the assertion inspired by the suggestion of Ferenc
|
Restructuring of the assertion inspired by the suggestion of Ferenc
|
||||||
Wágner (for the subsequent commit, actually).
|
Wágner (for the subsequent commit, actually).
|
||||||
@ -42,11 +42,11 @@ libqb-target cross-combination matrix and the findings).
|
|||||||
|
|
||||||
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
---
|
---
|
||||||
include/qb/qblog.h | 43 ++++++++++++++++++++++++++++++++++++++-----
|
include/qb/qblog.h | 45 ++++++++++++++++++++++++++++++++++++++++-----
|
||||||
1 file changed, 38 insertions(+), 5 deletions(-)
|
1 file changed, 40 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
||||||
index 3cb4eef..7b6db8b 100644
|
index 3cb4eef..4954932 100644
|
||||||
--- a/include/qb/qblog.h
|
--- a/include/qb/qblog.h
|
||||||
+++ b/include/qb/qblog.h
|
+++ b/include/qb/qblog.h
|
||||||
@@ -42,6 +42,10 @@ extern "C" {
|
@@ -42,6 +42,10 @@ extern "C" {
|
||||||
@ -78,7 +78,7 @@ index 3cb4eef..7b6db8b 100644
|
|||||||
* @par Configuring log targets.
|
* @par Configuring log targets.
|
||||||
* A log target can be syslog, stderr, the blackbox, stdout, or a text file.
|
* A log target can be syslog, stderr, the blackbox, stdout, or a text file.
|
||||||
* By default only syslog is enabled.
|
* By default only syslog is enabled.
|
||||||
@@ -268,11 +283,29 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs);
|
@@ -268,11 +283,31 @@ 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_START[];
|
||||||
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
||||||
|
|
||||||
@ -87,32 +87,34 @@ index 3cb4eef..7b6db8b 100644
|
|||||||
- void name(void); \
|
- void name(void); \
|
||||||
- void name(void) \
|
- void name(void) \
|
||||||
- { if (QB_ATTR_SECTION_START == QB_ATTR_SECTION_STOP) assert(0); } \
|
- { if (QB_ATTR_SECTION_START == QB_ATTR_SECTION_STOP) assert(0); } \
|
||||||
+/* optional on-demand self-check of (1) toolchain sanity (prerequisite for
|
+/* optional on-demand self-check of 1/ toolchain sanity (prerequisite for
|
||||||
+ the logging subsystem to work properly) and (2) non-void active use of
|
+ the logging subsystem to work properly) and 2/ non-void active use of
|
||||||
+ logging (satisfied with a justifying existence of a logging callsite as
|
+ logging (satisfied with a justifying existence of a logging callsite as
|
||||||
+ defined with a @c qb_logt invocation) at the target (but see below), which
|
+ defined with a @c qb_logt invocation) at the target (but see below), which
|
||||||
+ is presumably assured by it's author as of relying on this very macro
|
+ is supposedly assured by it's author(!) as of relying on this very macro
|
||||||
+ [technically, the symbols that happen to be resolved under the respective
|
+ [technically, the symbols that happen to be resolved under the respective
|
||||||
+ identifiers do not necessarily come from the same compilation unit level
|
+ identifiers do not necessarily originate in the same compilation unit as
|
||||||
+ as when it's not the end program (or by induction, a library higher in
|
+ when it's not the end executable (or by induction, a library positioned
|
||||||
+ the symbol resolution fall-through) but a shared library, the former takes
|
+ earlier in the symbol lookup order) but a shared library, the former takes
|
||||||
+ a precedence unless it lacks use of logging on its own making its very
|
+ a precedence unless that site comes short of exercising the logging,
|
||||||
+ section empty and hence without such boundary symbols provided at the
|
+ making its callsite section empty and, in turn, without such boundary
|
||||||
+ respective level and thus deferring to lower priority symbol resolution
|
+ symbols, hence making the resolution continue further in the lookup order
|
||||||
+ stop -- despite this fuzzily targeted attestation, the check remains
|
+ -- despite fuzzily targeted attestation, the check remains reasonable];
|
||||||
+ reasonable and should not harm anything];
|
|
||||||
+ only effective when link-time ("run-time amortizing") callsite collection
|
+ only effective when link-time ("run-time amortizing") callsite collection
|
||||||
+ is; as a side effect, it can ensure the boundary-denoting symbols for the
|
+ is; as a side effect, it can ensure the boundary-denoting symbols for the
|
||||||
+ target collection area are kept alive with some otherwise unkind linkers;
|
+ target collection area are kept alive with some otherwise unkind linkers;
|
||||||
+ may be extended in future for more in-depth self-validation */
|
+ may be extended in future for more in-depth self-validation */
|
||||||
+#define QB_LOG_INIT_DATA(name) \
|
+#define QB_LOG_INIT_DATA(name) \
|
||||||
+ void name(void); \
|
+ void name(void); \
|
||||||
+ void name(void) \
|
+ void name(void) { \
|
||||||
+ { assert("non-empty callsite section" \
|
+ /* our own (target's) sanity, or possibly that of higher priority \
|
||||||
|
+ symbol resolution site (unless target equals end executable) \
|
||||||
|
+ or even the lower one if no such predecessor defines these */ \
|
||||||
|
+ assert("non-empty implicit callsite section" \
|
||||||
+ && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \
|
+ && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \
|
||||||
void __attribute__ ((constructor)) name(void);
|
void __attribute__ ((constructor)) name(void);
|
||||||
#else
|
#else
|
||||||
#define QB_LOG_INIT_DATA(name)
|
#define QB_LOG_INIT_DATA(name)
|
||||||
--
|
--
|
||||||
2.14.2
|
2.14.3
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
From 796ce1191ffd99f0bceba174355f695af8dc368a Mon Sep 17 00:00:00 2001
|
From 287ae050e5330202eca59adbb7e87e9d26d69e08 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: Fri, 6 Oct 2017 17:17:26 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 2/6] build: configure: run attribute section test through
|
Subject: [PATCH 2/6] build: configure: run attribute section test through
|
||||||
@ -52,5 +52,5 @@ index 22630ba..478194c 100644
|
|||||||
gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
gcc_has_attribute_section=${ac_cv_link_attribute_section}
|
||||||
fi
|
fi
|
||||||
--
|
--
|
||||||
2.14.2
|
2.14.3
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
From 3df0138ba57e274b8c8065739870b1529b95e087 Mon Sep 17 00:00:00 2001
|
From afb1e96c8b45c520f1e66416167ad943326ae4fe 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: Fri, 6 Oct 2017 17:17:26 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 3/6] tests: new sort of tests dubbed "functional", cover
|
Subject: [PATCH 3/6] tests: new sort of tests dubbed "functional", cover
|
||||||
@ -47,12 +47,18 @@ libqb.spec for RPM packaging, whereas the regular one (b.) serves as
|
|||||||
a building block for new log_test_mock.sh runner of said test matrix
|
a building block for new log_test_mock.sh runner of said test matrix
|
||||||
-- it iterates through all the possible permutations of linker-imposed
|
-- it iterates through all the possible permutations of linker-imposed
|
||||||
implicit visibility of mentioned symbols between various affected
|
implicit visibility of mentioned symbols between various affected
|
||||||
linkage sides (see 1. - 3. above) so as to demonstrate a/ the impact
|
link participants all making use of logging (see 1. - 3. above) so as
|
||||||
of the problem (see table below), and subsequently b/ that the fix is
|
to demonstrate A/ the impact of the problem (see table below), and
|
||||||
effective in all these situations (updated table will be provided as
|
subsequently B/ that the fix is effective in all these situations
|
||||||
well) once it lands.
|
(updated table will be provided as well) once it lands. This script
|
||||||
|
also allows convoluting the test matrix further, notably with on-demand
|
||||||
|
defusing the self-checks based on QB_LOG_INIT_DATA macro, which is
|
||||||
|
of significance as demonstrated below (and will become even more
|
||||||
|
important with upcoming patches in this series).
|
||||||
|
|
||||||
Current state for this matrix, in which participants 1. - 3. map like:
|
* * *
|
||||||
|
|
||||||
|
Current state for such matrix, in which participants 1. - 3. map like:
|
||||||
1. ~ libqb(Y)
|
1. ~ libqb(Y)
|
||||||
2. ~ "direct"
|
2. ~ "direct"
|
||||||
3. ~ libX(Y) [a.k.a. interlib]
|
3. ~ libX(Y) [a.k.a. interlib]
|
||||||
@ -82,16 +88,18 @@ can observe a somewhat simpler story (DEP ~ "depends"):
|
|||||||
# x = b # DEP[*I] | DEP[*I] : DEP[*K] # BAD[*1] | BAD[*1] : BAD[*L] #
|
# x = b # DEP[*I] | DEP[*I] : DEP[*K] # BAD[*1] | BAD[*1] : BAD[*L] #
|
||||||
+=========+=========+=========+=========+=========+=========+=========+
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
[*1] client logging not working
|
[*1] client logging not working
|
||||||
[*2] interlib logging not working
|
[*2] interlib logging not working
|
||||||
[*3] both client and 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,
|
[*A] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
|
||||||
which fails on 'non-empty callsite section' assertion
|
which fails on 'non-empty implicit callsite section' assertion
|
||||||
[*B] boils down to [*1], unless QB_LOG_INIT_DATA used on interlib side,
|
[*B] boils down to [*1], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
which fails on 'non-empty callsite section' assertion
|
which fails on 'non-empty implicit callsite section' assertion
|
||||||
[*C] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
[*C] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
which fails on 'non-empty callsite section' assertion
|
which fails on 'non-empty implicit callsite section' assertion
|
||||||
[*D] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
[*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
|
which makes it boil down just to [*1] (hypothesis: mere internal
|
||||||
self-reference to the section's boundary symbols makes them
|
self-reference to the section's boundary symbols makes them
|
||||||
@ -113,6 +121,8 @@ can observe a somewhat simpler story (DEP ~ "depends"):
|
|||||||
(sufficient?), which makes it, likely through self-reference
|
(sufficient?), which makes it, likely through self-reference
|
||||||
keepalive (see below) boil down just to [*1]
|
keepalive (see below) boil down just to [*1]
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
Note: as observed with [*D] case (libqb linked with ld.bfd < 2.29
|
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
|
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
|
availability of a working logging doesn't depend solely on the linkers
|
||||||
@ -154,7 +164,7 @@ Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
|||||||
tests/functional/log_test_interlib_client.err | 4 +
|
tests/functional/log_test_interlib_client.err | 4 +
|
||||||
tests/functional/log_test_interlib_client.sh | 33 +++
|
tests/functional/log_test_interlib_client.sh | 33 +++
|
||||||
tests/functional/log_test_mock.sh | 310 ++++++++++++++++++++++++++
|
tests/functional/log_test_mock.sh | 310 ++++++++++++++++++++++++++
|
||||||
18 files changed, 767 insertions(+), 4 deletions(-)
|
16 files changed, 754 insertions(+), 2 deletions(-)
|
||||||
create mode 100644 tests/functional/GNUmakefile
|
create mode 100644 tests/functional/GNUmakefile
|
||||||
create mode 100644 tests/functional/Makefile.am
|
create mode 100644 tests/functional/Makefile.am
|
||||||
create mode 100644 tests/functional/log.am
|
create mode 100644 tests/functional/log.am
|
||||||
@ -1051,5 +1061,5 @@ index 0000000..145b9f4
|
|||||||
+ "- results stored in '_results/<timestamp>_<input_name>[_<tag>]'" \
|
+ "- results stored in '_results/<timestamp>_<input_name>[_<tag>]'" \
|
||||||
+ || do_proceed "$@"
|
+ || do_proceed "$@"
|
||||||
--
|
--
|
||||||
2.14.2
|
2.14.3
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
From 4f0fceaaf38a04e9f1c067a7b581265b9ceb81de Mon Sep 17 00:00:00 2001
|
From ca5c4425393c462670861a023608d30977a17de7 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: Fri, 6 Oct 2017 17:17:26 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 4/6] Med: add extra run-time (client, libqb) checks that
|
Subject: [PATCH 4/6] Med: add extra run-time (client, libqb) checks that
|
||||||
@ -7,15 +7,24 @@ 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
|
||||||
|
|
||||||
The table at the bottom concludes how the test matrix overview
|
Now that the previous commit provides a foundation for what exactly can
|
||||||
|
go wrong with ld.bfd = 2.29+ linker, let's start reconciling that with
|
||||||
|
some reasonable assurance that logging is not silently severed, because
|
||||||
|
realizing the logs are missing is otherwise bound to happen when the
|
||||||
|
logs are suddently pretty crucial analytical resource :-)
|
||||||
|
We'll proceed in two steps as detailed.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
As a first step, the table below concludes how the test matrix overview
|
||||||
introduced with a message for the preceding commit (also introducing
|
introduced with a message for the preceding commit (also introducing
|
||||||
log_test_mock.sh runner which got reused here) looks as of this
|
log_test_mock.sh runner which got reused here) looks as of this
|
||||||
refreshed sanity check, once QB_LOG_INIT_DATA macro at hand gets
|
refreshed sanity check, once QB_LOG_INIT_DATA macro at hand gets applied
|
||||||
applied (meaning "for non-libqb logging participants" so as not
|
(meaning "for non-libqb logging participants" so as not complicate the
|
||||||
complicate the matrix further). That macro is nothing triggered
|
matrix further). That macro is nothing triggered directly, it will just
|
||||||
directly, it will just plant a constructor-like function (to be
|
plant a constructor-like function (to be invoked automatically early in
|
||||||
invoked automatically early in the execution) that will run through
|
the execution) that will run through the checks (one original and couple
|
||||||
the checks (one original and couple of new ones as of this changeset).
|
of new ones as of this changeset).
|
||||||
|
|
||||||
Note that for libqb users, this implies a new link dependency on libdl,
|
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
|
because they may opt-in for refreshed QB_LOG_INIT_DATA sanity check that
|
||||||
@ -48,28 +57,68 @@ the table stated in the preceding commit):
|
|||||||
# x = b # BAD[*A] | BAD[*B] : BAD[*C] #<BAD[*E]>|<BAD[*F]>:<BAD[*G]>#
|
# x = b # BAD[*A] | BAD[*B] : BAD[*C] #<BAD[*E]>|<BAD[*F]>:<BAD[*G]>#
|
||||||
+=========+=========+=========+=========+=========+=========+=========+
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
|
|
||||||
whereas if we swap 2.29 for 2.29.1, i.e., X(b) .. ld.bfd = 2.29.1, we
|
Woefully, nothing changes if we swap binutils 2.29 for 2.29.1, i.e.,
|
||||||
can observe a somewhat simpler story (DEP ~ "depends"):
|
X(b) .. ld.bfd = 2.29.1, compared to previous state, i.e., the second
|
||||||
|
table from the previous commit is still applicable for that situation.
|
||||||
|
The added sanity checks are useful nonetheless, consider for example,
|
||||||
|
that attribute-section-less libqb is what gets run-time linked to an
|
||||||
|
attribute-section-full target. The most precise check we could use
|
||||||
|
-- a custom logger function applied in a self-test scheme -- is not
|
||||||
|
available at the point the macro-defined function gets invoked, simply
|
||||||
|
because qb_log_init hasn't been invoked by the time that constructor
|
||||||
|
gets triggered. However, what we can do is to add a non-trapping
|
||||||
|
libqb-residing reverse-testing of the client space that (and once it)
|
||||||
|
voluntarily initiates qb_log_init (delivering abruption all of a sudden
|
||||||
|
at some unanticipated, as opposed to a well-timed like with
|
||||||
|
constructors, execution point, seems pretty bad idea + libqb as
|
||||||
|
a library is a mere helper, not an undertaker :) -- this check then
|
||||||
|
only announces, via syslog (the only pre-enabled logging target),
|
||||||
|
the target's logging may be severed.
|
||||||
|
|
||||||
Woefully, nothing changes if we swap binutils 2.29.1 for 2.29, i.e.,
|
* * *
|
||||||
X(b) .. ld.bfd = 2.29.1. The second table from the previous commit
|
|
||||||
hence remains the same. The added sanity checks are useful nonetheless,
|
|
||||||
consider for example, that attribute-section-less libqb is what gets
|
|
||||||
run-time linked to an attribute-section-full target. The most precise
|
|
||||||
check we could use -- a custom logger function applied in a self-test
|
|
||||||
scheme -- is not available at the point the macro-defined function gets
|
|
||||||
invoked, simply because qb_log_init hasn't been invoked by the time
|
|
||||||
that constructor gets triggered. However, what we can do is to add
|
|
||||||
a non-trapping libqb-residing reverse-testing of the client space that
|
|
||||||
invokes qb_log_init (delivering abruption all of a sudden at some
|
|
||||||
unanticipated, as opposed to a well-timed like with constructors,
|
|
||||||
execution point, seems pretty bad idea + libqb as a library is a mere
|
|
||||||
helper, not an undertaker :) -- this check only announces, via syslog
|
|
||||||
(the only pre-enabled logging target), the target logging won't work.
|
|
||||||
|
|
||||||
After incorporating such a change (and extending log_test_mock.sh so as
|
Hence, as a promised second step, after incorporating the syslog
|
||||||
to capture syslog stream within the container), nothing changes with the
|
change (and extending log_test_mock.sh so as to capture syslog
|
||||||
table above, but desirably changes with "X(b) .. ld.bfd = 2.29.1" one:
|
stream within the container), not much changes with the table above,
|
||||||
|
i.e., X(b) .. ld.bfd = 2.29:
|
||||||
|
[*A] in addition, unless QB_LOG_INIT_DATA used on client side,
|
||||||
|
syslog carries this error:
|
||||||
|
"(LOG@QB) target chain supplied section not observed by libqb,
|
||||||
|
target's and/or libqb's linkage at fault and logging of the target
|
||||||
|
will not work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
|
logged by libqb proper
|
||||||
|
[*C] in addition, unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
|
syslog carries this error:
|
||||||
|
"(LOG@QB) target chain supplied section not observed by libqb,
|
||||||
|
target's and/or libqb's linkage at fault and logging of the target
|
||||||
|
will not work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
|
logged by libqb proper
|
||||||
|
[*E] in addition, unless QB_LOG_INIT_DATA used on client side,
|
||||||
|
syslog carries this warning:
|
||||||
|
"(LOG@QB) target chain supplied section empty, target's and/or
|
||||||
|
libqb's linkage at fault and logging of the target will not
|
||||||
|
work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
|
logged by libqb proper
|
||||||
|
[*F] in addition, unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
|
syslog carries this warning:
|
||||||
|
"(LOG@QB) target chain supplied section empty, target's and/or
|
||||||
|
libqb's linkage at fault and logging of the target will not
|
||||||
|
work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
|
logged by libqb proper
|
||||||
|
[*G] in addition, unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
|
syslog carries this warning:
|
||||||
|
"(LOG@QB) target chain supplied section empty, target's and/or
|
||||||
|
libqb's linkage at fault and logging of the target will not
|
||||||
|
work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
|
logged by libqb proper
|
||||||
|
|
||||||
|
but desirably changes with "X(b) .. ld.bfd = 2.29.1" one
|
||||||
|
(DEP ~ "depends"):
|
||||||
|
|
||||||
+=========+=========+=========+=========+=========+=========+=========+
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
#client(x)# libqb(a) usage # libqb(b) usage #
|
#client(x)# libqb(a) usage # libqb(b) usage #
|
||||||
@ -80,6 +129,8 @@ table above, but desirably changes with "X(b) .. ld.bfd = 2.29.1" one:
|
|||||||
# x = b #<DEP[*N]>| DEP[*I] :<DEP[*O]>#<BAD[*M]>|<BAD[*M]>:<BAD[*L]>#
|
# x = b #<DEP[*N]>| DEP[*I] :<DEP[*O]>#<BAD[*M]>|<BAD[*M]>:<BAD[*L]>#
|
||||||
+=========+=========+=========+=========+=========+=========+=========+
|
+=========+=========+=========+=========+=========+=========+=========+
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
[*1] client logging not working
|
[*1] client logging not working
|
||||||
[*2] interlib logging not working
|
[*2] interlib logging not working
|
||||||
[*3] both client and interlib logging not working
|
[*3] both client and interlib logging not working
|
||||||
@ -101,8 +152,8 @@ table above, but desirably changes with "X(b) .. ld.bfd = 2.29.1" one:
|
|||||||
assertion
|
assertion
|
||||||
[*E] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
|
[*E] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
|
||||||
which then fails on
|
which then fails on
|
||||||
"target's callsite section self-observable, otherwise target's
|
"implicit callsite section self-observable, otherwise target's and/or
|
||||||
and/or libqb's linkage at fault and logging would not work reliably"
|
libqb's linkage at fault and logging would not work reliably"
|
||||||
assertion
|
assertion
|
||||||
[*F] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
[*F] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
which then fails on
|
which then fails on
|
||||||
@ -111,44 +162,49 @@ table above, but desirably changes with "X(b) .. ld.bfd = 2.29.1" one:
|
|||||||
assertion
|
assertion
|
||||||
[*G] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
[*G] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
which then fails on
|
which then fails on
|
||||||
"target's callsite section self-observable, otherwise target's and/or
|
"implicit callsite section self-observable, otherwise target's and/or
|
||||||
libqb's linkage at fault and logging would not work reliably"
|
libqb's linkage at fault and logging would not work reliably"
|
||||||
assertion
|
assertion
|
||||||
|
|
||||||
[*I] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
|
[*I] boils down to [*1], unless QB_LOG_INIT_DATA used on client side,
|
||||||
which makes it, likely through self-reference keepalive (see
|
which makes it, likely through self-reference keepalive (see
|
||||||
below) work OK
|
below), work OK
|
||||||
[*J] boils down to [*2], unless QB_LOG_INIT_DATA used on interlib side,
|
[*J] boils down to [*2], unless QB_LOG_INIT_DATA used on interlib side,
|
||||||
which makes it, likely through self-reference keepalive (see
|
which makes it, likely through self-reference keepalive (see
|
||||||
below) work OK
|
below), work OK
|
||||||
[*K] boils down to [*3]
|
[*K] boils down to [*3]
|
||||||
in addition, syslog carries this error:
|
in addition, syslog carries this error:
|
||||||
"target chain supplied section not observed by libqb, target's and/or
|
"(LOG@QB) target chain supplied section not observed by libqb,
|
||||||
libqb's linkage at fault and logging of the target will not work
|
target's and/or libqb's linkage at fault and logging of the target
|
||||||
reliably"
|
will not work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
logged by libqb proper
|
logged by libqb proper
|
||||||
[*L] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side
|
[*L] boils down to [*3], unless QB_LOG_INIT_DATA used on interlib side
|
||||||
(sufficient?), which makes it, likely through self-reference
|
(sufficient?), which makes it, likely through self-reference
|
||||||
keepalive (see below) boil down just to [*1];
|
keepalive (see below), boil down just to [*1];
|
||||||
in addition, syslog carries this error:
|
in addition, syslog carries this error:
|
||||||
"target chain supplied section not observed by libqb, target's and/or
|
"(LOG@QB) target chain supplied section not observed by libqb,
|
||||||
libqb's linkage at fault and logging of the target will not work
|
target's and/or libqb's linkage at fault and logging of the target
|
||||||
reliably"
|
will not work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
logged by libqb proper
|
logged by libqb proper
|
||||||
[*M] boils down to [*1];
|
[*M] boils down to [*1];
|
||||||
in addition, syslog carries this error:
|
in addition, syslog carries this error:
|
||||||
"target chain supplied section not observed by libqb, target's and/or
|
"(LOG@QB) target chain supplied section not observed by libqb,
|
||||||
libqb's linkage at fault and logging of the target will not work
|
target's and/or libqb's linkage at fault and logging of the target
|
||||||
reliably"
|
will not work reliably (unless qb_log_init function used unexpectedly
|
||||||
|
in no-logging context)"
|
||||||
logged by libqb proper
|
logged by libqb proper
|
||||||
[*N] boils down to [*M], unless QB_LOG_INIT_DATA used on client side,
|
[*N] boils down to [*M], unless QB_LOG_INIT_DATA used on client side,
|
||||||
which makes it, likely through self-reference keepalive (see
|
which makes it, likely through self-reference keepalive (see
|
||||||
below) work OK
|
below), work OK
|
||||||
[*O] boils down to [*K], unless QB_LOG_INIT_DATA used on both client
|
[*O] boils down to [*K], unless QB_LOG_INIT_DATA used on both client
|
||||||
and interlib side, which makes it, likely through self-reference
|
and interlib side, which makes it, likely through self-reference
|
||||||
keepalive (see below) work OK (it's expected that this a mere
|
keepalive (see below), work OK (it's expected that this a mere
|
||||||
composite of situations [*I] and [*J] with consequences as stated)
|
composite of situations [*I] and [*J] with consequences as stated)
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
Note: the only problematic (i.e. not captured automatically by the
|
Note: the only problematic (i.e. not captured automatically by the
|
||||||
QB_LOG_INIT_DATA macro presumably utilized at every non-libqb logging
|
QB_LOG_INIT_DATA macro presumably utilized at every non-libqb logging
|
||||||
system participant in the form of a discrete compilation unit)
|
system participant in the form of a discrete compilation unit)
|
||||||
@ -158,27 +214,31 @@ course, be solvable as well, but presumably not in an easy way, and
|
|||||||
that use case should not be as frequent.
|
that use case should not be as frequent.
|
||||||
|
|
||||||
Takeway: whenever your target (library or client program) actively
|
Takeway: whenever your target (library or client program) actively
|
||||||
utilizes logging (meaning it emits at least a single log message),
|
utilizes logging (meaning it emits at least a single log message,
|
||||||
YOU ARE strongly ENCOURAGED TO USE QB_LOG_INIT_DATA macro function
|
otherwise there's an imminent danger of possibly even run-terminating
|
||||||
at (exactly) one of the source code files (presumably the main one)
|
false positive in the self-check mechanism!),
|
||||||
per respective target's compilation unit. It will alleviate the
|
|
||||||
hassles possibly caused by downgrading libqb to the linker-vs-libqb
|
YOU ARE strongly ENCOURAGED TO USE QB_LOG_INIT_DATA macro function
|
||||||
incompatibly compiled one or in similar circumstances arising merely
|
at (exactly) one of the source code files (presumably the main one)
|
||||||
from the linker behaviour change, which the current build system/code
|
per respective target's compilation unit.
|
||||||
quake is all about.
|
|
||||||
|
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 shake is all about.
|
||||||
|
|
||||||
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
||||||
---
|
---
|
||||||
configure.ac | 1 +
|
configure.ac | 1 +
|
||||||
include/qb/qblog.h | 95 ++++++++++++++++++++++++-------
|
include/qb/qblog.h | 110 ++++++++++++++++++++++--------
|
||||||
lib/libqb.pc.in | 3 +-
|
lib/libqb.pc.in | 3 +-
|
||||||
lib/log.c | 44 ++++++++++++++
|
lib/log.c | 49 +++++++++++++
|
||||||
tests/functional/Makefile.am | 3 +-
|
tests/functional/Makefile.am | 3 +-
|
||||||
tests/functional/log.am | 2 +-
|
tests/functional/log.am | 2 +-
|
||||||
tests/functional/log_external/Makefile.am | 8 ++-
|
tests/functional/log_external/Makefile.am | 8 ++-
|
||||||
tests/functional/log_test_mock.sh | 13 ++++-
|
tests/functional/log_test_mock.sh | 13 +++-
|
||||||
tests/functional/syslog-stdout.py | 49 ++++++++++++++++
|
tests/functional/syslog-stdout.py | 51 ++++++++++++++
|
||||||
9 files changed, 189 insertions(+), 29 deletions(-)
|
9 files changed, 204 insertions(+), 36 deletions(-)
|
||||||
create mode 100755 tests/functional/syslog-stdout.py
|
create mode 100755 tests/functional/syslog-stdout.py
|
||||||
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
diff --git a/configure.ac b/configure.ac
|
||||||
@ -194,35 +254,69 @@ index 274b49c..5769e60 100644
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
||||||
index 7b6db8b..10cd62c 100644
|
index 4954932..766cffe 100644
|
||||||
--- a/include/qb/qblog.h
|
--- a/include/qb/qblog.h
|
||||||
+++ b/include/qb/qblog.h
|
+++ b/include/qb/qblog.h
|
||||||
@@ -44,6 +44,7 @@ extern "C" {
|
@@ -1,9 +1,10 @@
|
||||||
|
/*
|
||||||
|
- * Copyright (C) 2010 Red Hat, Inc.
|
||||||
|
+ * Copyright 2017 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||||
|
+ * Jan Pokorny <jpokorny@redhat.com>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
@@ -44,6 +45,7 @@ extern "C" {
|
||||||
|
|
||||||
#ifdef QB_HAVE_ATTRIBUTE_SECTION
|
#ifdef QB_HAVE_ATTRIBUTE_SECTION
|
||||||
#include <assert.h> /* possibly needed for QB_LOG_INIT_DATA */
|
#include <assert.h> /* possibly needed for QB_LOG_INIT_DATA */
|
||||||
+#include <dlfcn.h>
|
+#include <dlfcn.h> /* dynamic linking: dlopen, dlsym, dladdr, ... */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,33 +284,83 @@ typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs);
|
@@ -70,14 +72,14 @@ extern "C" {
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* In practice, such a minimalistic approach hardly caters real use cases.
|
||||||
|
- * Following section discusses the customization. Moreover, it's quite
|
||||||
|
- * vital to instrument the target user of this logging subsystem with
|
||||||
|
- * @c QB_LOG_INIT_DATA() macro placed in the top file scope in an exactly
|
||||||
|
- * one source file (preferably the main one) to be mixed into the resulting
|
||||||
|
- * compilation unit. This is a self-defensive measure for when the
|
||||||
|
- * linker-assisted collection of callsite data silently fails, which
|
||||||
|
- * could otherwise go unnoticed, causing troubles down the road.
|
||||||
|
- *
|
||||||
|
+ * Following section discusses the customization. Moreover when employing
|
||||||
|
+ * the log module is bound to its active use (some log messages are assuredly
|
||||||
|
+ * emitted within the target compilation unit), it's quite vital to instrument
|
||||||
|
+ * the target side with @c QB_LOG_INIT_DATA() macro placed in the top file
|
||||||
|
+ * scope in exactly one source file (preferably the main one) to be mixed into
|
||||||
|
+ * the resulting compilation unit. This is a self-defensive measure for when
|
||||||
|
+ * the linker-assisted collection of callsite data silently fails, which could
|
||||||
|
+ * otherwise go unnoticed, causing troubles down the road.
|
||||||
|
*
|
||||||
|
* @par Configuring log targets.
|
||||||
|
* A log target can be syslog, stderr, the blackbox, stdout, or a text file.
|
||||||
|
@@ -283,35 +285,85 @@ 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_START[];
|
||||||
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
||||||
|
|
||||||
-/* optional on-demand self-check of (1) toolchain sanity (prerequisite for
|
-/* optional on-demand self-check of 1/ toolchain sanity (prerequisite for
|
||||||
- the logging subsystem to work properly) and (2) non-void active use of
|
- the logging subsystem to work properly) and 2/ non-void active use of
|
||||||
- logging (satisfied with a justifying existence of a logging callsite as
|
- logging (satisfied with a justifying existence of a logging callsite as
|
||||||
- defined with a @c qb_logt invocation) at the target (but see below), which
|
- defined with a @c qb_logt invocation) at the target (but see below), which
|
||||||
- is presumably assured by it's author as of relying on this very macro
|
- is supposedly assured by it's author(!) as of relying on this very macro
|
||||||
- [technically, the symbols that happen to be resolved under the respective
|
- [technically, the symbols that happen to be resolved under the respective
|
||||||
- identifiers do not necessarily come from the same compilation unit level
|
- identifiers do not necessarily originate in the same compilation unit as
|
||||||
- as when it's not the end program (or by induction, a library higher in
|
- when it's not the end executable (or by induction, a library positioned
|
||||||
- the symbol resolution fall-through) but a shared library, the former takes
|
- earlier in the symbol lookup order) but a shared library, the former takes
|
||||||
- a precedence unless it lacks use of logging on its own making its very
|
- a precedence unless that site comes short of exercising the logging,
|
||||||
- section empty and hence without such boundary symbols provided at the
|
- making its callsite section empty and, in turn, without such boundary
|
||||||
- respective level and thus deferring to lower priority symbol resolution
|
- symbols, hence making the resolution continue further in the lookup order
|
||||||
- stop -- despite this fuzzily targeted attestation, the check remains
|
- -- despite fuzzily targeted attestation, the check remains reasonable];
|
||||||
- reasonable and should not harm anything];
|
|
||||||
- only effective when link-time ("run-time amortizing") callsite collection
|
- only effective when link-time ("run-time amortizing") callsite collection
|
||||||
- is; as a side effect, it can ensure the boundary-denoting symbols for the
|
- is; as a side effect, it can ensure the boundary-denoting symbols for the
|
||||||
- target collection area are kept alive with some otherwise unkind linkers;
|
- target collection area are kept alive with some otherwise unkind linkers;
|
||||||
@ -232,9 +326,10 @@ index 7b6db8b..10cd62c 100644
|
|||||||
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
|
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
|
||||||
+ _Pragma(QB_PP_STRINGIFY(GCC warning QB_PP_STRINGIFY( \
|
+ _Pragma(QB_PP_STRINGIFY(GCC warning QB_PP_STRINGIFY( \
|
||||||
+ without "_GNU_SOURCE" defined (directly or not) \
|
+ without "_GNU_SOURCE" defined (directly or not) \
|
||||||
+ qb_log_init_data cannot check sanity of libqb proper)))
|
+ QB_LOG_INIT_DATA cannot check sanity of libqb proper)))
|
||||||
+#else
|
+#else
|
||||||
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
|
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
|
||||||
|
+ { Dl_info work_dli; \
|
||||||
+ /* libqb sanity (locating libqb by it's relatively unique \
|
+ /* libqb sanity (locating libqb by it's relatively unique \
|
||||||
+ -- and currently only such per-linkage global one -- \
|
+ -- and currently only such per-linkage global one -- \
|
||||||
+ non-functional symbol, due to possible confusion otherwise) */ \
|
+ non-functional symbol, due to possible confusion otherwise) */ \
|
||||||
@ -251,24 +346,23 @@ index 7b6db8b..10cd62c 100644
|
|||||||
+ assert("libqb's callsite section non-empty, otherwise libqb's \
|
+ assert("libqb's callsite section non-empty, otherwise libqb's \
|
||||||
+linkage at fault and logging would not work reliably" \
|
+linkage at fault and logging would not work reliably" \
|
||||||
+ && work_s1 != work_s2); \
|
+ && work_s1 != work_s2); \
|
||||||
+ dlclose(work_handle); }
|
+ dlclose(work_handle); } }
|
||||||
+#endif /* _GNU_SOURCE */
|
+#endif /* _GNU_SOURCE */
|
||||||
+
|
+
|
||||||
+/**
|
+/**
|
||||||
+ * Optional on-demand self-check of (1) toolchain sanity (prerequisite for
|
+ * Optional on-demand self-check of 1/ toolchain sanity (prerequisite for
|
||||||
+ * the logging subsystem to work properly) and (2) non-void active use of
|
+ * the logging subsystem to work properly) and 2/ non-void active use of
|
||||||
+ * logging (satisfied with a justifying existence of a logging callsite as
|
+ * logging (satisfied with a justifying existence of a logging callsite as
|
||||||
+ * defined with a @c qb_logt invocation) at the target (but see below), which
|
+ * defined with a @c qb_logt invocation) at the target (but see below), which
|
||||||
+ * is presumably assured by it's author as of relying on this very macro
|
+ * is supposedly assured by it's author(!) as of relying on this very macro
|
||||||
+ * [technically, the symbols that happen to be resolved under the respective
|
+ * [technically, the symbols that happen to be resolved under the respective
|
||||||
+ * identifiers do not necessarily come from the same compilation unit level
|
+ * identifiers do not necessarily originate in the same compilation unit as
|
||||||
+ * as when it's not the end program (or by induction, a library higher in
|
+ * when it's not the end executable (or by induction, a library positioned
|
||||||
+ * the symbol resolution fall-through) but a shared library, the former takes
|
+ * earlier in the symbol lookup order) but a shared library, the former takes
|
||||||
+ * a precedence unless it lacks use of logging on its own making its very
|
+ * a precedence unless that site comes short of exercising the logging,
|
||||||
+ * section empty and hence without such boundary symbols provided at the
|
+ * making its callsite section empty and, in turn, without such boundary
|
||||||
+ * respective level and thus deferring to lower priority symbol resolution
|
+ * symbols, hence making the resolution continue further in the lookup order
|
||||||
+ * stop -- despite this fuzzily targeted attestation, the check remains
|
+ * -- despite fuzzily targeted attestation, the check remains reasonable];
|
||||||
+ * reasonable and should not harm anything];
|
|
||||||
+ * only effective when link-time ("run-time amortizing") callsite collection
|
+ * only effective when link-time ("run-time amortizing") callsite collection
|
||||||
+ * is; as a side effect, it can ensure the boundary-denoting symbols for the
|
+ * is; as a side effect, it can ensure the boundary-denoting symbols for the
|
||||||
+ * target collection area are kept alive with some otherwise unkind linkers.
|
+ * target collection area are kept alive with some otherwise unkind linkers.
|
||||||
@ -282,22 +376,23 @@ index 7b6db8b..10cd62c 100644
|
|||||||
+ */
|
+ */
|
||||||
#define QB_LOG_INIT_DATA(name) \
|
#define QB_LOG_INIT_DATA(name) \
|
||||||
void name(void); \
|
void name(void); \
|
||||||
- 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; \
|
+ void *work_handle; struct qb_log_callsite *work_s1, *work_s2; \
|
||||||
+ Dl_info work_dli; \
|
/* our own (target's) sanity, or possibly that of higher priority \
|
||||||
+ /* our own (target's) sanity */ \
|
symbol resolution site (unless target equals end executable) \
|
||||||
|
or even the lower one if no such predecessor defines these */ \
|
||||||
|
- assert("non-empty implicit callsite section" \
|
||||||
|
- && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \
|
||||||
+ if ((work_handle = dlopen(NULL, RTLD_LOCAL|RTLD_LAZY)) != NULL) { \
|
+ if ((work_handle = dlopen(NULL, RTLD_LOCAL|RTLD_LAZY)) != NULL) { \
|
||||||
+ work_s1 = (struct qb_log_callsite *) \
|
+ work_s1 = (struct qb_log_callsite *) \
|
||||||
+ dlsym(work_handle, QB_ATTR_SECTION_START_STR); \
|
+ dlsym(work_handle, QB_ATTR_SECTION_START_STR); \
|
||||||
+ work_s2 = (struct qb_log_callsite *) \
|
+ work_s2 = (struct qb_log_callsite *) \
|
||||||
+ dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \
|
+ dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \
|
||||||
+ assert("target's callsite section self-observable, otherwise \
|
+ assert("implicit callsite section observable, otherwise \
|
||||||
+target's and/or libqb's linkage at fault and logging would not work \
|
+target's and/or libqb's linkage at fault and logging would not work \
|
||||||
+reliably" \
|
+reliably" \
|
||||||
+ && work_s1 != NULL && work_s2 != NULL); } \
|
+ && work_s1 != NULL && work_s2 != NULL); } \
|
||||||
|
+ /* better targeted attestations when available */ \
|
||||||
+ QB_NONAPI_LOG_INIT_DATA_EXTRA_; \
|
+ QB_NONAPI_LOG_INIT_DATA_EXTRA_; \
|
||||||
+ /* finally, original, straightforward check */ \
|
+ /* finally, original, straightforward check */ \
|
||||||
+ assert("non-empty implicit callsite section, otherwise target's \
|
+ assert("non-empty implicit callsite section, otherwise target's \
|
||||||
@ -324,7 +419,7 @@ index 8a8d0ba..37d27b7 100644
|
|||||||
+Libs.private: @LIBS@
|
+Libs.private: @LIBS@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
diff --git a/lib/log.c b/lib/log.c
|
diff --git a/lib/log.c b/lib/log.c
|
||||||
index bfd218f..3e9972e 100644
|
index bfd218f..777f378 100644
|
||||||
--- a/lib/log.c
|
--- a/lib/log.c
|
||||||
+++ b/lib/log.c
|
+++ b/lib/log.c
|
||||||
@@ -853,6 +853,18 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
@@ -853,6 +853,18 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
||||||
@ -372,7 +467,7 @@ index bfd218f..3e9972e 100644
|
|||||||
qb_log_callsites_register(QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP);
|
qb_log_callsites_register(QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP);
|
||||||
dl_iterate_phdr(_log_so_walk_callback, NULL);
|
dl_iterate_phdr(_log_so_walk_callback, NULL);
|
||||||
_log_so_walk_dlnames();
|
_log_so_walk_dlnames();
|
||||||
@@ -884,6 +915,19 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
@@ -884,6 +915,24 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
||||||
_log_target_state_set(&conf[QB_LOG_SYSLOG], QB_LOG_STATE_ENABLED);
|
_log_target_state_set(&conf[QB_LOG_SYSLOG], QB_LOG_STATE_ENABLED);
|
||||||
(void)qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
|
(void)qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
|
||||||
QB_LOG_FILTER_FILE, "*", priority);
|
QB_LOG_FILTER_FILE, "*", priority);
|
||||||
@ -382,12 +477,17 @@ index bfd218f..3e9972e 100644
|
|||||||
+ " not observed by libqb, target's and/or"
|
+ " not observed by libqb, target's and/or"
|
||||||
+ " libqb's linkage at fault and"
|
+ " libqb's linkage at fault and"
|
||||||
+ " logging of the target will not"
|
+ " logging of the target will not"
|
||||||
+ " work reliably");
|
+ " work reliably (unless qb_log_init"
|
||||||
|
+ " function used unexpectedly in"
|
||||||
|
+ " no-logging context)");
|
||||||
+ else if (preinit_err == preinit_err_target_empty) {
|
+ else if (preinit_err == preinit_err_target_empty) {
|
||||||
+ qb_util_log(LOG_WARNING, "(LOG@QB) target chain supplied"
|
+ qb_util_log(LOG_WARNING, "(LOG@QB) target chain supplied"
|
||||||
+ " section empty, target's linkage"
|
+ " section empty, target's and/or"
|
||||||
+ " at fault and logging of the target"
|
+ " libqb's linkage at fault and"
|
||||||
+ " will not work reliably");
|
+ " logging of the target will not"
|
||||||
|
+ " work reliably (unless qb_log_init"
|
||||||
|
+ " function used unexpectedly in"
|
||||||
|
+ " no-logging context)");
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,10 +561,10 @@ index 145b9f4..cdfce1f 100755
|
|||||||
mock ${mock_args} --copyout \
|
mock ${mock_args} --copyout \
|
||||||
diff --git a/tests/functional/syslog-stdout.py b/tests/functional/syslog-stdout.py
|
diff --git a/tests/functional/syslog-stdout.py b/tests/functional/syslog-stdout.py
|
||||||
new file mode 100755
|
new file mode 100755
|
||||||
index 0000000..a0a761b
|
index 0000000..64baf4c
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/tests/functional/syslog-stdout.py
|
+++ b/tests/functional/syslog-stdout.py
|
||||||
@@ -0,0 +1,49 @@
|
@@ -0,0 +1,51 @@
|
||||||
+#!/usr/bin/python3
|
+#!/usr/bin/python3
|
||||||
+# Copyright 2017 Red Hat, Inc.
|
+# Copyright 2017 Red Hat, Inc.
|
||||||
+#
|
+#
|
||||||
@ -485,6 +585,8 @@ index 0000000..a0a761b
|
|||||||
+# You should have received a copy of the GNU Lesser General Public License
|
+# You should have received a copy of the GNU Lesser General Public License
|
||||||
+# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
+# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||||
+
|
+
|
||||||
|
+"""Simple /dev/log to stdout forwarding"""
|
||||||
|
+
|
||||||
+import socket
|
+import socket
|
||||||
+from atexit import register
|
+from atexit import register
|
||||||
+from os import remove
|
+from os import remove
|
||||||
@ -515,5 +617,5 @@ index 0000000..a0a761b
|
|||||||
+if __name__ == '__main__':
|
+if __name__ == '__main__':
|
||||||
+ main(*argv)
|
+ main(*argv)
|
||||||
--
|
--
|
||||||
2.14.2
|
2.14.3
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
From dbe771c0ab30ded6f1d82b6ed9d61ac04560e913 Mon Sep 17 00:00:00 2001
|
From 0de4d2298da9c5880ff8c32ac2e75c3104d44816 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: Fri, 6 Oct 2017 17:17:26 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 5/6] High: bare fix for libqb logging not working with
|
Subject: [PATCH 5/6] High: bare fix for libqb logging not working with
|
||||||
@ -7,7 +7,9 @@ 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
|
||||||
|
|
||||||
(or rather [read on]: "bare" fix)
|
(or rather [read on]: "bare" fix, now that we established means to
|
||||||
|
analyse the impact of the linker-dependent misbehaviour and to detect
|
||||||
|
some of its symptoms in preceding two commits, respectively)
|
||||||
|
|
||||||
Initially with the help of the internal test suite and the failing log
|
Initially with the help of the internal test suite and the failing log
|
||||||
test, it was eventually discovered[1] that these binutils commits going
|
test, it was eventually discovered[1] that these binutils commits going
|
||||||
@ -43,7 +45,7 @@ https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=487b6440dad57440939fa
|
|||||||
At least that change doesn't invalidate all the effort being put into
|
At least that change doesn't invalidate all the effort being put into
|
||||||
the original version of the changeset, only the configure script check
|
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
|
had to be refined so as not to miss the "orphan section magic not
|
||||||
working properly out of the box, without a bandaid" observation
|
working properly out of the box, without band aid" observation
|
||||||
(see the inline comment) -- the workaround arrangement needs
|
(see the inline comment) -- the workaround arrangement needs
|
||||||
to be applied in that case as well.
|
to be applied in that case as well.
|
||||||
|
|
||||||
@ -103,6 +105,8 @@ So further extensions were devised to cover both consumption models:
|
|||||||
of consuming libqb outside of it's own playground is hardly
|
of consuming libqb outside of it's own playground is hardly
|
||||||
the Right Thing) if portability is important, nonetheless!
|
the Right Thing) if portability is important, nonetheless!
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
On the address of linker script workaround, there are linkers out there
|
On the address of linker script workaround, there are linkers out there
|
||||||
that do not support the trick, for instance:
|
that do not support the trick, for instance:
|
||||||
- ld.gold from binutils (but it has hardly ever been working with
|
- ld.gold from binutils (but it has hardly ever been working with
|
||||||
@ -112,7 +116,7 @@ that do not support the trick, for instance:
|
|||||||
system linker even in the most recent releases of FreeBSD, unless
|
system linker even in the most recent releases of FreeBSD, unless
|
||||||
GCC toolchain is used instead
|
GCC toolchain is used instead
|
||||||
If these are hit when (because) the compiler has already demonstrated it
|
If these are hit when (because) the compiler has already demonstrated it
|
||||||
supports section attribute, the build system configuration is forcibly
|
supports "section" attribute, the build system configuration is forcibly
|
||||||
stopped, simply to stay conceptually compatible with the prior state in
|
stopped, simply to stay conceptually compatible with the prior state in
|
||||||
which the affinity to leverage that feature hasn't been called off
|
which the affinity to leverage that feature hasn't been called off
|
||||||
under any circumstances. One is, however, able to achieve exactly
|
under any circumstances. One is, however, able to achieve exactly
|
||||||
@ -143,6 +147,60 @@ within libqb.so proper (at least with binutils 2.29).
|
|||||||
|
|
||||||
* * *
|
* * *
|
||||||
|
|
||||||
|
To provide a high-level prioritized overview of what drove the approach:
|
||||||
|
|
||||||
|
- PRESERVATION OF BINARY COMPATIBILITY (ABI), which is achieved except
|
||||||
|
for a single "ABI nongracefulness" I am aware of but that's more
|
||||||
|
a consequence of slightly incorrect assumptions in the logic of
|
||||||
|
QB_LOG_INIT_DATA macro function predating this whole affair by
|
||||||
|
a long shot and which the patchset finally rectifies:
|
||||||
|
|
||||||
|
if in the run-time dynamic link, following is combined:
|
||||||
|
(. libqb, arbitrary variant: pre-/post-fix, binutils < / >= 2.29)
|
||||||
|
. an "intermediate" library (something that the end executable links
|
||||||
|
with) triggering QB_LOG_INIT_DATA macro and being built with
|
||||||
|
pre-fix libqb (and perhaps only with binutils < 2.29)
|
||||||
|
. end executable using no libqb's logging at all, but being built
|
||||||
|
with post-fix libqb (and arbitrary binutils < / >= 2.29)
|
||||||
|
then, unlike when executable is built with pre-fix libqb, the
|
||||||
|
special callsite data containing section in the ELF structure
|
||||||
|
of the executable is created + its boundary denoting symbols
|
||||||
|
defined within, despite the section being empty (did not happen
|
||||||
|
with pre-fix libqb), and because the symbols defined within the
|
||||||
|
target program have priority over that of shared libraries in the
|
||||||
|
symbol resolution fallback scheme, the assertion of QB_LOG_INIT_DATA
|
||||||
|
of the mentioned intermediate library will actually be evaluating
|
||||||
|
the inequality of boundaries for the section of the executable(!)
|
||||||
|
rather than it's own (or whatever higher prio symbols are hit,
|
||||||
|
presumably only present if the section at that level is non-empty,
|
||||||
|
basically a generalization of the story so far);
|
||||||
|
|
||||||
|
the problem then manifests as unability to run said executable
|
||||||
|
as it will fail because of the intermediate library inflicted
|
||||||
|
assertion (sadly with very unhelpful "Assertion `0' failed"
|
||||||
|
message);
|
||||||
|
|
||||||
|
fortunately, there's enough flexibility so as how to fix
|
||||||
|
this, either should be fine:
|
||||||
|
. have everything in the executable's library dependency closure
|
||||||
|
that links against libqb assurably (compile-time) linked with one
|
||||||
|
variant of libqb only (either all pre-fix or post-fix, mind the
|
||||||
|
apparent limitation of binutils' versions with the former)
|
||||||
|
. have the end executable (that does not use logging at all as
|
||||||
|
discussed precondition) linked using substitution like this:
|
||||||
|
s/-lqb/-l:libqb.so.0/ (you may need to adapt the number later)
|
||||||
|
and you may also need to add this CPPFLAG for the executable:
|
||||||
|
-DQB_KILL_ATTRIBUTE_SECTION
|
||||||
|
|
||||||
|
- as high level of isolation of the client space from the linker
|
||||||
|
(respectively toolchain) subtleties as possible (no new compilation
|
||||||
|
flags and such required, plus there's no way to hook any dynamic
|
||||||
|
computational ad-hoc decision when the compilation is about to
|
||||||
|
happen, anyway), and in turn, versatility is preserved as much as
|
||||||
|
possible
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
Finally, let's have a look how the already well-known test matrix
|
Finally, let's have a look how the already well-known test matrix
|
||||||
overview changes as of this commit, but first as a recap,
|
overview changes as of this commit, but first as a recap,
|
||||||
"X(Y)" denotes "X linked with linker Y":
|
"X(Y)" denotes "X linked with linker Y":
|
||||||
@ -164,12 +222,19 @@ table stated in the preceding commit):
|
|||||||
|
|
||||||
Everything is green \o/
|
Everything is green \o/
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
Note: as of this fix, it is assumed that the non-green counterpart of
|
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
|
this table in the message for the preceding commit (loosely though[!],
|
||||||
indicator how will mixing the logging participants wrt. linker+libqb
|
as the occurrence of empty callsite section can no longer be attributed
|
||||||
version work out, when "X(Y)" becomes read as "X linked with linker
|
to something bad going on as of this fix that enforces its presence
|
||||||
Y under additional restriction on libqb version when compile-time link
|
unconditionally, whereas it would be suppressed when unused before
|
||||||
is performed of the particular part":
|
with kind linkers, hence some other conditions can be witnessed
|
||||||
|
especially when QB_LOG_INIT_DATA misused in no-logging context)
|
||||||
|
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(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
|
X(b) .. ld.bfd = 2.29 (and likely on) AND libqb up to, but excluding
|
||||||
this fix
|
this fix
|
||||||
@ -186,6 +251,11 @@ Deficiencies:
|
|||||||
- not solvable as long as we use the linker script, and there's
|
- not solvable as long as we use the linker script, and there's
|
||||||
hardly any other way not requiring the libqb consumers to adapt
|
hardly any other way not requiring the libqb consumers to adapt
|
||||||
in any aspect
|
in any aspect
|
||||||
|
* as already mentioned, lacking compatibility with ld.gold linker and
|
||||||
|
won't foreseeably be (cf. https://bugzilla.redhat.com/1500898#c7)
|
||||||
|
- please stick with ld.bfd (i.e. default ld linker), which you
|
||||||
|
had to do in the past anyway (at least for compiling libqb
|
||||||
|
itself)
|
||||||
|
|
||||||
Open questions:
|
Open questions:
|
||||||
* should we enable attribute((__section__)) for powerpc and other minor
|
* should we enable attribute((__section__)) for powerpc and other minor
|
||||||
@ -193,7 +263,8 @@ Open questions:
|
|||||||
and related to that, we need to figure out how static and dynamic call
|
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
|
sites can live together -- say what will happen to logging programs
|
||||||
compiled with libqb w/o attribute sections when the underlying libqb is
|
compiled with libqb w/o attribute sections when the underlying libqb is
|
||||||
flipped to the one with them...
|
flipped to the one with them ... do we need a transition plan to be
|
||||||
|
spread across an extended period to keep it smooth?
|
||||||
|
|
||||||
* * *
|
* * *
|
||||||
|
|
||||||
@ -210,14 +281,14 @@ Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
|||||||
---
|
---
|
||||||
configure.ac | 147 +++++++++++++++++++++++++++++++++++++++++------
|
configure.ac | 147 +++++++++++++++++++++++++++++++++++++++++------
|
||||||
include/qb/qbconfig.h.in | 2 +
|
include/qb/qbconfig.h.in | 2 +
|
||||||
include/qb/qblog.h | 37 ++++++++----
|
include/qb/qblog.h | 32 +++++++++--
|
||||||
lib/Makefile.am | 67 +++++++++++++++++++++
|
lib/Makefile.am | 67 +++++++++++++++++++++
|
||||||
lib/libqb.pc.in | 8 +++
|
lib/libqb.pc.in | 8 +++
|
||||||
lib/log.c | 7 +++
|
lib/log.c | 7 +++
|
||||||
lib/qblog_script.la.in | 15 +++++
|
lib/qblog_script.la.in | 15 +++++
|
||||||
lib/qblog_script.ld.in | 27 +++++++++
|
lib/qblog_script.ld.in | 27 +++++++++
|
||||||
lib/qblog_script_noop.ld | 1 +
|
lib/qblog_script_noop.ld | 1 +
|
||||||
10 files changed, 281 insertions(+), 30 deletions(-)
|
9 files changed, 282 insertions(+), 24 deletions(-)
|
||||||
create mode 100644 lib/qblog_script.la.in
|
create mode 100644 lib/qblog_script.la.in
|
||||||
create mode 100644 lib/qblog_script.ld.in
|
create mode 100644 lib/qblog_script.ld.in
|
||||||
create mode 100644 lib/qblog_script_noop.ld
|
create mode 100644 lib/qblog_script_noop.ld
|
||||||
@ -429,10 +500,22 @@ index c1852e1..b0bf428 100644
|
|||||||
/* versioning info: MAJOR, MINOR, MICRO, and REST components */
|
/* versioning info: MAJOR, MINOR, MICRO, and REST components */
|
||||||
#undef QB_VER_MAJOR
|
#undef QB_VER_MAJOR
|
||||||
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
||||||
index 10cd62c..07ae4c3 100644
|
index 766cffe..cd7256a 100644
|
||||||
--- a/include/qb/qblog.h
|
--- a/include/qb/qblog.h
|
||||||
+++ b/include/qb/qblog.h
|
+++ b/include/qb/qblog.h
|
||||||
@@ -286,15 +286,17 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
@@ -79,7 +79,10 @@ extern "C" {
|
||||||
|
* scope in exactly one source file (preferably the main one) to be mixed into
|
||||||
|
* the resulting compilation unit. This is a self-defensive measure for when
|
||||||
|
* the linker-assisted collection of callsite data silently fails, which could
|
||||||
|
- * otherwise go unnoticed, causing troubles down the road.
|
||||||
|
+ * otherwise go unnoticed, causing troubles down the road, but alas it cannot
|
||||||
|
+ * discern misuse of @c QB_LOG_INIT_DATA() macro in no-logging context from
|
||||||
|
+ * broken callsite section handling assumptions owing to overboard fancy
|
||||||
|
+ * linker -- situation that the self-check aims to detect in the first place.
|
||||||
|
*
|
||||||
|
* @par Configuring log targets.
|
||||||
|
* A log target can be syslog, stderr, the blackbox, stdout, or a text file.
|
||||||
|
@@ -287,12 +290,13 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
||||||
|
|
||||||
/* Related to the next macro that is -- unlike this one -- a public API */
|
/* Related to the next macro that is -- unlike this one -- a public API */
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
@ -440,26 +523,21 @@ index 10cd62c..07ae4c3 100644
|
|||||||
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \
|
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \
|
||||||
_Pragma(QB_PP_STRINGIFY(GCC warning QB_PP_STRINGIFY( \
|
_Pragma(QB_PP_STRINGIFY(GCC warning QB_PP_STRINGIFY( \
|
||||||
without "_GNU_SOURCE" defined (directly or not) \
|
without "_GNU_SOURCE" defined (directly or not) \
|
||||||
- qb_log_init_data cannot check sanity of libqb proper)))
|
- QB_LOG_INIT_DATA cannot check sanity of libqb proper)))
|
||||||
+ qb_log_init_data cannot check sanity of libqb proper \
|
+ QB_LOG_INIT_DATA cannot check sanity of libqb proper \
|
||||||
+ nor )))
|
+ nor of the target site originating this check alone)))
|
||||||
#else
|
#else
|
||||||
-#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
|
-#define QB_NONAPI_LOG_INIT_DATA_EXTRA_ \
|
||||||
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \
|
+#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \
|
||||||
|
{ Dl_info work_dli; \
|
||||||
/* libqb sanity (locating libqb by it's relatively unique \
|
/* libqb sanity (locating libqb by it's relatively unique \
|
||||||
-- and currently only such per-linkage global one -- \
|
-- and currently only such per-linkage global one -- \
|
||||||
non-functional symbol, due to possible confusion otherwise) */ \
|
@@ -310,6 +314,23 @@ linkage at fault and logging would not work reliably" \
|
||||||
+ { Dl_info work_dli; \
|
|
||||||
if (dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli) \
|
|
||||||
&& (work_handle = dlopen(work_dli.dli_fname, \
|
|
||||||
RTLD_LOCAL|RTLD_LAZY)) != NULL) { \
|
|
||||||
@@ -308,7 +310,22 @@ linkage at fault and logging would not work reliably" \
|
|
||||||
assert("libqb's callsite section non-empty, otherwise libqb's \
|
assert("libqb's callsite section non-empty, otherwise libqb's \
|
||||||
linkage at fault and logging would not work reliably" \
|
linkage at fault and logging would not work reliably" \
|
||||||
&& work_s1 != work_s2); \
|
&& work_s1 != work_s2); \
|
||||||
- dlclose(work_handle); }
|
|
||||||
+ dlclose(work_handle); } \
|
+ dlclose(work_handle); } \
|
||||||
+ /* finally, slightly modified original, straightforward check */ \
|
+ /* sanity of the target site originating this check alone */ \
|
||||||
+ if (dladdr(dlsym(RTLD_DEFAULT, QB_PP_STRINGIFY(name)), &work_dli) \
|
+ if (dladdr(dlsym(RTLD_DEFAULT, QB_PP_STRINGIFY(name)), &work_dli) \
|
||||||
+ && (work_handle = dlopen(work_dli.dli_fname, \
|
+ && (work_handle = dlopen(work_dli.dli_fname, \
|
||||||
+ RTLD_LOCAL|RTLD_LAZY)) != NULL) { \
|
+ RTLD_LOCAL|RTLD_LAZY)) != NULL) { \
|
||||||
@ -468,42 +546,26 @@ index 10cd62c..07ae4c3 100644
|
|||||||
+ work_s2 = (struct qb_log_callsite *) \
|
+ work_s2 = (struct qb_log_callsite *) \
|
||||||
+ dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \
|
+ dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \
|
||||||
+ assert("target's own callsite section observable, otherwise \
|
+ assert("target's own callsite section observable, otherwise \
|
||||||
+target's own linkage at fault and logging would not work reliably" \
|
+target's own linkage at fault and logging would not work reliably \
|
||||||
|
+(unless QB_LOG_INIT_DATA macro used unexpectedly in no-logging context)"\
|
||||||
+ && work_s1 != NULL && work_s2 != NULL); \
|
+ && work_s1 != NULL && work_s2 != NULL); \
|
||||||
+ assert("target's own callsite section non-empty, otherwise \
|
+ assert("target's own callsite section non-empty, otherwise \
|
||||||
+target's own linkage at fault and logging would not work reliably" \
|
+target's own linkage at fault and logging would not work reliably \
|
||||||
|
+(unless QB_LOG_INIT_DATA macro used unexpectedly in no-logging context)"\
|
||||||
+ && work_s1 != work_s2); \
|
+ && work_s1 != work_s2); \
|
||||||
+ dlclose(work_handle); } }
|
dlclose(work_handle); } }
|
||||||
#endif /* _GNU_SOURCE */
|
#endif /* _GNU_SOURCE */
|
||||||
|
|
||||||
/**
|
@@ -354,8 +375,7 @@ linkage at fault and logging would not work reliably" \
|
||||||
@@ -341,22 +358,18 @@ linkage at fault and logging would not work reliably" \
|
|
||||||
void name(void); \
|
|
||||||
void name(void) { \
|
|
||||||
void *work_handle; struct qb_log_callsite *work_s1, *work_s2; \
|
|
||||||
- Dl_info work_dli; \
|
|
||||||
- /* our own (target's) sanity */ \
|
|
||||||
+ /* our own (target's) sanity, or possibly that of higher level \
|
|
||||||
+ symbol resolution site */ \
|
|
||||||
if ((work_handle = dlopen(NULL, RTLD_LOCAL|RTLD_LAZY)) != NULL) { \
|
|
||||||
work_s1 = (struct qb_log_callsite *) \
|
|
||||||
dlsym(work_handle, QB_ATTR_SECTION_START_STR); \
|
|
||||||
work_s2 = (struct qb_log_callsite *) \
|
|
||||||
dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \
|
|
||||||
- assert("target's callsite section self-observable, otherwise \
|
|
||||||
+ assert("target's callsite section observable, otherwise \
|
|
||||||
target's and/or libqb's linkage at fault and logging would not work \
|
target's and/or libqb's linkage at fault and logging would not work \
|
||||||
reliably" \
|
reliably" \
|
||||||
&& work_s1 != NULL && work_s2 != NULL); } \
|
&& work_s1 != NULL && work_s2 != NULL); } \
|
||||||
|
- /* better targeted attestations when available */ \
|
||||||
- QB_NONAPI_LOG_INIT_DATA_EXTRA_; \
|
- QB_NONAPI_LOG_INIT_DATA_EXTRA_; \
|
||||||
- /* finally, original, straightforward check */ \
|
+ QB_NONAPI_LOG_INIT_DATA_EXTRA_(name); \
|
||||||
- assert("non-empty implicit callsite section, otherwise target's \
|
/* finally, original, straightforward check */ \
|
||||||
-linkage at fault and logging would not work reliably" \
|
assert("non-empty implicit callsite section, otherwise target's \
|
||||||
- && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \
|
linkage at fault and logging would not work reliably" \
|
||||||
+ QB_NONAPI_LOG_INIT_DATA_EXTRA_(name); } \
|
|
||||||
void __attribute__ ((constructor)) name(void);
|
|
||||||
#else
|
|
||||||
#define QB_LOG_INIT_DATA(name)
|
|
||||||
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
||||||
index 0bebeb5..ff5b3b4 100644
|
index 0bebeb5..ff5b3b4 100644
|
||||||
--- a/lib/Makefile.am
|
--- a/lib/Makefile.am
|
||||||
@ -618,7 +680,7 @@ index 37d27b7..65d3b8e 100644
|
|||||||
Libs.private: @LIBS@
|
Libs.private: @LIBS@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
diff --git a/lib/log.c b/lib/log.c
|
diff --git a/lib/log.c b/lib/log.c
|
||||||
index 3e9972e..514103f 100644
|
index 777f378..b0c8735 100644
|
||||||
--- a/lib/log.c
|
--- a/lib/log.c
|
||||||
+++ b/lib/log.c
|
+++ b/lib/log.c
|
||||||
@@ -40,6 +40,13 @@
|
@@ -40,6 +40,13 @@
|
||||||
@ -697,5 +759,5 @@ index 0000000..f037fca
|
|||||||
@@ -0,0 +1 @@
|
@@ -0,0 +1 @@
|
||||||
+/* this is an empty linker script having a role of a NO-OP link object */
|
+/* this is an empty linker script having a role of a NO-OP link object */
|
||||||
--
|
--
|
||||||
2.14.2
|
2.14.3
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
From eb0c29d0213784597b7fdffb24e79d9f0774b8c7 Mon Sep 17 00:00:00 2001
|
From 4cd8bdcd3daca8781b5ee7bd8cdfdbcd5ba9cb92 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: Fri, 6 Oct 2017 17:17:26 +0200
|
Date: Fri, 6 Oct 2017 17:17:26 +0200
|
||||||
Subject: [PATCH 6/6] Low: fix internal object symbol's leak & expose run-time
|
Subject: [PATCH 6/6] Low: fix internal object symbol's leak & expose run-time
|
||||||
@ -13,11 +13,13 @@ 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
|
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
|
started to depend on that symbol so as to locate the library handle
|
||||||
for libqb itself correctly. This is trivially fixed by finally exposing
|
for libqb itself correctly. This is trivially fixed by finally exposing
|
||||||
library versioning info in run-time through objects a structure with
|
library versioning info in run-time ("online") as a structure with
|
||||||
members corresponding to compile-time/static counterparts from
|
members corresponding to compile-time ("offline") counterparts from
|
||||||
qbconfig.h header file, plus lower-cased equivalent of QB_VER_STR.
|
qbconfig.h header file, which are admittedly of very limited use
|
||||||
Better than to roll out a futile data object serving as an artificial
|
as opposed to the newly introduced dynamic info, plus lower-cased
|
||||||
anchor for the above purpose, and this was a while due, afterall.
|
equivalent of QB_VER_STR. Better than to roll out a futile data object
|
||||||
|
serving as an artificial anchor for the above purpose, and this was
|
||||||
|
due for a while, afterall.
|
||||||
|
|
||||||
In turn, also bump "current" and "age" of fields of the libtool's
|
In turn, also bump "current" and "age" of fields of the libtool's
|
||||||
"-version-info" versioning system.
|
"-version-info" versioning system.
|
||||||
@ -31,12 +33,12 @@ Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
|||||||
lib/log.c | 10 ++++++----
|
lib/log.c | 10 ++++++----
|
||||||
lib/log_format.c | 2 +-
|
lib/log_format.c | 2 +-
|
||||||
lib/util.c | 10 ++++++++++
|
lib/util.c | 10 ++++++++++
|
||||||
tests/functional/log_client.c | 4 ++++
|
tests/functional/log_client.c | 5 +++++
|
||||||
tests/functional/log_test_client.err | 2 +-
|
tests/functional/log_test_client.err | 2 +-
|
||||||
9 files changed, 45 insertions(+), 11 deletions(-)
|
9 files changed, 46 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
diff --git a/include/qb/qbconfig.h.in b/include/qb/qbconfig.h.in
|
diff --git a/include/qb/qbconfig.h.in b/include/qb/qbconfig.h.in
|
||||||
index b0bf428..19d14bf 100644
|
index b0bf428..7199b1b 100644
|
||||||
--- a/include/qb/qbconfig.h.in
|
--- a/include/qb/qbconfig.h.in
|
||||||
+++ b/include/qb/qbconfig.h.in
|
+++ b/include/qb/qbconfig.h.in
|
||||||
@@ -32,7 +32,12 @@
|
@@ -32,7 +32,12 @@
|
||||||
@ -47,27 +49,26 @@ index b0bf428..19d14bf 100644
|
|||||||
+/* versioning info: MAJOR, MINOR, MICRO, and REST components;
|
+/* versioning info: MAJOR, MINOR, MICRO, and REST components;
|
||||||
+ note that static compile-time info is not that useful as consulting
|
+ note that static compile-time info is not that useful as consulting
|
||||||
+ the respectively named members of qb_version struct constant under
|
+ the respectively named members of qb_version struct constant under
|
||||||
+ @c qb_ver identifier (or @qb_ver_str equivalent of the local
|
+ @c qb_ver identifier (or @c qb_ver_str equivalent of the local
|
||||||
+ upper-cased value) directly from libqb in run-time (see qbutil.h),
|
+ upper-cased value) directly from libqb in run-time (see qbutil.h),
|
||||||
+ but that was only introduced after v1.0.2 */
|
+ but that was only introduced after v1.0.2 */
|
||||||
#undef QB_VER_MAJOR
|
#undef QB_VER_MAJOR
|
||||||
#undef QB_VER_MINOR
|
#undef QB_VER_MINOR
|
||||||
#undef QB_VER_MICRO
|
#undef QB_VER_MICRO
|
||||||
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
|
||||||
index 07ae4c3..a059fb5 100644
|
index cd7256a..4b18eba 100644
|
||||||
--- a/include/qb/qblog.h
|
--- a/include/qb/qblog.h
|
||||||
+++ b/include/qb/qblog.h
|
+++ b/include/qb/qblog.h
|
||||||
@@ -294,10 +294,12 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
@@ -299,9 +299,11 @@ extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
|
||||||
#else
|
|
||||||
#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \
|
#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \
|
||||||
|
{ Dl_info work_dli; \
|
||||||
/* libqb sanity (locating libqb by it's relatively unique \
|
/* libqb sanity (locating libqb by it's relatively unique \
|
||||||
- -- and currently only such per-linkage global one -- \
|
- -- and currently only such per-linkage global one -- \
|
||||||
- non-functional symbol, due to possible confusion otherwise) */ \
|
- non-functional symbol, due to possible confusion otherwise) */ \
|
||||||
|
- if (dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli) \
|
||||||
+ non-functional symbols -- the two are mutually exclusive, the \
|
+ non-functional symbols -- the two are mutually exclusive, the \
|
||||||
+ ordinarily latter was introduced by accident, the former is \
|
+ ordinarily latter was introduced by accident, the former is \
|
||||||
+ intentional -- due to possible confusion otherwise) */ \
|
+ intentional -- due to possible confusion otherwise) */ \
|
||||||
{ Dl_info work_dli; \
|
|
||||||
- if (dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli) \
|
|
||||||
+ if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli) \
|
+ if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli) \
|
||||||
+ || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli)) \
|
+ || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli)) \
|
||||||
&& (work_handle = dlopen(work_dli.dli_fname, \
|
&& (work_handle = dlopen(work_dli.dli_fname, \
|
||||||
@ -109,7 +110,7 @@ index ff5b3b4..a428975 100644
|
|||||||
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
|
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
|
||||||
array.c loop.c loop_poll.c loop_job.c \
|
array.c loop.c loop_poll.c loop_job.c \
|
||||||
diff --git a/lib/log.c b/lib/log.c
|
diff --git a/lib/log.c b/lib/log.c
|
||||||
index 514103f..37f1e4e 100644
|
index b0c8735..32c9315 100644
|
||||||
--- a/lib/log.c
|
--- a/lib/log.c
|
||||||
+++ b/lib/log.c
|
+++ b/lib/log.c
|
||||||
@@ -892,10 +892,12 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
@@ -892,10 +892,12 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
||||||
@ -123,7 +124,7 @@ index 514103f..37f1e4e 100644
|
|||||||
+ the proper libqb's ones (locating libqb by it's relatively unique
|
+ the proper libqb's ones (locating libqb by it's relatively unique
|
||||||
+ non-functional symbols -- the two are mutually exclusive, the
|
+ non-functional symbols -- the two are mutually exclusive, the
|
||||||
+ ordinarily latter was introduced by accident, the former is
|
+ ordinarily latter was introduced by accident, the former is
|
||||||
+ intentional -- due to possible confusion otherwise) */
|
+ intentional -- due to possible confusion otherwise) */
|
||||||
+ if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli)
|
+ if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli)
|
||||||
+ || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli))
|
+ || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli))
|
||||||
&& (work_handle = dlopen(work_dli.dli_fname,
|
&& (work_handle = dlopen(work_dli.dli_fname,
|
||||||
@ -168,28 +169,29 @@ index 6181a25..a510bd1 100644
|
|||||||
+
|
+
|
||||||
+const char *const qb_ver_str = QB_VER_STR;
|
+const char *const qb_ver_str = QB_VER_STR;
|
||||||
diff --git a/tests/functional/log_client.c b/tests/functional/log_client.c
|
diff --git a/tests/functional/log_client.c b/tests/functional/log_client.c
|
||||||
index c60d657..cb3e20b 100644
|
index c60d657..d5d8089 100644
|
||||||
--- a/tests/functional/log_client.c
|
--- a/tests/functional/log_client.c
|
||||||
+++ b/tests/functional/log_client.c
|
+++ b/tests/functional/log_client.c
|
||||||
@@ -53,6 +53,10 @@ main(int32_t argc, char *argv[])
|
@@ -53,6 +53,11 @@ main(int32_t argc, char *argv[])
|
||||||
qb_log_tags_stringify_fn_set(my_tags_stringify);
|
qb_log_tags_stringify_fn_set(my_tags_stringify);
|
||||||
qb_log_format_set(QB_LOG_STDERR, "[%5g|%p] %f:%l:%b");
|
qb_log_format_set(QB_LOG_STDERR, "[%5g|%p] %f:%l:%b");
|
||||||
|
|
||||||
+#if 0
|
+#if 0
|
||||||
+ printf("\n==%s==\n\n", qb_ver_str);
|
+ printf("\n==%s consists of: %d, %d, %d, %s==\n\n", qb_ver_str,
|
||||||
|
+ qb_ver.major, qb_ver.minor, qb_ver.micro, qb_ver.rest);
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
#if 0
|
#if 0
|
||||||
printf("--\n");
|
printf("--\n");
|
||||||
qb_log_callsites_dump();
|
qb_log_callsites_dump();
|
||||||
diff --git a/tests/functional/log_test_client.err b/tests/functional/log_test_client.err
|
diff --git a/tests/functional/log_test_client.err b/tests/functional/log_test_client.err
|
||||||
index cb0ff3c..29b9db0 100644
|
index cb0ff3c..7bc11b0 100644
|
||||||
--- a/tests/functional/log_test_client.err
|
--- a/tests/functional/log_test_client.err
|
||||||
+++ b/tests/functional/log_test_client.err
|
+++ b/tests/functional/log_test_client.err
|
||||||
@@ -1,2 +1,2 @@
|
@@ -1,2 +1,2 @@
|
||||||
-[MAIN |debug] ../log_client.c:64:hello
|
-[MAIN |debug] ../log_client.c:64:hello
|
||||||
+[MAIN |debug] ../log_client.c:68:hello
|
+[MAIN |debug] ../log_client.c:69:hello
|
||||||
[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2)
|
[libqb|error] log_blackbox.c:196:qb_log_blackbox_print_from_file: No such file or directory (2)
|
||||||
--
|
--
|
||||||
2.14.2
|
2.14.3
|
||||||
|
|
||||||
|
15
libqb.spec
15
libqb.spec
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: libqb
|
Name: libqb
|
||||||
Version: 1.0.2
|
Version: 1.0.2
|
||||||
Release: 11%{?dist}
|
Release: 12%{?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
|
||||||
@ -77,21 +77,24 @@ developing applications that use %{name}.
|
|||||||
%{_mandir}/man3/qb*3*
|
%{_mandir}/man3/qb*3*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Oct 25 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-12
|
||||||
|
- Evolution of the previous (rhbz#1478089)
|
||||||
|
|
||||||
* Wed Oct 18 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-11
|
* Wed Oct 18 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-11
|
||||||
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
- Evolution of the previous (rhbz#1478089)
|
||||||
|
|
||||||
* Fri Oct 13 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-10
|
* Fri Oct 13 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-10
|
||||||
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
- Evolution of the previous (rhbz#1478089)
|
||||||
|
|
||||||
* Mon Oct 09 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-9
|
* Mon Oct 09 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-9
|
||||||
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
- Evolution of the previous (rhbz#1478089)
|
||||||
|
|
||||||
* Fri Oct 06 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-8
|
* Fri Oct 06 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-8
|
||||||
- Evolution of the previous (rhbz#1478089, rhbz#1487787)
|
- Evolution of the previous (rhbz#1478089)
|
||||||
- New test included in check phase (as per upsteam)
|
- 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)
|
||||||
|
|
||||||
* Fri Sep 01 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-6
|
* Fri Sep 01 2017 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.2-6
|
||||||
- Better approach so as to mitigate changed treatment of orphaned sections
|
- Better approach so as to mitigate changed treatment of orphaned sections
|
||||||
|
Loading…
Reference in New Issue
Block a user