From 5257efdc5b30212b62a9d68857dc8e66d0e1a863 Mon Sep 17 00:00:00 2001
From: OCHyams <orlando.hyams@sony.com>
Date: Wed, 9 Feb 2022 10:47:07 +0000
Subject: [PATCH] [cross-project-tests] XFAIL llgdb-tests when gdb can't read
 clang's DWARF

Tests in the `cross-project-tests/debuginfo-tests/llgdb-tests` directory run
gdb on non-darwin platforms. gdb versions less than 10.1 cannot parse the DWARF
v5 emitted by clang, and DWARF v5 is now the default, so these tests fail on
Linux with gdb versions less than 10.1. This patch lets us XFAIL the tests
under these conditions.

Add `gdb-clang-incompatibility` to the `available_features` in
`cross-project-tests/lit.cfg.py` when clang's default DWARF version is 5 or
greater and the gdb (if found) version is less than 10.1.

Discourse discussion:
https://llvm.discourse.group/t/gdb-10-1-cant-read-clangs-dwarf-v5/6035

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D118468
---
 .../debuginfo-tests/llgdb-tests/asan-blocks.c |  8 +--
 .../llgdb-tests/asan-deque.cpp                | 10 ++--
 .../debuginfo-tests/llgdb-tests/asan.c        |  2 +-
 .../llgdb-tests/nested-struct.cpp             |  1 +
 .../llgdb-tests/nrvo-string.cpp               |  2 +-
 .../debuginfo-tests/llgdb-tests/safestack.c   |  2 +-
 .../debuginfo-tests/llgdb-tests/sret.cpp      |  3 +-
 .../llgdb-tests/static-member-2.cpp           |  2 +-
 .../llgdb-tests/static-member.cpp             |  2 +-
 cross-project-tests/lit.cfg.py                | 49 +++++++++++++++++++
 10 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/asan-blocks.c b/cross-project-tests/debuginfo-tests/llgdb-tests/asan-blocks.c
index 33f44cd66590..e7536c733109 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/asan-blocks.c
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/asan-blocks.c
@@ -4,13 +4,15 @@
 // REQUIRES: !asan, system-darwin
 //           Zorg configures the ASAN stage2 bots to not build the asan
 //           compiler-rt. Only run this test on non-asanified configurations.
+// XFAIL: !system-darwin && gdb-clang-incompatibility
+
 void b();
 struct S {
   int a[8];
 };
 
 int f(struct S s, unsigned i) {
-  // DEBUGGER: break 17
+  // DEBUGGER: break 19
   // DEBUGGER: r
   // DEBUGGER: p s
   // CHECK: a = ([0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7)
@@ -20,7 +22,7 @@ int f(struct S s, unsigned i) {
 int main(int argc, const char **argv) {
   struct S s = {{0, 1, 2, 3, 4, 5, 6, 7}};
   if (f(s, 4) == 4) {
-    // DEBUGGER: break 27
+    // DEBUGGER: break 29
     // DEBUGGER: c
     // DEBUGGER: p s
     // CHECK: a = ([0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7)
@@ -32,7 +34,7 @@ int main(int argc, const char **argv) {
 void c() {}
 
 void b() {
-  // DEBUGGER: break 40
+  // DEBUGGER: break 42
   // DEBUGGER: c
   // DEBUGGER: p x
   // CHECK: 42
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/asan-deque.cpp b/cross-project-tests/debuginfo-tests/llgdb-tests/asan-deque.cpp
index f3f55aae0ff6..00fdf4cc440b 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/asan-deque.cpp
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/asan-deque.cpp
@@ -4,6 +4,8 @@
 //           Zorg configures the ASAN stage2 bots to not build the asan
 //           compiler-rt. Only run this test on non-asanified configurations.
 // UNSUPPORTED: apple-lldb-pre-1000
+// XFAIL: !system-darwin && gdb-clang-incompatibility
+
 #include <deque>
 
 struct A {
@@ -23,24 +25,24 @@ int main() {
   log.push_back(1234);
   log.push_back(56789);
   escape(log);
-  // DEBUGGER: break 25
+  // DEBUGGER: break 27
   while (!log.empty()) {
     auto record = log.front();
     log.pop_front();
     escape(log);
-    // DEBUGGER: break 30
+    // DEBUGGER: break 32
   }
 }
 
 // DEBUGGER: r
 
-// (at line 25)
+// (at line 27)
 // DEBUGGER: p log
 // CHECK: 1234
 // CHECK: 56789
 
 // DEBUGGER: c
 
-// (at line 30)
+// (at line 32)
 // DEBUGGER: p log
 // CHECK: 56789
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/asan.c b/cross-project-tests/debuginfo-tests/llgdb-tests/asan.c
index 96dffb348d43..3e9d601f5e96 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/asan.c
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/asan.c
@@ -3,7 +3,7 @@
 // REQUIRES: !asan
 //           Zorg configures the ASAN stage2 bots to not build the asan
 //           compiler-rt. Only run this test on non-asanified configurations.
-//
+// XFAIL: !system-darwin && gdb-clang-incompatibility
 
 struct S {
   int a[8];
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/nested-struct.cpp b/cross-project-tests/debuginfo-tests/llgdb-tests/nested-struct.cpp
index 7533e6a81518..08668d61d222 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/nested-struct.cpp
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/nested-struct.cpp
@@ -1,5 +1,6 @@
 // RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
 // RUN: %test_debuginfo %s %t.o
+// XFAIL: !system-darwin && gdb-clang-incompatibility
 // Radar 9440721
 // If debug info for my_number() is emitted outside function foo's scope
 // then a debugger may not be able to handle it. At least one version of
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/nrvo-string.cpp b/cross-project-tests/debuginfo-tests/llgdb-tests/nrvo-string.cpp
index 9b805c91c4e8..988c4ae2232a 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/nrvo-string.cpp
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/nrvo-string.cpp
@@ -5,7 +5,7 @@
 // RUN: %test_debuginfo %s %t.out
 // RUN: %clangxx -O1 -fno-exceptions %target_itanium_abi_host_triple %s -o %t.out -g
 // RUN: %test_debuginfo %s %t.out
-//
+// XFAIL: !system-darwin && gdb-clang-incompatibility
 // PR34513
 volatile int sideeffect = 0;
 void __attribute__((noinline)) stop() { sideeffect++; }
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/safestack.c b/cross-project-tests/debuginfo-tests/llgdb-tests/safestack.c
index cf3efc75239a..38636a5b8843 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/safestack.c
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/safestack.c
@@ -5,7 +5,7 @@
 //           Zorg configures the ASAN stage2 bots to not build the
 //           safestack compiler-rt.  Only run this test on
 //           non-asanified configurations.
-
+// XFAIL: !system-darwin && gdb-clang-incompatibility
 struct S {
   int a[8];
 };
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/sret.cpp b/cross-project-tests/debuginfo-tests/llgdb-tests/sret.cpp
index 640015fab40b..28f057b4e9b5 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/sret.cpp
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/sret.cpp
@@ -1,8 +1,9 @@
 // RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
 // RUN: %clangxx %target_itanium_abi_host_triple %t.o -o %t.out
 // RUN: %test_debuginfo %s %t.out
+// XFAIL: !system-darwin && gdb-clang-incompatibility
 // Radar 8775834
-// DEBUGGER: break 62
+// DEBUGGER: break 63
 // DEBUGGER: r
 // DEBUGGER: p a
 // CHECK: ${{[0-9]+}} =
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/static-member-2.cpp b/cross-project-tests/debuginfo-tests/llgdb-tests/static-member-2.cpp
index 4edb2b060f1a..8d65a8bb41b7 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/static-member-2.cpp
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/static-member-2.cpp
@@ -3,7 +3,7 @@
 // RUN: %test_debuginfo %s %t.out
 
 // FIXME: LLDB finds the wrong symbol for "C". rdar://problem/14933867
-// XFAIL: darwin
+// XFAIL: darwin, gdb-clang-incompatibility
 
 // DEBUGGER: delete breakpoints
 // DEBUGGER: break static-member.cpp:33
diff --git a/cross-project-tests/debuginfo-tests/llgdb-tests/static-member.cpp b/cross-project-tests/debuginfo-tests/llgdb-tests/static-member.cpp
index 1d8ad62c5b88..29dd84dc8325 100644
--- a/cross-project-tests/debuginfo-tests/llgdb-tests/static-member.cpp
+++ b/cross-project-tests/debuginfo-tests/llgdb-tests/static-member.cpp
@@ -1,7 +1,7 @@
 // RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -o %t -c
 // RUN: %clangxx %target_itanium_abi_host_triple %t -o %t.out
 // RUN: %test_debuginfo %s %t.out
-
+// XFAIL: !system-darwin && gdb-clang-incompatibility
 // DEBUGGER: delete breakpoints
 // DEBUGGER: break static-member.cpp:33
 // DEBUGGER: r
diff --git a/cross-project-tests/lit.cfg.py b/cross-project-tests/lit.cfg.py
index 51a6dd514a87..c4bb83dd1874 100644
--- a/cross-project-tests/lit.cfg.py
+++ b/cross-project-tests/lit.cfg.py
@@ -3,6 +3,7 @@ import platform
 import re
 import subprocess
 import sys
+from distutils.version import StrictVersion
 
 import lit.formats
 import lit.util
@@ -200,6 +201,54 @@ if platform.system() == 'Darwin':
         if apple_lldb_vers < 1000:
             config.available_features.add('apple-lldb-pre-1000')
 
+def get_gdb_version_string():
+  """Return gdb's version string, or None if gdb cannot be found or the
+  --version output is formatted unexpectedly.
+  """
+  # See if we can get a gdb version, e.g.
+  #   $ gdb --version
+  #   GNU gdb (GDB) 10.2
+  #   ...More stuff...
+  try:
+    gdb_vers_lines = subprocess.check_output(['gdb', '--version']).decode().splitlines()
+  except:
+    return None # We coudln't find gdb or something went wrong running it.
+  if len(gdb_vers_lines) < 1:
+    print("Unkown GDB version format (too few lines)", file=sys.stderr)
+    return None
+  string = gdb_vers_lines[0].strip().partition('GNU gdb (GDB) ')[2]
+  if len(string) == 0:
+    print("Unkown GDB version format", file=sys.stderr)
+    return None
+  return string
+
+def get_clang_default_dwarf_version_string(triple):
+  """Return the default dwarf version string for clang on this (host) platform
+  or None if we can't work it out.
+  """
+  # Get the flags passed by the driver and look for -dwarf-version.
+  cmd = f'{llvm_config.use_llvm_tool("clang")} -g -xc  -c - -v -### --target={triple}'
+  stderr = subprocess.run(cmd.split(), stderr=subprocess.PIPE).stderr.decode()
+  match = re.search('-dwarf-version=(\d+)', stderr)
+  if match is None:
+    print("Cannot determine default dwarf version", file=sys.stderr)
+    return None
+  return match.group(1)
+
+# Some cross-project-tests use gdb, but not all versions of gdb are compatible
+# with clang's dwarf. Add feature `gdb-clang-incompatibility` to signal that
+# there's an incompatibility between clang's default dwarf version for this
+# platform and the installed gdb version.
+dwarf_version_string = get_clang_default_dwarf_version_string(config.host_triple)
+gdb_version_string = get_gdb_version_string()
+if dwarf_version_string and gdb_version_string:
+  if int(dwarf_version_string) >= 5:
+    if StrictVersion(gdb_version_string) < StrictVersion('10.1'):
+      # Example for llgdb-tests, which use lldb on darwin but gdb elsewhere:
+      # XFAIL: !system-darwin && gdb-clang-incompatibility
+      config.available_features.add('gdb-clang-incompatibility')
+      print("XFAIL some tests: use gdb version >= 10.1 to restore test coverage", file=sys.stderr)
+
 llvm_config.feature_config(
     [('--build-mode', {'Debug|RelWithDebInfo': 'debug-info'})]
 )
-- 
GitLab