laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmocore/+/35208?usp=email )

 (

2 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted 
one.
 )Change subject: logging: fix nul octets in log output / use osmo_strbuf
......................................................................

logging: fix nul octets in log output / use osmo_strbuf

Patch [1] merged few weeks ago, for yet unknown reasons, sprinkles nul
characters at seemingly randomly chosen log line ends.

Trying to figure out why that happens, i got tired of the unreadable
cruft, and decided to migrate the _output_buf() implementation to
osmo_strbuf first.

With osmo_strbuf in use and implementing 1:1 what the previous code did,
the odd nul octets have disappeared. So the bug was caused by unreadable
code.

[1] 11a416827dd9f2da6b7c1db0e1e83adb1e6e5cc8
Ia7de9d88aa5ac48ec0d5c1a931a89d21c02c5433
"logging: ensure ANSI color escape is sent in same line/before newline"

Related: OS#6284
Related: Ia7de9d88aa5ac48ec0d5c1a931a89d21c02c5433
Change-Id: Ib577a5e0d7450ce93ff21f37ba3262704cbf4752
---
M src/core/logging.c
1 file changed, 70 insertions(+), 84 deletions(-)

Approvals:
  Jenkins Builder: Verified
  osmith: Looks good to me, but someone else must approve
  neels: Looks good to me, approved
  laforge: Looks good to me, but someone else must approve




diff --git a/src/core/logging.c b/src/core/logging.c
index dc19cf3..0d215f4 100644
--- a/src/core/logging.c
+++ b/src/core/logging.c
@@ -486,18 +486,18 @@
                        unsigned int level, const char *file, int line, int 
cont,
                        const char *format, va_list ap)
 {
-       int ret, len = 0, offset = 0, rem = buf_len;
+       int ret;
        const char *c_subsys = NULL;
+       struct osmo_strbuf sb = { .buf = buf, .len = buf_len };
+
+       /* safety net in case of encountering errors and returning nothing */
+       buf[0] = '\0';

        /* are we using color */
        if (target->use_color) {
                c_subsys = color(subsys);
-               if (c_subsys) {
-                       ret = snprintf(buf + offset, rem, "%s", c_subsys);
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
-               }
+               if (c_subsys)
+                       OSMO_STRBUF_PRINTF(sb, "%s", c_subsys);
        }
        if (!cont) {
                if (target->print_ext_timestamp) {
@@ -506,13 +506,10 @@
                        struct timeval tv;
                        osmo_gettimeofday(&tv, NULL);
                        localtime_r(&tv.tv_sec, &tm);
-                       ret = snprintf(buf + offset, rem, 
"%04d%02d%02d%02d%02d%02d%03d ",
-                                       tm.tm_year + 1900, tm.tm_mon + 1, 
tm.tm_mday,
-                                       tm.tm_hour, tm.tm_min, tm.tm_sec,
-                                       (int)(tv.tv_usec / 1000));
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                       OSMO_STRBUF_PRINTF(sb, "%04d%02d%02d%02d%02d%02d%03d ",
+                                          tm.tm_year + 1900, tm.tm_mon + 1, 
tm.tm_mday,
+                                          tm.tm_hour, tm.tm_min, tm.tm_sec,
+                                          (int)(tv.tv_usec / 1000));
 #endif
                } else if (target->print_timestamp) {
                        time_t tm;
@@ -520,97 +517,66 @@
                                goto err;
                        /* Get human-readable representation of time.
                           man ctime: we need at least 26 bytes in buf */
-                       if (rem < 26 || !ctime_r(&tm, buf + offset))
+                       if (OSMO_STRBUF_REMAIN(sb) < 26 || !ctime_r(&tm, 
sb.pos))
                                goto err;
-                       ret = strlen(buf + offset);
+                       ret = strnlen(sb.pos, 26);
                        if (ret <= 0)
                                goto err;
+                       OSMO_STRBUF_ADDED_TAIL(sb, ret);
                        /* Get rid of useless final '\n' added by ctime_r. We 
want a space instead. */
-                       buf[offset + ret - 1] = ' ';
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                       OSMO_STRBUF_DROP_TAIL(sb, 1);
+                       OSMO_STRBUF_PRINTF(sb, " ");
                }
                if (target->print_tid) {
                        if (logging_tid == 0)
                                logging_tid = (long int)osmo_gettid();
-                       ret = snprintf(buf + offset, rem, "%ld ", logging_tid);
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                       OSMO_STRBUF_PRINTF(sb, "%ld ", logging_tid);
                }
-               if (target->print_category) {
-                       ret = snprintf(buf + offset, rem, "%s%s%s%s ",
-                                      target->use_color ? level_color(level) : 
"",
-                                      log_category_name(subsys),
-                                      target->use_color ? OSMO_LOGCOLOR_END : 
"",
-                                      c_subsys ? c_subsys : "");
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
-               }
-               if (target->print_level) {
-                       ret = snprintf(buf + offset, rem, "%s%s%s%s ",
-                                      target->use_color ? level_color(level) : 
"",
-                                      log_level_str(level),
-                                      target->use_color ? OSMO_LOGCOLOR_END : 
"",
-                                      c_subsys ? c_subsys : "");
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
-               }
-               if (target->print_category_hex) {
-                       ret = snprintf(buf + offset, rem, "<%4.4x> ", subsys);
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
-               }
+               if (target->print_category)
+                       OSMO_STRBUF_PRINTF(sb, "%s%s%s%s ",
+                                          target->use_color ? 
level_color(level) : "",
+                                          log_category_name(subsys),
+                                          target->use_color ? 
OSMO_LOGCOLOR_END : "",
+                                          c_subsys ? c_subsys : "");
+               if (target->print_level)
+                       OSMO_STRBUF_PRINTF(sb, "%s%s%s%s ",
+                                          target->use_color ? 
level_color(level) : "",
+                                          log_level_str(level),
+                                          target->use_color ? 
OSMO_LOGCOLOR_END : "",
+                                          c_subsys ? c_subsys : "");
+               if (target->print_category_hex)
+                       OSMO_STRBUF_PRINTF(sb, "<%4.4x> ", subsys);

                if (target->print_filename_pos == LOG_FILENAME_POS_HEADER_END) {
                        switch (target->print_filename2) {
                        case LOG_FILENAME_NONE:
                                break;
                        case LOG_FILENAME_PATH:
-                               ret = snprintf(buf + offset, rem, "%s:%d ", 
file, line);
-                               if (ret < 0)
-                                       goto err;
-                               OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                               OSMO_STRBUF_PRINTF(sb, "%s:%d ", file, line);
                                break;
                        case LOG_FILENAME_BASENAME:
-                               ret = snprintf(buf + offset, rem, "%s:%d ", 
const_basename(file), line);
-                               if (ret < 0)
-                                       goto err;
-                               OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                               OSMO_STRBUF_PRINTF(sb, "%s:%d ", 
const_basename(file), line);
                                break;
                        }
                }
        }
-       ret = vsnprintf(buf + offset, rem, format, ap);
-       if (ret < 0)
-               goto err;
-       OSMO_SNPRINTF_RET(ret, rem, offset, len);
+       OSMO_STRBUF_APPEND(sb, vsnprintf, format, ap);

        /* For LOG_FILENAME_POS_LAST, print the source file info only when the 
caller ended the log
         * message in '\n'. If so, nip the last '\n' away, insert the source 
file info and re-append an
         * '\n'. All this to allow LOGP("start..."); LOGPC("...end\n") 
constructs. */
        if (target->print_filename_pos == LOG_FILENAME_POS_LINE_END
-           && offset > 0 && buf[offset - 1] == '\n') {
+           && sb.pos > sb.buf && *(sb.pos - 1) == '\n') {
                switch (target->print_filename2) {
                case LOG_FILENAME_NONE:
                        break;
                case LOG_FILENAME_PATH:
-                       offset--;
-                       len--;
-                       ret = snprintf(buf + offset, rem, " (%s:%d)\n", file, 
line);
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                       OSMO_STRBUF_DROP_TAIL(sb, 1);
+                       OSMO_STRBUF_PRINTF(sb, " (%s:%d)\n", file, line);
                        break;
                case LOG_FILENAME_BASENAME:
-                       offset--;
-                       len--;
-                       ret = snprintf(buf + offset, rem, " (%s:%d)\n", 
const_basename(file), line);
-                       if (ret < 0)
-                               goto err;
-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);
+                       OSMO_STRBUF_DROP_TAIL(sb, 1);
+                       OSMO_STRBUF_PRINTF(sb, " (%s:%d)\n", 
const_basename(file), line);
                        break;
                }
        }
@@ -618,21 +584,15 @@
        if (target->use_color && c_subsys) {
                /* Ensure the last color escape is sent before the newline
                * (to not clobber journald, which works on single-lines only) */
-               if (offset > 0 && buf[offset - 1] == '\n') {
-                       offset--; rem++;
-                       ret = snprintf(buf + offset, rem, OSMO_LOGCOLOR_END 
"\n");
+               if (sb.pos > sb.buf && *(sb.pos - 1) == '\n') {
+                       OSMO_STRBUF_DROP_TAIL(sb, 1);
+                       OSMO_STRBUF_PRINTF(sb, OSMO_LOGCOLOR_END "\n");
                } else {
-                       ret = snprintf(buf + offset, rem, OSMO_LOGCOLOR_END);
+                       OSMO_STRBUF_PRINTF(sb, OSMO_LOGCOLOR_END);
                }
-
-               if (ret < 0)
-                       goto err;
-               OSMO_SNPRINTF_RET(ret, rem, offset, len);
        }
 err:
-       len = OSMO_MIN(buf_len - 1, len);
-       buf[len] = '\0';
-       return len;
+       return OSMO_STRBUF_CHAR_COUNT(sb);
 }

 /* Format the log line for given target; use a stack buffer and call 
target->output */

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35208?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Ib577a5e0d7450ce93ff21f37ba3262704cbf4752
Gerrit-Change-Number: 35208
Gerrit-PatchSet: 3
Gerrit-Owner: neels <nhofm...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: neels <nhofm...@sysmocom.de>
Gerrit-Reviewer: osmith <osm...@sysmocom.de>
Gerrit-MessageType: merged

Reply via email to