summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Bettis <jbettis@google.com>2023-04-14 13:39:12 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-14 23:32:18 +0000
commit69a9a9ff9abf61a7bc082eec80eca7fb2d12eb73 (patch)
tree2dfc4500bc2ba53b3b4b22c83d92df469cf40f59
parent4f561a604d77fb53fb6eb1865627d265ff742584 (diff)
downloadchrome-ec-69a9a9ff9abf61a7bc082eec80eca7fb2d12eb73.tar.gz
util: Add new utility to find non-exec lines
Add a new utility that reads one or more lcov files, and reads each executable line from that file, and then tries to verify if that line is actually executable code or not. This should help when playing whack-a-mole with strange pre-processor off-by-one errors. BRANCH=None BUG=b:272518464 TEST=Ran it on a known bad commit Change-Id: I89b43f73e59f14854b45855322ada626146658b6 Signed-off-by: Jeremy Bettis <jbettis@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4426796 Commit-Queue: Jeremy Bettis <jbettis@chromium.org> Auto-Submit: Jeremy Bettis <jbettis@chromium.org> Tested-by: Jeremy Bettis <jbettis@chromium.org> Reviewed-by: Tristan Honscheid <honscheid@google.com>
-rwxr-xr-xutil/find_non_exec_lines.py62
1 files changed, 62 insertions, 0 deletions
diff --git a/util/find_non_exec_lines.py b/util/find_non_exec_lines.py
new file mode 100755
index 0000000000..e88d3f61ff
--- /dev/null
+++ b/util/find_non_exec_lines.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Read lcov files, and find lines that are probably not executable.
+
+Example run:
+zmake build --coverage -a && \
+./util/find_non_exec_lines.py build/zephyr/all_builds.info && \
+echo SUCCESS
+"""
+
+import re
+import sys
+
+
+BAD_COVERAGE = re.compile(r"^$|\*/\s*$")
+
+
+def main() -> int:
+ """Read lcov files, and find lines that are probably not executable."""
+ exit_code = 0
+ for input_file in sys.argv:
+ with open(input_file, encoding="utf-8") as lcov:
+ active_file = None
+ active_line = 0
+ active_name = ""
+ for line in lcov:
+ line = line.strip()
+ if line.startswith("SF:"):
+ if active_file:
+ active_file.close()
+ active_file = None
+ active_line = 0
+ active_name = line[3:]
+ # There are several files in zephyr that have odd coverage
+ # but it seems consistent.
+ if not "src/third_party/zephyr" in active_name:
+ active_file = open( # pylint: disable=R1732
+ active_name, encoding="utf-8"
+ )
+ if active_file and line.startswith("DA:"):
+ target_line = int(line[3:].split(",", 1)[0])
+ target = "NO SUCH LINE\n"
+ while target and target_line > active_line:
+ target = active_file.readline()
+ active_line += 1
+ if target and target_line == active_line:
+ target = target.strip()
+ if BAD_COVERAGE.match(target):
+ print(f"{active_name}:{active_line}={target}")
+ exit_code = 1
+ if active_file:
+ active_file.close()
+ active_file = None
+
+ return exit_code
+
+
+if __name__ == "__main__":
+ sys.exit(main()) # next section explains the use of sys.exit