diff options
author | Pablo Neira Ayuso <pablo@gnumonks.org> | 2011-05-19 01:40:43 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2011-05-19 01:40:43 +0200 |
commit | dd93bf46ed0c3c75c1e330db2197703c0b6f8cda (patch) | |
tree | eacd9d1150da3664d6d685e2c3b8cf829041a50f /src | |
parent | ba01fa44feb6deb0f0359f381eafe866991c06c1 (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."
Diffstat (limited to 'src')
-rw-r--r-- | src/logging.c | 6 |
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) continue; + /* 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); } } |