I will partially revert commit 44d0532

Denys Vlasenko dvlasenk at redhat.com
Tue Jan 24 09:10:05 UTC 2012


The commit was:

"strace.c (verror_msg): Rewrite without use of heap memory allocation"

it replaced "malloc + one fprintf + free" with "three fprintf's".

I guess it's my fault that I did not add a comment which explains
that one fprintf was used on purpose: we want to (attempt to)
send entire message as one write() call. Since stderr is unbuffered,
separate fprintf's to it always result in separate writes,
they are not coalesced. If we aren't the only program which
writes to this particular stderr, this may result in interleaved
messages.

Since this function is not performance critical, I guess
it's ok to make it less efficient.

I propose the following version:


static void verror_msg(int err_no, const char *fmt, va_list p)
{
         char *msg;

         fflush(NULL);

         /* We want to print entire message with single fprintf to ensure
          * message integrity if stderr is shared with other programs.
          * Thus we use vasprintf + single fprintf.
          */
         msg = NULL;
         vasprintf(&msg, fmt, p);
         if (msg) {
                 if (err_no)
                         fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
                 else
                         fprintf(stderr, "%s: %s\n", progname, msg);
                 free(msg);
         } else {
                 /* malloc in vasprintf failed, try it without malloc */
                 fprintf(stderr, "%s: ", progname);
                 vfprintf(stderr, fmt, p);
                 if (err_no)
                         fprintf(stderr, ": %s\n", strerror(err_no));
                 else
                         putc('\n', stderr);
         }
         /* We don't switch stderr to buffered, thus fprintf(stderr)
          * always flushes its output and this is not necessary: */
         /* fflush(stderr); */
}


-- 
vda




More information about the Strace-devel mailing list