Commit Graph

3 Commits

Author SHA1 Message Date
Prarit Bhargava 1f01c63945 scripts: handle BrokenPipeError for python scripts
JIRA: https://issues.redhat.com/browse/RHEL-25415

commit 87c7ee67deb7fce9951a5f9d80641138694aad17
Author: Masahiro Yamada <masahiroy@kernel.org>
Date:   Thu Jan 12 11:30:06 2023 +0900

    scripts: handle BrokenPipeError for python scripts

    In the follow-up of commit fb3041d61f68 ("kbuild: fix SIGPIPE error
    message for AR=gcc-ar and AR=llvm-ar"), Kees Cook pointed out that
    tools should _not_ catch their own SIGPIPEs [1] [2].

    Based on his feedback, LLVM was fixed [3].

    However, Python's default behavior is to show noisy bracktrace when
    SIGPIPE is sent. So, scripts written in Python are basically in the
    same situation as the buggy llvm tools.

    Example:

      $ make -s allnoconfig
      $ make -s allmodconfig
      $ scripts/diffconfig .config.old .config | head -n1
      -ALIX n
      Traceback (most recent call last):
        File "/home/masahiro/linux/scripts/diffconfig", line 132, in <module>
          main()
        File "/home/masahiro/linux/scripts/diffconfig", line 130, in main
          print_config("+", config, None, b[config])
        File "/home/masahiro/linux/scripts/diffconfig", line 64, in print_config
          print("+%s %s" % (config, new_value))
      BrokenPipeError: [Errno 32] Broken pipe

    Python documentation [4] notes how to make scripts die immediately and
    silently:

      """
      Piping output of your program to tools like head(1) will cause a
      SIGPIPE signal to be sent to your process when the receiver of its
      standard output closes early. This results in an exception like
      BrokenPipeError: [Errno 32] Broken pipe. To handle this case,
      wrap your entry point to catch this exception as follows:

        import os
        import sys

        def main():
            try:
                # simulate large output (your code replaces this loop)
                for x in range(10000):
                    print("y")
                # flush output here to force SIGPIPE to be triggered
                # while inside this try block.
                sys.stdout.flush()
            except BrokenPipeError:
                # Python flushes standard streams on exit; redirect remaining output
                # to devnull to avoid another BrokenPipeError at shutdown
                devnull = os.open(os.devnull, os.O_WRONLY)
                os.dup2(devnull, sys.stdout.fileno())
                sys.exit(1)  # Python exits with error code 1 on EPIPE

        if __name__ == '__main__':
            main()

      Do not set SIGPIPE’s disposition to SIG_DFL in order to avoid
      BrokenPipeError. Doing that would cause your program to exit
      unexpectedly whenever any socket connection is interrupted while
      your program is still writing to it.
      """

    Currently, tools/perf/scripts/python/intel-pt-events.py seems to be the
    only script that fixes the issue that way.

    tools/perf/scripts/python/compaction-times.py uses another approach
    signal.signal(signal.SIGPIPE, signal.SIG_DFL) but the Python
    documentation clearly says "Don't do it".

    I cannot fix all Python scripts since there are so many.
    I fixed some in the scripts/ directory.

    [1]: https://lore.kernel.org/all/202211161056.1B9611A@keescook/
    [2]: https://github.com/llvm/llvm-project/issues/59037
    [3]: 4787efa380
    [4]: https://docs.python.org/3/library/signal.html#note-on-sigpipe

    Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
    Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
    Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>

Signed-off-by: Prarit Bhargava <prarit@redhat.com>
2024-03-20 09:42:44 -04:00
Masahiro Yamada 074075aea2 scripts/clang-tools: switch explicitly to Python 3
For the same reason as commit 51839e29cb ("scripts: switch explicitly
to Python 3"), switch some more scripts, which I tested and confirmed
working on Python 3.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Acked-by: Nathan Chancellor <nathan@kernel.org>
2021-02-03 09:01:08 +09:00
Nathan Huckleberry 6ad7cbc015 Makefile: Add clang-tidy and static analyzer support to makefile
This patch adds clang-tidy and the clang static-analyzer as make
targets. The goal of this patch is to make static analysis tools
usable and extendable by any developer or researcher who is familiar
with basic c++.

The current static analysis tools require intimate knowledge of the
internal workings of the static analysis. Clang-tidy and the clang
static analyzers expose an easy to use api and allow users unfamiliar
with clang to write new checks with relative ease.

===Clang-tidy===

Clang-tidy is an easily extendable 'linter' that runs on the AST.
Clang-tidy checks are easy to write and understand. A check consists of
two parts, a matcher and a checker. The matcher is created using a
domain specific language that acts on the AST
(https://clang.llvm.org/docs/LibASTMatchersReference.html).  When AST
nodes are found by the matcher a callback is made to the checker. The
checker can then execute additional checks and issue warnings.

Here is an example clang-tidy check to report functions that have calls
to local_irq_disable without calls to local_irq_enable and vice-versa.
Functions flagged with __attribute((annotation("ignore_irq_balancing")))
are ignored for analysis. (https://reviews.llvm.org/D65828)

===Clang static analyzer===

The clang static analyzer is a more powerful static analysis tool that
uses symbolic execution to find bugs. Currently there is a check that
looks for potential security bugs from invalid uses of kmalloc and
kfree. There are several more general purpose checks that are useful for
the kernel.

The clang static analyzer is well documented and designed to be
extensible.
(https://clang-analyzer.llvm.org/checker_dev_manual.html)
(https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf)

The main draw of the clang tools is how accessible they are. The clang
documentation is very nice and these tools are built specifically to be
easily extendable by any developer. They provide an accessible method of
bug-finding and research to people who are not overly familiar with the
kernel codebase.

Signed-off-by: Nathan Huckleberry <nhuck@google.com>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2020-08-27 00:44:33 +09:00