diff options
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-05-19 08:55:32 +0200
committerHarald Welte <laforge@gnumonks.org>2011-05-19 08:55:32 +0200
commit825607672215b7a12ea6e201a89cd5209f6d657f (patch)
parentba01fa44feb6deb0f0359f381eafe866991c06c1 (diff)
logging: fix corrupted output
Harald reported a problem in the logging: http://lists.osmocom.org/pipermail/openbsc/2011-May/002896.html Reverting 81e9636454294ae10ef9bc8bf149dd0248afce76 seems to fix the problem. However, that workaround looks ugly. Holger gives us another clue on what was wrong: http://lists.osmocom.org/pipermail/openbsc/2011-May/002905.html While digging in the manpage, I found this: "The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() are equivalent to the functions printf(), fprintf(), sprintf(), snprintf(), respectively, except that they are called with a va_list instead of a variable number of arguments. These functions do not call the va_end macro. Consequently, the value of ap is undefined after the call. The application should call va_end(ap) itself afterwards."
1 files changed, 6 insertions, 0 deletions
diff --git a/src/logging.c b/src/logging.c
index 0911010a..3c9dc03f 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -198,6 +198,7 @@ static void _logp(unsigned int subsys, int level, char *file, int line,
llist_for_each_entry(tar, &osmo_log_target_list, entry) {
struct log_category *category;
int output = 0;
+ va_list bp;
category = &tar->categories[subsys];
/* subsystem is not supposed to be logged */
@@ -224,7 +225,12 @@ static void _logp(unsigned int subsys, int level, char *file, int line,
if (!output)
+ /* According to the manpage, vsnprintf leaves the value of ap
+ * in undefined state. Since _output uses vsnprintf and it may
+ * be called several times, we have to pass a copy of ap. */
+ va_copy(bp, ap);
_output(tar, subsys, level, file, line, cont, format, ap);
+ va_end(bp);