]> sourceware.org Git - systemtap.git/commitdiff
Add some monitor mode improvements.
authorFelix Lu <flu@redhat.com>
Fri, 18 Mar 2016 18:11:05 +0000 (14:11 -0400)
committerFelix Lu <flu@redhat.com>
Fri, 18 Mar 2016 20:49:28 +0000 (16:49 -0400)
Added an option to pause and resume the script while running to
allow the user to review the output. Previously, a synthetic probe
was being displayed in the probe list, this is now removed.

* elaborate.cxx:
  - monitor_mode_write: skip generating probe point
    condition for synthetic probes. Add command to resume
    and pause all probes.
  - semantic_pass: call monitor_mode_{read, write} in init
* staprun/monitor.c: Bind keys for pause and resume.

elaborate.cxx
man/stap.1.in
staprun/monitor.c

index f72d937f82c8c9c31eca5ea0b3acda30b1b7cfdd..df45f2264e578fe55c058b4113baf38922504a2d 100644 (file)
@@ -2017,84 +2017,6 @@ void add_global_var_display (systemtap_session& s)
     }
 }
 
-static void create_monitor_function(systemtap_session& s)
-{
-  functiondecl* fd = new functiondecl;
-  fd->synthetic = true;
-  fd->unmangled_name = fd->name = "__private___monitor_data_function_probes";
-  fd->type = pe_string;
-
-  vardecl* v = new vardecl;
-  v->type = pe_long;
-  v->unmangled_name = v->name = "index";
-  fd->formal_args.push_back(v);
-
-  embeddedcode* ec = new embeddedcode;
-  string code;
-  code = "/* unprivileged */ /* pure */"
-         "const struct stap_probe *const p = &stap_probes[STAP_ARG_index];\n"
-         "if (likely (probe_timing(STAP_ARG_index))) {\n"
-         "struct stat_data *stats = _stp_stat_get (probe_timing(STAP_ARG_index), 0);\n"
-         "if (stats->count) {\n"
-         "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);\n"
-         "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
-         "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %lld, "
-         "\\\"min\\\": %lld, \\\"avg\\\": %lld, \\\"max\\\": %lld, \",\n"
-         "p->index, p->cond_enabled ? \"on\" : \"off\", (long long) stats->count,\n"
-         "(long long) stats->min, (long long) avg, (long long) stats->max);\n"
-         "} else {\n"
-         "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
-         "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %d, "
-         "\\\"min\\\": %d, \\\"avg\\\": %d, \\\"max\\\": %d, \",\n"
-         "p->index, p->cond_enabled ? \"on\" : \"off\", 0, 0, 0, 0);}}\n"
-         "STAP_RETURN(_monitor_buf);\n";
-  ec->code = code;
-  fd->body = ec;
-
-  s.functions[fd->name] = fd;
-}
-
-static void monitor_mode_init(systemtap_session& s)
-{
-  if (!s.monitor) return;
-
-  vardecl* v = new vardecl;
-  v->unmangled_name = v->name = "__global___monitor_module_start";
-  v->set_arity(0, 0);
-  v->type = pe_long;
-  v->synthetic = true;
-  s.globals.push_back(v);
-
-  stringstream code;
-  code << "probe begin {" << endl;
-  code << "__monitor_module_start = jiffies()" << endl;
-  code << "}" << endl;
-
-  probe* p = parse_synthetic_probe(s, code, 0);
-  if (!p)
-    throw SEMANTIC_ERROR (_("can't create begin probe"), 0);
-
-  vector<derived_probe*> dps;
-  derive_probes (s, p, dps);
-
-  derived_probe* dp = dps[0];
-  s.probes.insert (s.probes.begin(), dp);
-  dp->join_group (s);
-
-  // Repopulate symbol info
-  symresolution_info sym (s);
-  sym.current_function = 0;
-  sym.current_probe = dp;
-  dp->body->visit (&sym);
-
-  embeddedcode* ec = new embeddedcode;
-  ec->code = "#define STAP_MONITOR_READ 8192\n"
-             "static char _monitor_buf[STAP_MONITOR_READ];";
-  s.embeds.push_back(ec);
-
-  create_monitor_function(s);
-}
-
 static void monitor_mode_read(systemtap_session& s)
 {
   if (!s.monitor) return;
@@ -2161,7 +2083,7 @@ static void monitor_mode_read(systemtap_session& s)
   s.probes.push_back (dp);
   dp->join_group (s);
 
-  // Repopulate symbol and type info
+  // Repopulate symbol info
   symresolution_info sym (s);
   sym.current_function = 0;
   sym.current_probe = dp;
@@ -2173,7 +2095,7 @@ static void monitor_mode_write(systemtap_session& s)
   if (!s.monitor) return;
 
   for (vector<derived_probe*>::const_iterator it = s.probes.begin();
-      it != s.probes.end(); ++it)
+      it != s.probes.end()-1; ++it) // Skip monitor read probe
     {
       vardecl* v = new vardecl;
       v->unmangled_name = v->name = "__global___monitor_" + lex_cast(it-s.probes.begin()) + "_enabled";
@@ -2212,7 +2134,7 @@ static void monitor_mode_write(systemtap_session& s)
 
   code << "  if ($value == \"exit\") { exit()";
 
-  code << "  } else if ($value == \"reset\") {";
+  code << "  } else if ($value == \"clear\") {";
   for (vector<vardecl*>::const_iterator it = s.globals.begin();
       it != s.globals.end(); ++it)
     {
@@ -2240,10 +2162,24 @@ static void monitor_mode_write(systemtap_session& s)
           code << "delete " << v->name << endl;
         }
     }
-  code << "}" << endl;
 
+  code << "} else if ($value == \"resume\") {" << endl;
   for (vector<derived_probe*>::const_iterator it = s.probes.begin();
-      it != s.probes.end(); ++it)
+      it != s.probes.end()-1; ++it)
+    {
+      code << "  __monitor_" << it-s.probes.begin() << "_enabled" << " = 1" << endl;
+    }
+
+  code << "} else if ($value == \"pause\") {" << endl;
+  for (vector<derived_probe*>::const_iterator it = s.probes.begin();
+      it != s.probes.end()-1; ++it)
+    {
+      code << "  __monitor_" << it-s.probes.begin() << "_enabled" << " = 0" << endl;
+    }
+  code << "}";
+
+  for (vector<derived_probe*>::const_iterator it = s.probes.begin();
+      it != s.probes.end()-1; ++it)
     {
       code << "  if ($value == \"" << it-s.probes.begin() << "\")"
            << "  __monitor_" << it-s.probes.begin() << "_enabled" << " ^= 1" << endl;
@@ -2262,7 +2198,87 @@ static void monitor_mode_write(systemtap_session& s)
   s.probes.push_back (dp);
   dp->join_group (s);
 
-  // Repopulate symbol and type info
+  // Repopulate symbol info
+  symresolution_info sym (s);
+  sym.current_function = 0;
+  sym.current_probe = dp;
+  dp->body->visit (&sym);
+}
+
+static void create_monitor_function(systemtap_session& s)
+{
+  functiondecl* fd = new functiondecl;
+  fd->synthetic = true;
+  fd->unmangled_name = fd->name = "__private___monitor_data_function_probes";
+  fd->type = pe_string;
+
+  vardecl* v = new vardecl;
+  v->type = pe_long;
+  v->unmangled_name = v->name = "index";
+  fd->formal_args.push_back(v);
+
+  embeddedcode* ec = new embeddedcode;
+  string code;
+  code = "/* unprivileged */ /* pure */"
+         "const struct stap_probe *const p = &stap_probes[STAP_ARG_index];\n"
+         "if (likely (probe_timing(STAP_ARG_index))) {\n"
+         "struct stat_data *stats = _stp_stat_get (probe_timing(STAP_ARG_index), 0);\n"
+         "if (stats->count) {\n"
+         "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);\n"
+         "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
+         "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %lld, "
+         "\\\"min\\\": %lld, \\\"avg\\\": %lld, \\\"max\\\": %lld, \",\n"
+         "p->index, p->cond_enabled ? \"on\" : \"off\", (long long) stats->count,\n"
+         "(long long) stats->min, (long long) avg, (long long) stats->max);\n"
+         "} else {\n"
+         "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
+         "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %d, "
+         "\\\"min\\\": %d, \\\"avg\\\": %d, \\\"max\\\": %d, \",\n"
+         "p->index, p->cond_enabled ? \"on\" : \"off\", 0, 0, 0, 0);}}\n"
+         "STAP_RETURN(_monitor_buf);\n";
+  ec->code = code;
+  fd->body = ec;
+
+  s.functions[fd->name] = fd;
+}
+
+static void monitor_mode_init(systemtap_session& s)
+{
+  if (!s.monitor) return;
+
+  vardecl* v = new vardecl;
+  v->unmangled_name = v->name = "__global___monitor_module_start";
+  v->set_arity(0, 0);
+  v->type = pe_long;
+  v->synthetic = true;
+  s.globals.push_back(v);
+
+  embeddedcode* ec = new embeddedcode;
+  ec->code = "#define STAP_MONITOR_READ 8192\n"
+             "static char _monitor_buf[STAP_MONITOR_READ];";
+  s.embeds.push_back(ec);
+
+  create_monitor_function(s);
+  monitor_mode_read(s);
+  monitor_mode_write(s);
+
+  stringstream code;
+  code << "probe begin {" << endl;
+  code << "__monitor_module_start = jiffies()" << endl;
+  code << "}" << endl;
+
+  probe* p = parse_synthetic_probe(s, code, 0);
+  if (!p)
+    throw SEMANTIC_ERROR (_("can't create begin probe"), 0);
+
+  vector<derived_probe*> dps;
+  derive_probes (s, p, dps);
+
+  derived_probe* dp = dps[0];
+  s.probes.push_back (dp);
+  dp->join_group (s);
+
+  // Repopulate symbol info
   symresolution_info sym (s);
   sym.current_function = 0;
   sym.current_probe = dp;
@@ -2285,8 +2301,6 @@ semantic_pass (systemtap_session& s)
 
       if (rc == 0) rc = semantic_pass_symbols (s);
       if (rc == 0) monitor_mode_init (s);
-      if (rc == 0) monitor_mode_read (s);
-      if (rc == 0) monitor_mode_write (s);
       if (rc == 0) rc = semantic_pass_conditions (s);
       if (rc == 0) rc = semantic_pass_optimize1 (s);
       if (rc == 0) rc = semantic_pass_types (s);
index 2fb326196a42d48d2414700194e062c18849c5d8..4b7f8d881662644b8bd28313a13b06106b715f61 100644 (file)
@@ -791,7 +791,7 @@ refresh rate in seconds of the status window. The module can also be controlled
 of commands using the following keys:
 .RS
 .TP
-.BI r
+.BI c
 resets all global variables to their initial values or zeroes them if they
 did not have an initial value.
 .TP
@@ -799,7 +799,14 @@ did not have an initial value.
 rotates the attribute used to sort the list of probes.
 .TP
 .BI t
-brings up a prompt to allow toggling(on/off) of probes by index.
+brings up a prompt to allow toggling(on/off) of probes by index. Probe points
+are still affected by their conditions.
+.TP
+.BI r
+resumes the script by toggling on all probes.
+.TP
+.BI p
+pauses the script by toggling off all probes.
 .TP
 .BI navigation-keys
 the j/k/ArrowDown/ArrowUp keys can be used to scroll through the probe
index 9612797c7311f5e46365bf60c70d035642986d1e..e9d94d6d7316c56eb60a98875eb90ea60690c28f 100644 (file)
@@ -255,13 +255,32 @@ void monitor_render(void)
   max_rows = monitor_y;
   max_cols = MIN(MAX_COLS, monitor_x);
 
-  if (monitor_state != help)
+  if (monitor_state == help)
     {
+      /* Render help page */
+      rendered = 0;
+      wclear(monitor_status);
+      wprintw(monitor_status, "MONITOR MODE COMMANDS\n");
+      wprintw(monitor_status, "h - Display help page.\n");
+      wprintw(monitor_status, "c - Reset all global variables to initial state, zeroes if unset.\n");
+      wprintw(monitor_status, "s - Rotate sort columns for probes.\n");
+      wprintw(monitor_status, "t - Open a prompt to enter the index of a probe to toggle.\n");
+      wprintw(monitor_status, "r - Resume script by toggling on all probes.\n");
+      wprintw(monitor_status, "p - Pause script by toggling off all probes.\n");
+      wprintw(monitor_status, "j/DownArrow - Scroll down the probe list.\n");
+      wprintw(monitor_status, "k/UpArrow - Scroll up the probe list.\n");
+      wprintw(monitor_status, "d/PageDown - Scroll down the output by one page.\n");
+      wprintw(monitor_status, "u/PageUp - Scroll up the probe list by one page.\n");
+      mvwprintw(monitor_status, max_rows-1, 0, "press q to go back\n");
+      wrefresh(monitor_status);
+    }
+  else
+    {
+      /* Render monitor mode statistics */
       if (sprintf_chk(path, "/proc/systemtap/%s/monitor_status", modname))
         return;
       monitor_fp = fopen(path, "r");
 
-      /* Render monitor mode statistics */
       if (monitor_fp)
         {
           char json[MAX_DATA];
@@ -401,21 +420,6 @@ void monitor_render(void)
           /* Free allocated memory */
           json_object_put(jso);
         }
-    } else {
-      /* Render help page */
-      rendered = 0;
-      wclear(monitor_status);
-      wprintw(monitor_status, "MONITOR MODE COMMANDS\n");
-      wprintw(monitor_status, "h - Display help page.\n");
-      wprintw(monitor_status, "r - Reset global variables to initial state, zeroes if unset.\n");
-      wprintw(monitor_status, "s - Rotate sort columns for probes.\n");
-      wprintw(monitor_status, "t - Open prompt to enter a probe index to toggle.\n");
-      wprintw(monitor_status, "j/DownArrow - Scroll down the probe list.\n");
-      wprintw(monitor_status, "k/UpArrow - Scroll up the probe list.\n");
-      wprintw(monitor_status, "d/PageDown - Scroll down the output by one page.\n");
-      wprintw(monitor_status, "u/PageUp - Scroll up the probe list by one page.\n");
-      mvwprintw(monitor_status, max_rows-1, 0, "press q to go back\n");
-      wrefresh(monitor_status);
     }
 }
 
@@ -459,8 +463,14 @@ void monitor_input(void)
               if (comp_fn_index == COMP_FNS)
                 comp_fn_index = 0;
               break;
+            case 'c':
+              write_command("clear", 5);
+              break;
             case 'r':
-              write_command("reset", 5);
+              write_command("resume", 6);
+              break;
+            case 'p':
+              write_command("pause", 5);
               break;
             case 't':
               monitor_state = insert;
This page took 0.043086 seconds and 5 git commands to generate.