[PATCH] D124607: Add an error message to the default SIGPIPE handler

Damian Malarczyk via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 1 03:29:05 PDT 2022


dmcyk added a comment.

Thanks for trying it out @nemanjai, I can reproduce this locally indeed.

In D124607#3536577 <https://reviews.llvm.org/D124607#3536577>, @nemanjai wrote:

> In D124607#3536329 <https://reviews.llvm.org/D124607#3536329>, @jhenderson wrote:
>
>> Both llvm-symbolizer and llvm-cxxfilt, if called without positional arguments, are run interactively, essentially taking a line of input then writing some output before waiting for more input. This would allow you to force output to be written (by writing to stdin) after the pipe has been closed. Maybe that'll solve the issue, although I'm not sure I understand why the python script doesn't work in its current form: llvm-nm should try to write many bytes of output (> 1 byte), but the pipe is closed after the very first byte is written. Before going and changing the script, I'd like to understand whether this statement is actually true, and if so, why:
>>
>>> That does not appear to be enough. You can either run a tool that runs longer or run llvm-nm with something that produces more output.
>
> If you have an idea for how I can verify this, I'd love to help. Without any tracing/debugging as proof, the way I guess I reason about it is that the process writes to the pipe asynchronously without regard to how much is read from the pipe. So if the write finishes before the pipe is closed, it finishes. Namely, reading a single byte from the pipe rather than all of them does not prevent all the bytes from being written to it before it is closed.
> As I said, I am not sure why the test only works when there is more output. All I know for sure is that I've tried it on multiple machines with a shared library build with the same results.

I think you're right about llvm-nm being able to write out all the bytes before the pipe is closed. Kernel buffers writes to a pipe, if nm's output doesn't exceed the buffer size it may finish running before stdout is closed.

In my system it looks like the kernel's pipe buffer fits 65k bytes, here's how I tested it:

  $ cat sigtest.c
  #include <signal.h>
  #include <sys/signal.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <stdio.h>
  
  void Action(int sig, siginfo_t* info, void* context) {
    fprintf(stderr, "sig action\n");
    exit(78);
  }
  
  int main(int argc, char** argv) {
    struct sigaction orig;
    struct sigaction handler;
    handler.sa_flags = SA_SIGINFO;
    handler.sa_sigaction = Action;
    sigaction(SIGPIPE, &handler, &orig);
  
    int limit = 1000;
    if (argc > 1) {
      limit = atoi(argv[1]);
    }
    for (int i = 0; i < limit; ++i) {
      write(1, "a", 1);
      fprintf(stderr, "wrote nth: %d\n", i + 1);
    }
  }
  
  $ cat test.py
  import subprocess
  import sys
  import time
  
  with subprocess.Popen([sys.argv[1], sys.argv[2]], stdout=subprocess.PIPE) as process:
    time.sleep(5);
    print("- finished sleep")
    process.stdout.read(1)
    process.stdout.close()
  
  print("- exit: ", process.returncode)
  sys.exit(process.returncode)
  $ clang sigtest.c
  $ python3 test.py $PWD/a.out 65536
  wrote nth: 65535
  wrote nth: 65536
  - finished sleep
  - exit:  0

This finishes writing all the bytes before the first byte is even read and always exits with a 0 code.
But when I bump the number of bytes it hangs trying to write the 65537th byte, sometimes it still manages to write it before the pipe is closed:

  $ python3 test.py $PWD/a.out 65537
  wrote nth: 65535
  wrote nth: 65536
  - finished sleep
  wrote nth: 65537
  - exit:  0

and sometimes stdout is closed faster:

  $ python3 test.py $PWD/a.out 65537
  wrote nth: 65536
  - finished sleep
  sig action
  - exit:  78

llvm-nm won't get the signal without a guarantee that stdout is closed before it tries to write to it, so I've moved the test case to use llvm-cxxfilt. Thanks for the tip @jhenderson.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124607/new/

https://reviews.llvm.org/D124607



More information about the llvm-commits mailing list