validate:launcher: Allow retrieving coredumps from within flatpak

This commit is contained in:
Thibault Saunier 2018-07-01 11:32:10 -04:00
parent 8d58befadd
commit 69ec48feef
2 changed files with 41 additions and 23 deletions

View file

@ -277,7 +277,7 @@ class Test(Loggable):
self.debug("%s returncode: %s", self, self.process.returncode) self.debug("%s returncode: %s", self, self.process.returncode)
if self.process.returncode == 0: if self.process.returncode == 0:
self.set_result(Result.PASSED) self.set_result(Result.PASSED)
elif self.process.returncode in [-signal.SIGSEGV, -signal.SIGABRT, 139]: elif self.process.returncode in COREDUMP_SIGNALS:
self.add_stack_trace_to_logfile() self.add_stack_trace_to_logfile()
self.set_result(Result.FAILED, self.set_result(Result.FAILED,
"Application segfaulted, returne code: %d" % ( "Application segfaulted, returne code: %d" % (

View file

@ -27,6 +27,7 @@ import os
import platform import platform
import re import re
import shutil import shutil
import shlex
import signal import signal
import subprocess import subprocess
import sys import sys
@ -309,13 +310,25 @@ def get_scenarios():
class BackTraceGenerator(Loggable): class BackTraceGenerator(Loggable):
__instance = None __instance = None
_executable_regex = re.compile(r'Executable: (.*)\n') _command_line_regex = re.compile(r'Command Line: (.*)\n')
_timestamp_regex = re.compile(r'Timestamp: .*\((\d*)s ago\)') _timestamp_regex = re.compile(r'Timestamp: .*\((\d*)s ago\)')
_pid_regex = re.compile(r'PID: (\d+) \(.*\)')
def __init__(self): def __init__(self):
Loggable.__init__(self) Loggable.__init__(self)
self.coredumpctl = shutil.which('coredumpctl') self.in_flatpak = os.path.exists("/usr/manifest.json")
if self.in_flatpak:
coredumpctl = ['flatpak-spawn', '--host', 'coredumpctl']
else:
coredumpctl = ['coredumpctl']
try:
subprocess.check_output(coredumpctl)
self.coredumpctl = coredumpctl
except Exception as e:
self.warning(e)
self.coredumpctl = None
self.gdb = shutil.which('gdb') self.gdb = shutil.which('gdb')
@classmethod @classmethod
@ -358,11 +371,15 @@ class BackTraceGenerator(Loggable):
# yet. # yet.
time.sleep(1) time.sleep(1)
application = test.process.args[0] if not self.in_flatpak:
coredumpctl = self.coredumpctl + ['info', str(test.process.pid)]
else:
newer_than = time.strftime("%a %Y-%m-%d %H:%M:%S %Z", time.localtime(test._starting_time))
coredumpctl = self.coredumpctl + ['info', os.path.basename(test.command[0]),
'--since', newer_than]
try: try:
info = subprocess.check_output(['coredumpctl', 'info', info = subprocess.check_output(coredumpctl, stderr=subprocess.STDOUT)
str(test.process.pid)],
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
# The trace might not be ready yet # The trace might not be ready yet
time.sleep(1) time.sleep(1)
@ -370,16 +387,16 @@ class BackTraceGenerator(Loggable):
info = info.decode() info = info.decode()
try: try:
executable = BackTraceGenerator._executable_regex.findall(info)[ pid = self._pid_regex.findall(info)[0]
0]
except IndexError: except IndexError:
self.debug("Backtrace could not be found yet, trying harder.") self.debug("Backtrace could not be found yet, trying harder.")
# The trace might not be ready yet
continue continue
if executable != application: application = test.process.args[0]
command_line = BackTraceGenerator._command_line_regex.findall(info)[0]
if shlex.split(command_line)[0] != application:
self.debug("PID: %s -- executable %s != test application: %s" % ( self.debug("PID: %s -- executable %s != test application: %s" % (
test.process.pid, executable, application)) pid, command_line[0], test.application))
# The trace might not be ready yet # The trace might not be ready yet
continue continue
@ -392,20 +409,21 @@ class BackTraceGenerator(Loggable):
bt_all = None bt_all = None
if self.gdb: if self.gdb:
try: try:
tf = tempfile.NamedTemporaryFile() with tempfile.NamedTemporaryFile() as stderr:
subprocess.check_output(['coredumpctl', 'dump', coredump = subprocess.check_output(self.coredumpctl + ['dump', pid],
str(test.process.pid), '--output=' + stderr=stderr)
tf.name], stderr=subprocess.STDOUT)
gdb = ['gdb', '-ex', 't a a bt', '-ex', 'quit', with tempfile.NamedTemporaryFile() as tf:
application, tf.name] tf.write(coredump)
bt_all = subprocess.check_output( tf.flush()
gdb, stderr=subprocess.STDOUT).decode() gdb = ['gdb', '-ex', 't a a bt', '-ex', 'quit', application, tf.name]
bt_all = subprocess.check_output(
gdb, stderr=subprocess.STDOUT).decode()
info += "\nThread apply all bt:\n\n%s" % ( info += "\nThread apply all bt:\n\n%s" % (
bt_all.replace('\n', '\n' + 15 * ' ')) bt_all.replace('\n', '\n' + 15 * ' '))
except Exception as e: except Exception as e:
self.debug("Could not get backtrace from gdb: %s" % e) self.error("Could not get backtrace from gdb: %s" % e)
return info return info