Skip to content

write_logs() drops the queue when the length prefix ends flush against the end of the ring #86

Description

@novotimo

src/logging.c:write_logs() takes len_to_end from the read index as it stood
before the prefix, then subtracts LINEBUF_OFFSET from it. That is the distance
to the end of the ring only while the prefix itself does not wrap. When a record
begins at exactly TPX_LOGBUF_SIZE - LINEBUF_OFFSET, the prefix occupies the
last four bytes and the body starts at 0, so len_to_end comes out 0 rather
than the whole ring, ntowrite is MIN(0, linelen) and the write() loop
never runs. r_idx is then sitting on the body's first byte, the terminator
check fails, and the Log ring corrupt: line does not end where its length says
path resynchronizes read_idx onto write_idx, so the line and everything
queued behind it are discarded.

Reproduced with a copy of write_logs_returns_a_message_whose_header_wrapped
set to read_idx = write_idx = TPX_LOGBUF_SIZE - 4; it fails with that error
line in place of the message.

Before #61's fix the same input took the non-wrapping branch instead, leaving
r_idx at TPX_LOGBUF_SIZE and reading log_buf[65535], one past the array,
which sits in shared_t's tail padding and reads as '\0', so the line was
dropped silently. The out-of-bounds read is gone with that fix; the drop is not.

It needs a line to begin at one exact offset, so it is rare: for lines averaging
L bytes it is roughly one lap of the ring in L, which is an estimate from the
geometry rather than a measurement. It affects Debug and Release alike, and both
writes here are of the master's own making, so no worker input is needed to
reach it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions