mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
validate: launcher: Add support for lldb
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7452>
This commit is contained in:
parent
1b5a093b96
commit
0d24821167
3 changed files with 93 additions and 15 deletions
|
@ -79,6 +79,63 @@ EXITING_SIGNALS.update({(v, k) for k, v in EXITING_SIGNALS.items()})
|
|||
|
||||
|
||||
CI_ARTIFACTS_URL = os.environ.get('CI_ARTIFACTS_URL')
|
||||
DEBUGGER = None
|
||||
|
||||
|
||||
def get_debugger():
|
||||
global DEBUGGER
|
||||
if DEBUGGER is not None:
|
||||
return DEBUGGER
|
||||
|
||||
gdb = shutil.which('gdb')
|
||||
if gdb:
|
||||
DEBUGGER = GDBDebugger(gdb)
|
||||
else:
|
||||
lldb = shutil.which('lldb')
|
||||
DEBUGGER = LLDBDebugger(lldb)
|
||||
|
||||
return DEBUGGER
|
||||
|
||||
|
||||
class Debugger:
|
||||
def __init__(self, executable):
|
||||
self.executable = executable
|
||||
|
||||
def get_args(self, args, non_stop) -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_attach_args(self, pid):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class GDBDebugger(Debugger):
|
||||
def get_args(self, args, non_stop) -> list:
|
||||
if non_stop:
|
||||
return [
|
||||
self.executable,
|
||||
"-ex",
|
||||
"run",
|
||||
"-ex",
|
||||
"bt",
|
||||
"-ex",
|
||||
"quit",
|
||||
"--args",
|
||||
] + args
|
||||
else:
|
||||
return [self.executable, "--args"] + args
|
||||
|
||||
def get_attach_args(self, pid):
|
||||
return [self.executable, "-p", str(pid)]
|
||||
|
||||
|
||||
class LLDBDebugger(Debugger):
|
||||
def get_args(self, args, non_stop) -> list:
|
||||
if non_stop:
|
||||
return [self.executable, "-o", "run", "-o", "bt", "-o", "quit", "--"] + args
|
||||
return [self.executable, "--"] + args
|
||||
|
||||
def get_attach_args(self, pid):
|
||||
return [self.executable, "-p", str(pid)]
|
||||
|
||||
|
||||
class Test(Loggable):
|
||||
|
@ -365,6 +422,7 @@ class Test(Loggable):
|
|||
message, error))
|
||||
|
||||
if result is Result.TIMEOUT:
|
||||
self.add_stack_trace_to_logfile()
|
||||
if self.options.debug is True:
|
||||
if self.options.gdb:
|
||||
printc("Timeout, you should process <ctrl>c to get into gdb",
|
||||
|
@ -373,11 +431,21 @@ class Test(Loggable):
|
|||
self.process.communicate()
|
||||
else:
|
||||
pname = self.command[0]
|
||||
input("%sTimeout happened on %s you can attach gdb doing:\n $gdb %s %d%s\n"
|
||||
"Press enter to continue" % (Colors.FAIL, self.classname,
|
||||
pname, self.process.pid, Colors.ENDC))
|
||||
while True:
|
||||
debugger = get_debugger()
|
||||
if not debugger:
|
||||
res = input(f"{Colors.FAIL}Timeout happened on {self.classname} no known debugger found but the process PID is {self.process.pid}\n"
|
||||
f"You can find log file at {self.logfile}\n"
|
||||
f"Press 'ok(o)' enter to continue\n\n")
|
||||
else:
|
||||
self.add_stack_trace_to_logfile()
|
||||
res = input(f"{Colors.FAIL}Timeout happened on {self.classname} you can attach the debugger doing:\n"
|
||||
f" $ {' '.join([shlex.quote(a) for a in debugger.get_attach_args(self.process.pid)])}\n"
|
||||
f"You can find log file at {self.logfile}\n"
|
||||
f"**Press ok(o) to continue**{Colors.ENDC}\n\n")
|
||||
|
||||
if res.lower() in ['o', 'ok']:
|
||||
print("Continuing...\n")
|
||||
break
|
||||
|
||||
self.result = result
|
||||
self.message = message
|
||||
|
@ -544,10 +612,8 @@ class Test(Loggable):
|
|||
self.timeout = sys.maxsize
|
||||
self.hard_timeout = sys.maxsize
|
||||
|
||||
args = ["gdb"]
|
||||
if self.options.gdb_non_stop:
|
||||
args += ["-ex", "run", "-ex", "backtrace", "-ex", "quit"]
|
||||
args += ["--args"] + command
|
||||
assert DEBUGGER is not None
|
||||
args = DEBUGGER.get_args(command, self.options.gdb_non_stop)
|
||||
return args
|
||||
|
||||
def use_rr(self, command, subenv):
|
||||
|
@ -1621,6 +1687,10 @@ class TestsManager(Loggable):
|
|||
for patterns in options.blacklisted_tests:
|
||||
self._add_blacklist(patterns)
|
||||
|
||||
if options.gdb:
|
||||
if get_debugger() is None:
|
||||
raise RuntimeError("No debugger found, can't run tests with --gdb")
|
||||
|
||||
def check_blacklists(self):
|
||||
if self.options.check_bugs_status:
|
||||
if not check_bugs_resolution(self.blacklisted_tests):
|
||||
|
|
|
@ -266,12 +266,6 @@ class LauncherConfig(Loggable):
|
|||
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 available on the system",
|
||||
Colors.FAIL)
|
||||
return False
|
||||
|
||||
# other output directories
|
||||
if self.logsdir in ['stdout', 'stderr']:
|
||||
|
|
|
@ -385,6 +385,7 @@ class BackTraceGenerator(Loggable):
|
|||
self.warning(e)
|
||||
self.coredumpctl = None
|
||||
self.gdb = shutil.which('gdb')
|
||||
self.lldb = shutil.which('lldb')
|
||||
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
|
@ -404,8 +405,21 @@ class BackTraceGenerator(Loggable):
|
|||
" supported way to get backtraces for now.")
|
||||
return None
|
||||
|
||||
def get_trace_on_running_process_with_lldb(self, test):
|
||||
lldb = ['lldb', '-o', 'bt all', '-o', 'quit', '-p', str(test.process.pid)]
|
||||
|
||||
try:
|
||||
return subprocess.check_output(
|
||||
lldb, stderr=subprocess.STDOUT, timeout=30).decode()
|
||||
except Exception as e:
|
||||
return "Could not run `lldb` on process (pid: %d):\n%s" % (
|
||||
test.process.pid, e)
|
||||
|
||||
def get_trace_on_running_process(self, test):
|
||||
if not self.gdb:
|
||||
if self.lldb:
|
||||
return self.get_trace_on_running_process_with_lldb(test)
|
||||
|
||||
return "Can not generate stack trace as `gdb` is not" \
|
||||
"installed."
|
||||
|
||||
|
|
Loading…
Reference in a new issue