validate: Implement support to run tests inside gdb

Making debugging races leading to crashes easier to debug
This commit is contained in:
Thibault Saunier 2015-11-10 17:43:54 +01:00
parent 91d3e70098
commit 8899fd8dd1
2 changed files with 38 additions and 6 deletions

View file

@ -40,7 +40,7 @@ from utils import mkdir, Result, Colors, printc, DEFAULT_TIMEOUT, GST_SECOND, \
# The factor by which we increase the hard timeout when running inside
# Valgrind
VALGRIND_TIMEOUT_FACTOR = 20
GDB_TIMEOUT_FACTOR = VALGRIND_TIMEOUT_FACTOR = 20
# The error reported by valgrind when detecting errors
VALGRIND_ERROR_CODE = 20
@ -186,12 +186,19 @@ class Test(Loggable):
def set_result(self, result, message="", error=""):
self.debug("Setting result: %s (message: %s, error: %s)" % (result,
message, error))
if result is Result.TIMEOUT and self.options.debug is True:
pname = subprocess.check_output(("readlink -e /proc/%s/exe"
% self.process.pid).split(' ')).replace('\n', '')
raw_input("%sTimeout happened you can attach gdb doing: $gdb %s %d%s\n"
"Press enter to continue" % (Colors.FAIL, pname, self.process.pid,
Colors.ENDC))
if self.options.gdb:
printc("Timeout, you should process <ctrl>c to get into gdb",
Colors.FAIL)
# and wait here until gdb exits
self.process.communicate()
else:
pname = subprocess.check_output(("readlink -e /proc/%s/exe"
% self.process.pid).split(' ')).replace('\n', '')
raw_input("%sTimeout happened you can attach gdb doing: $gdb %s %d%s\n"
"Press enter to continue" % (Colors.FAIL, pname, self.process.pid,
Colors.ENDC))
self.result = result
self.message = message
@ -307,6 +314,12 @@ class Test(Loggable):
def get_valgrind_suppressions(self):
return [self.get_valgrind_suppression_file('data', 'gstvalidate.supp')]
def use_gdb(self):
if self.hard_timeout is not None:
self.hard_timeout *= GDB_TIMEOUT_FACTOR
self.timeout *= GDB_TIMEOUT_FACTOR
self.command = "gdb -ex run -ex quit --args %s" % self.command
def use_valgrind(self):
vglogsfile = self.logfile + '.valgrind'
self.extra_logfiles.append(vglogsfile)
@ -364,6 +377,9 @@ class Test(Loggable):
self.proc_env[var] = self.proc_env.get(var, '') + os.pathsep + value
self.add_env_variable(var, self.proc_env[var])
if self.options.gdb:
self.use_gdb()
if self.options.valgrind:
self.use_valgrind()

View file

@ -192,6 +192,7 @@ class LauncherConfig(Loggable):
self.long_limit = utils.LONG_TEST
self.config = None
self.valgrind = False
self.gdb = False
self.no_display = False
self.xunit_file = None
self.main_dir = utils.DEFAULT_MAIN_DIR
@ -230,6 +231,17 @@ class LauncherConfig(Loggable):
else:
self.output_dir = os.path.abspath(self.output_dir)
if self.gdb:
self.logsdir = "stdout"
self.debug = True
self.num_jobs = 1
try:
subprocess.check_output("gdb --help", shell=True)
except subprocess.CalledProcessError:
printc("Want to use gdb, but not avalaible on the system",
Colors.FAIL)
return False
# other output directories
if self.logsdir in ['stdout', 'stderr']:
# Allow -l stdout/stderr to work like -rl stdout/stderr
@ -403,6 +415,10 @@ Note that all testsuite should be inside python modules, so the directory should
parser.add_argument("-vg", "--valgrind", dest="valgrind",
action="store_true",
help="Run the tests inside Valgrind")
parser.add_argument("--gdb", dest="gdb",
action="store_true",
help="Run the tests inside gdb (implies"
" --output-dir=stdout and --jobs=1)")
parser.add_argument("-nd", "--no-display", dest="no_display",
action="store_true",
help="Run the tests without outputting graphics"