[PATCH] D62371: [llvm-symbolizer] Flush output on bad input

James Henderson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 24 01:33:01 PDT 2019


jhenderson created this revision.
jhenderson added reviewers: grimar, ruiu, rupprecht, dblaikie, ikudrin.
Herald added a project: LLVM.

One way of using llvm-symbolizer is to interactively within a process write a line from a parent process to llvm-symbolizer's stdin, and then read the output, then write the next line, read, etc. This worked as long as all the lines were good. However, this didn't work prior to this patch if any of the inputs were bad inputs, because the output is not flushed after a bad input, meaning the parent process is sat waiting for output, whilst llvm-symbolizer is sat waiting for input. This patch flushes the output after every invocation of symbolizeInput when reading from stdin. It also removes unnecessary flushing when llvm-symbolizer is not reading addresses from stdin, which should give a slight performance boost in these situations.


Repository:
  rL LLVM

https://reviews.llvm.org/D62371

Files:
  test/tools/llvm-symbolizer/Inputs/flush-output.py
  test/tools/llvm-symbolizer/flush-output.s
  tools/llvm-symbolizer/llvm-symbolizer.cpp


Index: tools/llvm-symbolizer/llvm-symbolizer.cpp
===================================================================
--- tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -246,7 +246,6 @@
   }
   if (ClOutputStyle == DIPrinter::OutputStyle::LLVM)
     outs() << "\n";
-  outs().flush();
 }
 
 int main(int argc, char **argv) {
@@ -291,8 +290,10 @@
     const int kMaxInputStringLength = 1024;
     char InputString[kMaxInputStringLength];
 
-    while (fgets(InputString, sizeof(InputString), stdin))
+    while (fgets(InputString, sizeof(InputString), stdin)) {
       symbolizeInput(InputString, Symbolizer, Printer);
+      outs().flush();
+    }
   } else {
     for (StringRef Address : ClInputAddresses)
       symbolizeInput(Address, Symbolizer, Printer);
Index: test/tools/llvm-symbolizer/flush-output.s
===================================================================
--- test/tools/llvm-symbolizer/flush-output.s
+++ test/tools/llvm-symbolizer/flush-output.s
@@ -0,0 +1,17 @@
+# REQUIRES: x86-registered-target
+
+## If a process spawns llvm-symbolizer, and wishes to feed it addresses one at a
+## time, llvm-symbolizer needs to flush its output after each input has been
+## processed or the parent process will not be able to read the output and may
+## deadlock. This test runs a script that simulates this situation for both a
+## a good and bad input.
+
+foo:
+    nop
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -g
+# RUN: %python %p/Inputs/flush-output.py llvm-symbolizer %t.o \
+# RUN:   | FileCheck %s
+
+# CHECK: flush-output.s:10
+# CHECK: bad
Index: test/tools/llvm-symbolizer/Inputs/flush-output.py
===================================================================
--- test/tools/llvm-symbolizer/Inputs/flush-output.py
+++ test/tools/llvm-symbolizer/Inputs/flush-output.py
@@ -0,0 +1,14 @@
+from __future__ import print_function
+import subprocess
+import sys
+
+# Pass -f=none and --output-style=GNU to get only one line of output per input.
+cmd = subprocess.Popen([sys.argv[1],
+                        '--obj=' + sys.argv[2],
+                        '-f=none',
+                        '--output-style=GNU'],
+                        stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+cmd.stdin.write('0\n')
+print(cmd.stdout.readline())
+cmd.stdin.write('bad\n')
+print(cmd.stdout.readline())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62371.201143.patch
Type: text/x-patch
Size: 2389 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190524/47c764e2/attachment.bin>


More information about the llvm-commits mailing list