Use JSON format of llvm-symbolizer

The LLVM webpage of llvm-symbolizer[1] demonstrates outputs in JSON
format as the machine readable format.

[1]: https://llvm.org/docs/CommandGuide/llvm-symbolizer.html

Bug: None
Test: stack with a local stack trace
Test: python3 symbol.py
Change-Id: Iee6b8805510f5f8569b0a454849fc2e4ffb6d510
diff --git a/scripts/symbol.py b/scripts/symbol.py
index f4c2395..64242ea 100755
--- a/scripts/symbol.py
+++ b/scripts/symbol.py
@@ -20,6 +20,7 @@
 """
 
 import atexit
+import json
 import glob
 import os
 import platform
@@ -292,7 +293,7 @@
     return None
 
   cmd = [ToolPath("llvm-symbolizer"), "--functions", "--inlines",
-      "--demangle", "--obj=" + symbols, "--output-style=GNU"]
+      "--demangle", "--obj=" + symbols, "--output-style=JSON"]
   child = _PIPE_ADDR2LINE_CACHE.GetProcess(cmd)
 
   for addr in addrs:
@@ -300,20 +301,12 @@
       child.stdin.write("0x%s\n" % addr)
       child.stdin.flush()
       records = []
-      first = True
-      while True:
-        symbol = child.stdout.readline().strip()
-        if not symbol:
-          break
-        location = child.stdout.readline().strip()
-        records.append((symbol, location))
-        if first:
-          # Write a blank line as a sentinel so we know when to stop
-          # reading inlines from the output.
-          # The blank line will cause llvm-symbolizer to emit a blank line.
-          child.stdin.write("\n")
-          child.stdin.flush()
-          first = False
+      json_result = json.loads(child.stdout.readline().strip())
+      for symbol in json_result["Symbol"]:
+        function_name = symbol["FunctionName"]
+        # GNU style location: file_name:line_num
+        location = ("%s:%s" % (symbol["FileName"], symbol["Line"]))
+        records.append((function_name, location))
     except IOError as e:
       # Remove the / in front of the library name to match other output.
       records = [(None, lib[1:] + "  ***Error: " + str(e))]