sanitycheck: enable valgrind checking using an option
Enable valgrind using --enable-valgrind option and fix reporting. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
7358bd342a
commit
c1ea45280b
1 changed files with 38 additions and 26 deletions
|
@ -203,6 +203,7 @@ import logging
|
||||||
|
|
||||||
|
|
||||||
hw_map_local = threading.Lock()
|
hw_map_local = threading.Lock()
|
||||||
|
report_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
log_format = "%(levelname)s %(name)s::%(module)s.%(funcName)s():%(lineno)d: %(message)s"
|
log_format = "%(levelname)s %(name)s::%(module)s.%(funcName)s():%(lineno)d: %(message)s"
|
||||||
|
@ -522,7 +523,6 @@ class BinaryHandler(Handler):
|
||||||
"""
|
"""
|
||||||
super().__init__(instance, type_str)
|
super().__init__(instance, type_str)
|
||||||
|
|
||||||
self.valgrind = False
|
|
||||||
self.terminated = False
|
self.terminated = False
|
||||||
|
|
||||||
def try_kill_process_by_pid(self):
|
def try_kill_process_by_pid(self):
|
||||||
|
@ -566,12 +566,14 @@ class BinaryHandler(Handler):
|
||||||
else:
|
else:
|
||||||
command = [self.binary]
|
command = [self.binary]
|
||||||
|
|
||||||
if self.valgrind and shutil.which("valgrind"):
|
run_valgrind = False
|
||||||
|
if options.enable_valgrind and shutil.which("valgrind"):
|
||||||
command = ["valgrind", "--error-exitcode=2",
|
command = ["valgrind", "--error-exitcode=2",
|
||||||
"--leak-check=full",
|
"--leak-check=full",
|
||||||
"--suppressions="+ZEPHYR_BASE+"/scripts/valgrind.supp",
|
"--suppressions="+ZEPHYR_BASE+"/scripts/valgrind.supp",
|
||||||
"--log-file="+self.build_dir+"/valgrind.log"
|
"--log-file="+self.build_dir+"/valgrind.log"
|
||||||
] + command
|
] + command
|
||||||
|
run_valgrind = True
|
||||||
|
|
||||||
verbose("Spawning process: " +
|
verbose("Spawning process: " +
|
||||||
" ".join(shlex.quote(word) for word in command) + os.linesep +
|
" ".join(shlex.quote(word) for word in command) + os.linesep +
|
||||||
|
@ -605,17 +607,22 @@ class BinaryHandler(Handler):
|
||||||
|
|
||||||
subprocess.call(["stty", "sane"])
|
subprocess.call(["stty", "sane"])
|
||||||
self.instance.results = harness.tests
|
self.instance.results = harness.tests
|
||||||
|
|
||||||
if not self.terminated and self.returncode != 0:
|
if not self.terminated and self.returncode != 0:
|
||||||
#When a process is killed, the default handler returns 128 + SIGTERM
|
#When a process is killed, the default handler returns 128 + SIGTERM
|
||||||
#so in that case the return code itself is not meaningful
|
#so in that case the return code itself is not meaningful
|
||||||
self.set_state("failed", handler_time)
|
self.set_state("failed", handler_time)
|
||||||
self.instance.reason = "Handler error"
|
self.instance.reason = "Handler Error"
|
||||||
|
elif run_valgrind and self.returncode == 2:
|
||||||
|
self.set_state("failed", handler_time)
|
||||||
|
self.instance.reason = "Valgrind error"
|
||||||
elif harness.state:
|
elif harness.state:
|
||||||
self.set_state(harness.state, handler_time)
|
self.set_state(harness.state, handler_time)
|
||||||
else:
|
else:
|
||||||
self.set_state("timeout", handler_time)
|
self.set_state("timeout", handler_time)
|
||||||
self.instance.reason = "Handler timeout"
|
self.instance.reason = "Handler timeout"
|
||||||
|
|
||||||
|
|
||||||
self.record(harness)
|
self.record(harness)
|
||||||
|
|
||||||
class DeviceHandler(Handler):
|
class DeviceHandler(Handler):
|
||||||
|
@ -796,7 +803,6 @@ class DeviceHandler(Handler):
|
||||||
if c not in harness.tests:
|
if c not in harness.tests:
|
||||||
harness.tests[c] = "BLOCK"
|
harness.tests[c] = "BLOCK"
|
||||||
|
|
||||||
|
|
||||||
handler_time = time.time() - start_time
|
handler_time = time.time() - start_time
|
||||||
|
|
||||||
self.instance.results = harness.tests
|
self.instance.results = harness.tests
|
||||||
|
@ -1737,7 +1743,6 @@ class CMake():
|
||||||
msg = "Finished building %s for %s" %(self.source_dir, self.platform.name)
|
msg = "Finished building %s for %s" %(self.source_dir, self.platform.name)
|
||||||
|
|
||||||
self.instance.status = "passed"
|
self.instance.status = "passed"
|
||||||
self.instance.reason = ""
|
|
||||||
results = {'msg': msg, "returncode": p.returncode, "instance": self.instance}
|
results = {'msg': msg, "returncode": p.returncode, "instance": self.instance}
|
||||||
|
|
||||||
if out:
|
if out:
|
||||||
|
@ -1988,7 +1993,6 @@ class ProjectBuilder(FilterBuilder):
|
||||||
verbose("run test: %s" %self.instance.name)
|
verbose("run test: %s" %self.instance.name)
|
||||||
self.run()
|
self.run()
|
||||||
self.instance.status, _ = self.instance.handler.get_state()
|
self.instance.status, _ = self.instance.handler.get_state()
|
||||||
self.instance.reason = ""
|
|
||||||
pipeline.put({
|
pipeline.put({
|
||||||
"op": "report",
|
"op": "report",
|
||||||
"test": self.instance,
|
"test": self.instance,
|
||||||
|
@ -1999,7 +2003,22 @@ class ProjectBuilder(FilterBuilder):
|
||||||
|
|
||||||
# Report results and output progress to screen
|
# Report results and output progress to screen
|
||||||
elif op == "report":
|
elif op == "report":
|
||||||
self.report_out()
|
with report_lock:
|
||||||
|
self.report_out()
|
||||||
|
|
||||||
|
def log_info_file(self, instance):
|
||||||
|
|
||||||
|
build_dir = instance.build_dir
|
||||||
|
h_log = "{}/handler.log".format(build_dir)
|
||||||
|
b_log = "{}/build.log".format(build_dir)
|
||||||
|
v_log = "{}/valgrind.log".format(build_dir)
|
||||||
|
|
||||||
|
if os.path.exists(v_log) and "Valgrind" in instance.reason:
|
||||||
|
log_info("{}".format(v_log))
|
||||||
|
elif os.path.exists(h_log):
|
||||||
|
log_info("{}".format(h_log))
|
||||||
|
else:
|
||||||
|
log_info("{}".format(b_log))
|
||||||
|
|
||||||
def report_out(self):
|
def report_out(self):
|
||||||
total_tests_width = len(str(self.suite.total_tests))
|
total_tests_width = len(str(self.suite.total_tests))
|
||||||
|
@ -2012,25 +2031,17 @@ class ProjectBuilder(FilterBuilder):
|
||||||
status = COLOR_RED + "FAILED " + COLOR_NORMAL + instance.reason
|
status = COLOR_RED + "FAILED " + COLOR_NORMAL + instance.reason
|
||||||
else:
|
else:
|
||||||
info(
|
info(
|
||||||
"{:<25} {:<50} {}FAILED{}: {}".format(
|
"\n{:<25} {:<50} {}FAILED{}: {}".format(
|
||||||
instance.platform.name,
|
instance.platform.name,
|
||||||
instance.testcase.name,
|
instance.testcase.name,
|
||||||
COLOR_RED,
|
COLOR_RED,
|
||||||
COLOR_NORMAL,
|
COLOR_NORMAL,
|
||||||
instance.reason), False)
|
instance.reason), False)
|
||||||
|
if not VERBOSE:
|
||||||
# FIXME
|
self.log_info_file(instance)
|
||||||
h_log = "{}/handler.log".format(instance.build_dir)
|
|
||||||
b_log = "{}/build.log".format(instance.build_dir)
|
|
||||||
if os.path.exists(h_log):
|
|
||||||
log_info("{}".format(h_log))
|
|
||||||
else:
|
|
||||||
log_info("{}".format(b_log))
|
|
||||||
|
|
||||||
elif instance.status == "skipped":
|
elif instance.status == "skipped":
|
||||||
self.suite.total_skipped += 1
|
self.suite.total_skipped += 1
|
||||||
status = COLOR_YELLOW + "SKIPPED" + COLOR_NORMAL
|
status = COLOR_YELLOW + "SKIPPED" + COLOR_NORMAL
|
||||||
|
|
||||||
else:
|
else:
|
||||||
status = COLOR_GREEN + "PASSED" + COLOR_NORMAL
|
status = COLOR_GREEN + "PASSED" + COLOR_NORMAL
|
||||||
|
|
||||||
|
@ -2053,13 +2064,7 @@ class ProjectBuilder(FilterBuilder):
|
||||||
instance.testcase.name, status, more_info))
|
instance.testcase.name, status, more_info))
|
||||||
|
|
||||||
if instance.status in ["failed", "timeout"]:
|
if instance.status in ["failed", "timeout"]:
|
||||||
h_log = "{}/handler.log".format(instance.build_dir)
|
self.log_info_file(instance)
|
||||||
b_log = "{}/build.log".format(instance.build_dir)
|
|
||||||
if os.path.exists(h_log):
|
|
||||||
log_info("{}".format(h_log))
|
|
||||||
else:
|
|
||||||
log_info("{}".format(b_log))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
sys.stdout.write("\rtotal complete: %s%4d/%4d%s %2d%% skipped: %s%4d%s, failed: %s%4d%s" % (
|
sys.stdout.write("\rtotal complete: %s%4d/%4d%s %2d%% skipped: %s%4d%s, failed: %s%4d%s" % (
|
||||||
COLOR_GREEN,
|
COLOR_GREEN,
|
||||||
|
@ -3342,6 +3347,13 @@ structure in the main Zephyr tree: boards/<arch>/<board_name>/""")
|
||||||
NOTE: west-flash must be enabled to use this option.
|
NOTE: west-flash must be enabled to use this option.
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--enable-valgrind", action="store_true",
|
||||||
|
help="""Run binary through valgrind and check for several memory access
|
||||||
|
errors." Valgrind needs to be installed on the host. This option only
|
||||||
|
works with host binaries such as those generated for the native_posix
|
||||||
|
configuration.
|
||||||
|
""")
|
||||||
|
|
||||||
parser.add_argument("--enable-coverage", action="store_true",
|
parser.add_argument("--enable-coverage", action="store_true",
|
||||||
help="Enable code coverage using gcov.")
|
help="Enable code coverage using gcov.")
|
||||||
|
@ -3378,7 +3390,7 @@ def log_info(filename):
|
||||||
log_file.write(data)
|
log_file.write(data)
|
||||||
info("{:-^100}".format(filename))
|
info("{:-^100}".format(filename))
|
||||||
else:
|
else:
|
||||||
info("\tsee: " + COLOR_YELLOW + filename + COLOR_NORMAL)
|
info("\n\tsee: " + COLOR_YELLOW + filename + COLOR_NORMAL)
|
||||||
|
|
||||||
def size_report(sc):
|
def size_report(sc):
|
||||||
info(sc.filename)
|
info(sc.filename)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue