[gjs: 2/11] profiler: Implement --profile flag behaviour



commit 2a908ad16cde448fb40974cf50ae8c8942dbf027
Author: Philip Chimento <philip endlessm com>
Date:   Thu Jan 18 13:32:06 2018 -0800

    profiler: Implement --profile flag behaviour
    
    This changes the behaviour of the profiler command line flag to what was
    discussed in #31. --profile without an argument starts the profiler and
    dumps to gjs-$PID.syscap in the current directory, and --profile=foo.dat
    starts the profiler and dumps to foo.dat.

 gjs/console.cpp                            | 44 ++++++++++++++++++++++++++++--
 gjs/profiler.cpp                           |  8 ++----
 installed-tests/scripts/testCommandLine.sh | 13 +++++++++
 3 files changed, 57 insertions(+), 8 deletions(-)
---
diff --git a/gjs/console.cpp b/gjs/console.cpp
index 993c692..672ef9d 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -36,14 +36,21 @@ static char *coverage_output_path = NULL;
 static char *profile_output_path = nullptr;
 static char *command = NULL;
 static gboolean print_version = false;
+static gboolean enable_profiler = false;
 
+static gboolean parse_profile_arg(const char *, const char *, void *, GError **);
+
+/* Keep in sync with entries in check_script_args_for_stray_gjs_args() */
 static GOptionEntry entries[] = {
     { "version", 0, 0, G_OPTION_ARG_NONE, &print_version, "Print GJS version and exit" },
     { "command", 'c', 0, G_OPTION_ARG_STRING, &command, "Program passed in as a string", "COMMAND" },
     { "coverage-prefix", 'C', 0, G_OPTION_ARG_STRING_ARRAY, &coverage_prefixes, "Add the prefix PREFIX to 
the list of files to generate coverage info for", "PREFIX" },
     { "coverage-output", 0, 0, G_OPTION_ARG_STRING, &coverage_output_path, "Write coverage output to a 
directory DIR. This option is mandatory when using --coverage-path", "DIR", },
     { "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &include_path, "Add the directory DIR to the list 
of directories to search for js files.", "DIR" },
-    { "profile-output", 0, 0, G_OPTION_ARG_FILENAME, &profile_output_path, "Enable the profiler and Write 
output to FILE", "FILE" },
+    { "profile", 0, G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
+        G_OPTION_ARG_CALLBACK, reinterpret_cast<void *>(&parse_profile_arg),
+        "Enable the profiler and write output to FILE (default: gjs-$PID.syscap)",
+        "FILE" },
     { NULL }
 };
 
@@ -86,6 +93,31 @@ strcatv(char **strv1,
     return retval;
 }
 
+static gboolean
+parse_profile_arg(const char *option_name,
+                  const char *value,
+                  void       *data,
+                  GError    **error_out)
+{
+    enable_profiler = true;
+    if (value)
+        profile_output_path = g_strdup(value);
+    return true;
+}
+
+static gboolean
+check_stray_profile_arg(const char *option_name,
+                        const char *value,
+                        void       *data,
+                        GError    **error_out)
+{
+    g_warning("You used the --profile option after the script on the GJS "
+              "command line. Support for this will be removed in a future "
+              "version. Place the option before the script.");
+    g_free(profile_output_path);
+    return parse_profile_arg(option_name, value, data, error_out);
+}
+
 static void
 check_script_args_for_stray_gjs_args(int           argc,
                                      char * const *argv)
@@ -94,10 +126,13 @@ check_script_args_for_stray_gjs_args(int           argc,
     char **new_coverage_prefixes = NULL;
     char *new_coverage_output_path = NULL;
     char **new_include_paths = NULL;
+    /* Keep in sync with entries[] at the top */
     static GOptionEntry script_check_entries[] = {
         { "coverage-prefix", 'C', 0, G_OPTION_ARG_STRING_ARRAY, &new_coverage_prefixes },
         { "coverage-output", 0, 0, G_OPTION_ARG_STRING, &new_coverage_output_path },
         { "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &new_include_paths },
+        { "profile", 0, G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
+          G_OPTION_ARG_CALLBACK, reinterpret_cast<void *>(&check_stray_profile_arg) },
         { NULL }
     };
     char **argv_copy = g_new(char *, argc + 2);
@@ -278,8 +313,11 @@ main(int argc, char **argv)
     /* Allow SIGUSR2 (with sigaction param) to enable/disable */
     gjs_profiler_setup_signals();
 
-    if (profile_output_path) {
-        gjs_profiler_set_filename(profiler, profile_output_path);
+    if (enable_profiler) {
+        if (profile_output_path) {
+            gjs_profiler_set_filename(profiler, profile_output_path);
+            g_free(profile_output_path);
+        }
         gjs_profiler_start(profiler);
     }
 
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index cfa6ffb..c199179 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -343,10 +343,8 @@ gjs_profiler_start(GjsProfiler *self)
         return;
 
     GjsAutoChar path = g_strdup(self->filename);
-    if (!path) {
-        GjsAutoChar filename = g_strdup_printf("gjs-profile-%jd", intmax_t(self->pid));
-        path = g_build_filename(g_get_tmp_dir(), filename.get(), nullptr);
-    }
+    if (!path)
+        path = g_strdup_printf("gjs-%jd.syscap", intmax_t(self->pid));
 
     self->capture = sp_capture_writer_new(path, 0);
 
@@ -534,7 +532,7 @@ gjs_profiler_chain_signal(siginfo_t *info)
  * @filename: string containing a filename
  *
  * Set the file to which profiling data is written when the @self is stopped.
- * By default, this is $TMPDIR/gjs-profile-$PID.
+ * By default, this is `gjs-$PID.syscap` in the current directory.
  */
 void
 gjs_profiler_set_filename(GjsProfiler *self,
diff --git a/installed-tests/scripts/testCommandLine.sh b/installed-tests/scripts/testCommandLine.sh
index df9c6e6..e0a42f5 100755
--- a/installed-tests/scripts/testCommandLine.sh
+++ b/installed-tests/scripts/testCommandLine.sh
@@ -135,6 +135,9 @@ report "--coverage-prefix after script should succeed but give a warning"
 $gjs -c 'imports.system.exit(0)' --coverage-prefix=foo --coverage-output=foo 2>&1 | grep -q 
'Gjs-WARNING.*--coverage-output'
 report "--coverage-output after script should succeed but give a warning"
 rm -f foo/coverage.lcov
+$gjs -c 'imports.system.exit(0)' --profile=foo 2>&1 | grep -q 'Gjs-WARNING.*--profile'
+report "--profile after script should succeed but give a warning"
+rm -f foo
 
 # --version works
 $gjs --version >/dev/null
@@ -149,6 +152,16 @@ report "--version after -c should be passed to script"
 test -z "$($gjs -c "$script" --version)"
 report "--version after -c should not print anything"
 
+# --profile
+rm -f gjs-*.syscap foo.syscap
+$gjs -c 'imports.system.exit(0)' && test ! -f gjs-*.syscap
+report "no profiling data should be dumped without --profile"
+$gjs --profile -c 'imports.system.exit(0)' && test -f gjs-*.syscap
+report "--profile should dump profiling data to the default file name"
+$gjs --profile=foo.syscap -c 'imports.system.exit(0)' && test -f foo.syscap
+report "--profile with argument should dump profiling data to the named file"
+rm -f gjs-*.syscap foo.syscap
+
 # interpreter handles queued promise jobs correctly
 output=$($gjs promise.js)
 test $? -eq 42


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]