Enhance fflush error diagnostics
authorDmitry V. Levin <ldv@altlinux.org>
Sun, 6 Aug 2017 11:26:52 +0000 (11:26 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 6 Aug 2017 11:26:52 +0000 (11:26 +0000)
* strace.c (flush_tcp_output): New function.
(line_ended, droptcb, print_event_exit): Use it to flush tcp->outf.
* tests/fflush.c: New file.
* tests/fflush.test: New test.
* tests/Makefile.am (MISC_TESTS): Add it.
* tests/.gitignore: Add fflush.
* tests/pure_executables.list: Likewise.

strace.c
tests/.gitignore
tests/Makefile.am
tests/fflush.c [new file with mode: 0644]
tests/fflush.test [new file with mode: 0755]
tests/pure_executables.list

index b0d9b88ae7f2cbab8c307afe380e04c634a09f96..5a2adf02c8724e3d797683ead4b7219c648b5360 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -591,6 +591,7 @@ tvprintf(const char *const fmt, va_list args)
        if (current_tcp) {
                int n = vfprintf(current_tcp->outf, fmt, args);
                if (n < 0) {
+                       /* very unlikely due to vfprintf buffering */
                        if (current_tcp->outf != stderr)
                                perror_msg("%s", outfname);
                } else
@@ -620,6 +621,7 @@ tprints(const char *str)
                        current_tcp->curcol += strlen(str);
                        return;
                }
+               /* very unlikely due to fputs_unlocked buffering */
                if (current_tcp->outf != stderr)
                        perror_msg("%s", outfname);
        }
@@ -646,12 +648,19 @@ tprintf_comment(const char *fmt, ...)
        va_end(args);
 }
 
+static void
+flush_tcp_output(const struct tcb *const tcp)
+{
+       if (fflush(tcp->outf) && tcp->outf != stderr)
+               perror_msg("%s", outfname);
+}
+
 void
 line_ended(void)
 {
        if (current_tcp) {
                current_tcp->curcol = 0;
-               fflush(current_tcp->outf);
+               flush_tcp_output(current_tcp);
        }
        if (printing_tcp) {
                printing_tcp->curcol = 0;
@@ -861,7 +870,7 @@ droptcb(struct tcb *tcp)
                } else {
                        if (printing_tcp == tcp && tcp->curcol != 0)
                                fprintf(tcp->outf, " <detached ...>\n");
-                       fflush(tcp->outf);
+                       flush_tcp_output(tcp);
                }
        }
 
@@ -2240,7 +2249,7 @@ print_event_exit(struct tcb *tcp)
            && printing_tcp->curcol != 0) {
                current_tcp = printing_tcp;
                tprints(" <unfinished ...>\n");
-               fflush(printing_tcp->outf);
+               flush_tcp_output(printing_tcp);
                printing_tcp->curcol = 0;
                current_tcp = tcp;
        }
index e8f5ec6051e9133f759353b982e12b72f2222987..ad80c53b2df9baf8f56fecca61077432a68bfb54 100644 (file)
@@ -66,6 +66,7 @@ fchownat
 fcntl
 fcntl64
 fdatasync
+fflush
 file_handle
 file_ioctl
 filter-unavailable
index 717e03705d315317ded255d7852704e794de44d4..6d3849292cdc62b9a53dcbd60071a31a65b37163 100644 (file)
@@ -256,6 +256,7 @@ MISC_TESTS = \
        detach-sleeping.test \
        detach-stopped.test \
        filter-unavailable.test \
+       fflush.test \
        get_regs.test \
        interactive_block.test \
        ksysent.test \
diff --git a/tests/fflush.c b/tests/fflush.c
new file mode 100644 (file)
index 0000000..84a62ec
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Check fflush error diagnostics.
+ *
+ * Copyright (c) 2017 The strace developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(void)
+{
+       errno = ENOSPC;
+       printf("%s: /dev/full: %m\n", getenv("STRACE_EXE") ?: "strace");
+       return 0;
+}
diff --git a/tests/fflush.test b/tests/fflush.test
new file mode 100755 (executable)
index 0000000..c0f4e3f
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/sh -efu
+#
+# Check fflush error diagnostics.
+#
+# Copyright (c) 2011-2017 The strace developers.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+args="-o /dev/full -e trace=none $args"
+
+$STRACE $args > "$EXP" 2> "$LOG" || {
+       msg="$STRACE $args failed with code $?"
+       cat "$LOG" >&2
+       fail_ "$msg"
+}
+
+match_diff "$LOG" "$EXP"
index fddf69106e123d2ab1a3d596a9af5f2f9a88263c..3d05531c65c61de0b2e4fe92cd22c28f1a4da050 100755 (executable)
@@ -50,6 +50,7 @@ fchownat
 fcntl
 fcntl64
 fdatasync
+fflush
 file_handle
 file_ioctl
 finit_module