forked from AuroraMiddleware/gtk
testsuite: use SysprofProfiler for profiling
Instead of using sysprof-cli to profile subprocesses, this uses libsysprof's SysprofProfiler directly so that we can avoid an indirect subprocess as well as disabling the polkit nag. To do this, we have to link against libsysprof instead of libsysprof-capture. This is limited to the -Dbuild-tests=true and -Dprofiler=true case.
This commit is contained in:
parent
7039f31391
commit
5a5b30681e
38
meson.build
38
meson.build
@ -703,20 +703,34 @@ endif
|
||||
|
||||
profiler_enabled = get_option('profiler')
|
||||
if profiler_enabled
|
||||
# libsysprof-capture support
|
||||
profiler_dep = dependency('sysprof-capture-4',
|
||||
# Depend on libsysprof-capture if we only need the capture format.
|
||||
# For -Dbuild-tests=true, we need SysprofProfiler to profile processes
|
||||
# which requires sysprof-4 instead of sysprof-capture-4.
|
||||
|
||||
profiler_options = [
|
||||
'enable_examples=false',
|
||||
'enable_gtk=false',
|
||||
'enable_tests=false',
|
||||
'enable_tools=false',
|
||||
'with_sysprofd=none',
|
||||
'help=false',
|
||||
]
|
||||
|
||||
if get_option('build-tests')
|
||||
profiler_dep_name = 'sysprof-4'
|
||||
profiler_fallback = 'libsysprof_dep'
|
||||
else
|
||||
profiler_dep_name = 'sysprof-capture-4'
|
||||
profiler_fallback = 'libsysprof_capture_dep'
|
||||
profiler_options += ['libsysprof=false']
|
||||
endif
|
||||
|
||||
profiler_dep = dependency(profiler_dep_name,
|
||||
required: true,
|
||||
default_options: [
|
||||
'enable_examples=false',
|
||||
'enable_gtk=false',
|
||||
'enable_tests=false',
|
||||
'enable_tools=false',
|
||||
'libsysprof=false',
|
||||
'with_sysprofd=none',
|
||||
'help=false',
|
||||
],
|
||||
fallback: ['sysprof', 'libsysprof_capture_dep'],
|
||||
default_options: profiler_options,
|
||||
fallback: ['sysprof', profiler_fallback],
|
||||
)
|
||||
|
||||
if profiler_dep.found()
|
||||
cdata.set('HAVE_SYSPROF', profiler_dep.found())
|
||||
else
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sysprof-capture.h>
|
||||
#include <sysprof.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
typedef struct {
|
||||
@ -46,6 +47,8 @@ static char *opt_detail;
|
||||
static char *opt_name;
|
||||
static char *opt_output;
|
||||
static gboolean opt_start_time;
|
||||
static GMainLoop *main_loop;
|
||||
static GError *failure;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "mark", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &opt_mark, "Name of the mark", "NAME" },
|
||||
@ -57,6 +60,29 @@ static GOptionEntry options[] = {
|
||||
{ NULL, }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
start_in_main (gpointer data)
|
||||
{
|
||||
SysprofProfiler *profiler = data;
|
||||
sysprof_profiler_start (profiler);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_failure_cb (SysprofProfiler *profiler,
|
||||
const GError *error)
|
||||
{
|
||||
g_propagate_error (&failure, g_error_copy (error));
|
||||
g_main_loop_quit (main_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stopped_cb (SysprofProfiler *profiler)
|
||||
{
|
||||
g_clear_error (&failure);
|
||||
g_main_loop_quit (main_loop);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -68,7 +94,9 @@ main (int argc, char *argv[])
|
||||
gint64 min, max, total;
|
||||
int count;
|
||||
char *output_dir = NULL;
|
||||
int i;
|
||||
char **spawn_env;
|
||||
char *workdir;
|
||||
int i, j;
|
||||
|
||||
context = g_option_context_new ("COMMANDLINE");
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
@ -84,6 +112,12 @@ main (int argc, char *argv[])
|
||||
if (opt_rep < 1)
|
||||
g_error ("COUNT must be a positive number");
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
workdir = g_get_current_dir ();
|
||||
|
||||
spawn_env = g_get_environ ();
|
||||
spawn_env = g_environ_setenv (spawn_env, "GTK_DEBUG_AUTO_QUIT", "1", TRUE);
|
||||
|
||||
if (opt_output)
|
||||
{
|
||||
GError *err = NULL;
|
||||
@ -116,10 +150,10 @@ main (int argc, char *argv[])
|
||||
|
||||
for (i = 0; i < opt_rep; i++)
|
||||
{
|
||||
GSubprocessLauncher *launcher;
|
||||
GSubprocess *subprocess;
|
||||
SysprofProfiler *profiler;
|
||||
int fd;
|
||||
char *name;
|
||||
SysprofCaptureWriter *writer;
|
||||
SysprofCaptureReader *reader;
|
||||
SysprofCaptureCursor *cursor;
|
||||
SysprofCaptureCondition *condition;
|
||||
@ -128,40 +162,42 @@ main (int argc, char *argv[])
|
||||
fd = g_file_open_tmp ("gtk.XXXXXX.syscap", &name, &error);
|
||||
if (error)
|
||||
g_error ("Create syscap file: %s", error->message);
|
||||
close (fd); // sysprof-cli uses O_EXCL
|
||||
|
||||
child_argv = g_new (char *, argc + 6);
|
||||
child_argv[0] = (char *)"sysprof-cli";
|
||||
child_argv[1] = (char *)"--force";
|
||||
child_argv[2] = (char *)"--use-trace-fd";
|
||||
child_argv[3] = name;
|
||||
child_argv[4] = (char *)"--";
|
||||
for (i = 0; i + 1 < argc; i++)
|
||||
child_argv[5 + i] = argv[i + 1];
|
||||
child_argv[5 + argc - 1] = NULL;
|
||||
child_argv = g_new (char *, argc);
|
||||
for (j = 0; j + 1 < argc; j++)
|
||||
child_argv[j] = argv[j + 1];
|
||||
child_argv[argc - 1] = NULL;
|
||||
|
||||
launcher = g_subprocess_launcher_new (0);
|
||||
g_subprocess_launcher_setenv (launcher, "GTK_DEBUG_AUTO_QUIT", "1", TRUE);
|
||||
writer = sysprof_capture_writer_new_from_fd (fd, 0);
|
||||
if (!writer)
|
||||
g_error ("Failed to create capture writer: %s", g_strerror (errno));
|
||||
|
||||
subprocess = g_subprocess_launcher_spawnv (launcher, (const char *const *)child_argv, &error);
|
||||
if (error)
|
||||
g_error ("Launch child: %s", error->message);
|
||||
profiler = sysprof_local_profiler_new ();
|
||||
sysprof_profiler_set_whole_system (profiler, FALSE);
|
||||
sysprof_profiler_set_spawn (profiler, TRUE);
|
||||
sysprof_profiler_set_spawn_argv (profiler, (const char * const *)child_argv);
|
||||
sysprof_profiler_set_spawn_cwd (profiler, workdir);
|
||||
sysprof_profiler_set_spawn_env (profiler, (const char * const *)spawn_env);
|
||||
sysprof_profiler_set_writer (profiler, writer);
|
||||
|
||||
sysprof_capture_writer_unref (writer);
|
||||
g_free (child_argv);
|
||||
|
||||
if (!g_subprocess_wait (subprocess, NULL, &error))
|
||||
g_error ("Run child: %s", error->message);
|
||||
g_signal_connect_swapped (profiler, "failed", G_CALLBACK (on_failure_cb), NULL);
|
||||
g_signal_connect_swapped (profiler, "stopped", G_CALLBACK (on_stopped_cb), NULL);
|
||||
|
||||
if (!g_subprocess_get_successful (subprocess))
|
||||
g_error ("Child process failed");
|
||||
g_idle_add (start_in_main, profiler);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
g_object_unref (subprocess);
|
||||
g_object_unref (launcher);
|
||||
if (failure)
|
||||
g_error ("Run child: %s", failure->message);
|
||||
|
||||
reader = sysprof_capture_reader_new (name);
|
||||
reader = sysprof_capture_writer_create_reader (writer);
|
||||
if (!reader)
|
||||
g_error ("Opening syscap file: %s", g_strerror (errno));
|
||||
|
||||
sysprof_capture_writer_unref (writer);
|
||||
|
||||
data.mark = opt_mark ? opt_mark : "css validation";
|
||||
data.detail = opt_detail ? opt_detail : NULL;
|
||||
data.do_start = opt_start_time;
|
||||
@ -206,6 +242,8 @@ main (int argc, char *argv[])
|
||||
g_usleep (300000);
|
||||
}
|
||||
|
||||
g_free (workdir);
|
||||
|
||||
min = G_MAXINT64;
|
||||
max = 0;
|
||||
count = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user