mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 06:26:23 +00:00
validate: launcher: Add a way to retrieve trace without coredumpctl
Simply spnning on segfaults (like gst-launch) and catch that in the launcher to transform the timeout into a segfault and grab a gdb backtrace
This commit is contained in:
parent
21e23c72fc
commit
72995d5bbe
6 changed files with 119 additions and 19 deletions
|
@ -20,11 +20,23 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include<math.h>
|
||||
#include<ctype.h>
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
#include<stdlib.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#include <glib-unix.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "gst-validate-utils.h"
|
||||
#include <gst/gst.h>
|
||||
|
@ -821,3 +833,76 @@ gst_validate_object_set_property (GstValidateReporter * reporter,
|
|||
g_value_reset (&nvalue);
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
fault_restore (void)
|
||||
{
|
||||
struct sigaction action;
|
||||
|
||||
memset (&action, 0, sizeof (action));
|
||||
action.sa_handler = SIG_DFL;
|
||||
|
||||
sigaction (SIGSEGV, &action, NULL);
|
||||
sigaction (SIGQUIT, &action, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fault_spin (void)
|
||||
{
|
||||
int spinning = TRUE;
|
||||
|
||||
g_on_error_stack_trace ("GstValidate");
|
||||
|
||||
wait (NULL);
|
||||
|
||||
g_printerr ("Please run 'gdb <process-name> %d' to "
|
||||
"continue debugging, Ctrl-C to quit, or Ctrl-\\ to dump core.\n",
|
||||
(gint) getpid ());
|
||||
|
||||
while (spinning)
|
||||
g_usleep (1000000);
|
||||
}
|
||||
|
||||
static void
|
||||
fault_handler_sighandler (int signum)
|
||||
{
|
||||
fault_restore ();
|
||||
|
||||
/* printf is used instead of g_print(), since it's less likely to
|
||||
* deadlock */
|
||||
switch (signum) {
|
||||
case SIGSEGV:
|
||||
g_printerr ("<Caught SIGNAL: SIGSEGV>\n");
|
||||
break;
|
||||
case SIGQUIT:
|
||||
g_print ("<Caught SIGNAL: SIGQUIT>\n");
|
||||
break;
|
||||
default:
|
||||
g_printerr ("<Caught SIGNAL: %d>\n", signum);
|
||||
break;
|
||||
}
|
||||
|
||||
fault_spin ();
|
||||
}
|
||||
|
||||
static void
|
||||
fault_setup (void)
|
||||
{
|
||||
struct sigaction action;
|
||||
|
||||
memset (&action, 0, sizeof (action));
|
||||
action.sa_handler = fault_handler_sighandler;
|
||||
|
||||
sigaction (SIGSEGV, &action, NULL);
|
||||
sigaction (SIGQUIT, &action, NULL);
|
||||
}
|
||||
#endif /* G_OS_UNIX */
|
||||
|
||||
void
|
||||
gst_validate_spin_on_fault_signals (void)
|
||||
{
|
||||
#ifdef G_OS_UNIX
|
||||
fault_setup ();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -64,4 +64,7 @@ GstValidateActionReturn gst_validate_object_set_property (GstValidateReporter *
|
|||
const GValue * value,
|
||||
gboolean optional);
|
||||
|
||||
GST_VALIDATE_API
|
||||
void gst_validate_spin_on_fault_signals (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -232,6 +232,7 @@ class Test(Loggable):
|
|||
self.add_env_variable("DISPLAY")
|
||||
|
||||
def add_stack_trace_to_logfile(self):
|
||||
self.debug("Adding stack trace")
|
||||
trace_gatherer = BackTraceGenerator.get_default()
|
||||
stack_trace = trace_gatherer.get_trace(self)
|
||||
|
||||
|
@ -241,11 +242,13 @@ class Test(Loggable):
|
|||
info = "\n\n== Stack trace: == \n%s" % stack_trace
|
||||
if self.options.redirect_logs:
|
||||
print(info)
|
||||
elif self.options.xunit_file:
|
||||
return
|
||||
|
||||
if self.options.xunit_file:
|
||||
self.stack_trace = stack_trace
|
||||
else:
|
||||
with open(self.logfile, 'a') as f:
|
||||
f.write(info)
|
||||
|
||||
with open(self.logfile, 'a') as f:
|
||||
f.write(info)
|
||||
|
||||
def set_result(self, result, message="", error=""):
|
||||
self.debug("Setting result: %s (message: %s, error: %s)" % (result,
|
||||
|
@ -638,12 +641,8 @@ class GstValidateListener(socketserver.BaseRequestHandler):
|
|||
class GstValidateTest(Test):
|
||||
|
||||
""" A class representing a particular test. """
|
||||
findpos_regex = re.compile(
|
||||
'.*position.*(\d+):(\d+):(\d+).(\d+).*duration.*(\d+):(\d+):(\d+).(\d+)')
|
||||
findlastseek_regex = re.compile(
|
||||
'seeking to.*(\d+):(\d+):(\d+).(\d+).*stop.*(\d+):(\d+):(\d+).(\d+).*rate.*(\d+)\.(\d+)')
|
||||
|
||||
HARD_TIMEOUT_FACTOR = 5
|
||||
fault_sig_regex = re.compile("<Caught SIGNAL: .*>")
|
||||
|
||||
def __init__(self, application_name, classname,
|
||||
options, reporter, duration=0,
|
||||
|
@ -908,11 +907,16 @@ class GstValidateTest(Test):
|
|||
msg = ""
|
||||
result = Result.PASSED
|
||||
if self.result == Result.TIMEOUT:
|
||||
if expected_timeout:
|
||||
not_found_expected_failures.remove(expected_timeout)
|
||||
result, msg = self.check_expected_timeout(expected_timeout)
|
||||
else:
|
||||
return
|
||||
with open(self.logfile) as f:
|
||||
signal_fault_info = self.fault_sig_regex.findall(f.read())
|
||||
if signal_fault_info:
|
||||
result = Result.FAILED
|
||||
msg = signal_fault_info[0]
|
||||
elif expected_timeout:
|
||||
not_found_expected_failures.remove(expected_timeout)
|
||||
result, msg = self.check_expected_timeout(expected_timeout)
|
||||
else:
|
||||
return
|
||||
elif self.process.returncode in COREDUMP_SIGNALS:
|
||||
result = Result.FAILED
|
||||
msg = "Application segfaulted "
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <gst/validate/media-descriptor-writer.h>
|
||||
#include <gst/validate/media-descriptor-parser.h>
|
||||
#include <gst/validate/media-descriptor.h>
|
||||
#include <gst/validate/gst-validate-utils.h>
|
||||
#include <gst/pbutils/encoding-profile.h>
|
||||
#include <locale.h> /* for LC_ALL */
|
||||
|
||||
|
@ -102,6 +103,8 @@ main (int argc, gchar ** argv)
|
|||
}
|
||||
g_option_context_free (ctx);
|
||||
|
||||
gst_validate_spin_on_fault_signals ();
|
||||
|
||||
runner = gst_validate_runner_new ();
|
||||
|
||||
if (expected_file) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/validate/gst-validate-utils.h>
|
||||
#include <gst/validate/validate.h>
|
||||
#include <gst/pbutils/encoding-profile.h>
|
||||
|
||||
|
@ -836,6 +837,8 @@ main (int argc, gchar ** argv)
|
|||
g_unix_signal_add (SIGINT, (GSourceFunc) intr_handler, pipeline);
|
||||
#endif
|
||||
|
||||
gst_validate_spin_on_fault_signals ();
|
||||
|
||||
monitor =
|
||||
gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline), runner,
|
||||
NULL);
|
||||
|
|
|
@ -457,6 +457,8 @@ main (int argc, gchar ** argv)
|
|||
g_unix_signal_add (SIGINT, (GSourceFunc) intr_handler, pipeline);
|
||||
#endif
|
||||
|
||||
gst_validate_spin_on_fault_signals ();
|
||||
|
||||
if (_is_playbin_pipeline (argc - 1, argv + 1)) {
|
||||
_register_playbin_actions ();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue