aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/probe.c76
-rw-r--r--gdb/probe.h6
-rw-r--r--gdb/stap-probe.c10
4 files changed, 96 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bf98df1..f988d97 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2015-02-17 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * probe.c (print_ui_out_not_applicables): New function.
+ (exists_probe_with_pops): Likewise.
+ (info_probes_for_ops): Do not include column headers for probe
+ types for which no probe has been actually found on any object.
+ Also invoke `print_ui_out_not_applicables' in order to match the
+ column rows with the header when probes of several types are
+ listed.
+ Print the "Type" column.
+ * probe.h (probe_ops): Added a new probe operation `type_name'.
+ * stap-probe.c (stap_probe_ops): Add `stap_type_name'.
+ (stap_type_name): New function.
+
2015-02-17 Patrick Palka <patrick@parcs.ath.cx>
* tui/tui-io.c (tui_getc): Don't call key_is_command_char.
diff --git a/gdb/probe.c b/gdb/probe.c
index 56b5fc1..5ab2593 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -410,6 +410,31 @@ gen_ui_out_table_header_info (VEC (bound_probe_s) *probes,
do_cleanups (c);
}
+/* Helper function to print not-applicable strings for all the extra
+ columns defined in a probe_ops. */
+
+static void
+print_ui_out_not_applicables (const struct probe_ops *pops)
+{
+ struct cleanup *c;
+ VEC (info_probe_column_s) *headings = NULL;
+ info_probe_column_s *column;
+ int ix;
+
+ if (pops->gen_info_probes_table_header == NULL)
+ return;
+
+ c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
+ pops->gen_info_probes_table_header (&headings);
+
+ for (ix = 0;
+ VEC_iterate (info_probe_column_s, headings, ix, column);
+ ++ix)
+ ui_out_field_string (current_uiout, column->field_name, _("n/a"));
+
+ do_cleanups (c);
+}
+
/* Helper function to print extra information about a probe and an objfile
represented by PROBE. */
@@ -482,6 +507,23 @@ get_number_extra_fields (const struct probe_ops *pops)
return n;
}
+/* Helper function that returns 1 if there is a probe in PROBES
+ featuring the given POPS. It returns 0 otherwise. */
+
+static int
+exists_probe_with_pops (VEC (bound_probe_s) *probes,
+ const struct probe_ops *pops)
+{
+ struct bound_probe *probe;
+ int ix;
+
+ for (ix = 0; VEC_iterate (bound_probe_s, probes, ix, probe); ++ix)
+ if (probe->probe->pops == pops)
+ return 1;
+
+ return 0;
+}
+
/* See comment in probe.h. */
void
@@ -497,6 +539,7 @@ info_probes_for_ops (const char *arg, int from_tty,
size_t size_name = strlen ("Name");
size_t size_objname = strlen ("Object");
size_t size_provider = strlen ("Provider");
+ size_t size_type = strlen ("Type");
struct bound_probe *probe;
struct gdbarch *gdbarch = get_current_arch ();
@@ -517,6 +560,9 @@ info_probes_for_ops (const char *arg, int from_tty,
}
}
+ probes = collect_probes (objname, provider, probe_name, pops);
+ make_cleanup (VEC_cleanup (probe_p), &probes);
+
if (pops == NULL)
{
const struct probe_ops *po;
@@ -529,18 +575,18 @@ info_probes_for_ops (const char *arg, int from_tty,
To do that, we iterate over all probe_ops, querying each one about
its extra fields, and incrementing `ui_out_extra_fields' to reflect
- that number. */
+ that number. But note that we ignore the probe_ops for which no probes
+ are defined with the given search criteria. */
for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
- ui_out_extra_fields += get_number_extra_fields (po);
+ if (exists_probe_with_pops (probes, po))
+ ui_out_extra_fields += get_number_extra_fields (po);
}
else
ui_out_extra_fields = get_number_extra_fields (pops);
- probes = collect_probes (objname, provider, probe_name, pops);
- make_cleanup (VEC_cleanup (probe_p), &probes);
make_cleanup_ui_out_table_begin_end (current_uiout,
- 4 + ui_out_extra_fields,
+ 5 + ui_out_extra_fields,
VEC_length (bound_probe_s, probes),
"StaticProbes");
@@ -552,15 +598,19 @@ info_probes_for_ops (const char *arg, int from_tty,
/* What's the size of an address in our architecture? */
size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
- /* Determining the maximum size of each field (`provider', `name' and
- `objname'). */
+ /* Determining the maximum size of each field (`type', `provider',
+ `name' and `objname'). */
for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
{
+ const char *probe_type = probe->probe->pops->type_name (probe->probe);
+
+ size_type = max (strlen (probe_type), size_type);
size_name = max (strlen (probe->probe->name), size_name);
size_provider = max (strlen (probe->probe->provider), size_provider);
size_objname = max (strlen (objfile_name (probe->objfile)), size_objname);
}
+ ui_out_table_header (current_uiout, size_type, ui_left, "type", _("Type"));
ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
_("Provider"));
ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
@@ -571,10 +621,12 @@ info_probes_for_ops (const char *arg, int from_tty,
const struct probe_ops *po;
int ix;
- /* We have to generate the table header for each new probe type that we
- will print. */
+ /* We have to generate the table header for each new probe type
+ that we will print. Note that this excludes probe types not
+ having any defined probe with the search criteria. */
for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
- gen_ui_out_table_header_info (probes, po);
+ if (exists_probe_with_pops (probes, po))
+ gen_ui_out_table_header_info (probes, po);
}
else
gen_ui_out_table_header_info (probes, pops);
@@ -586,9 +638,11 @@ info_probes_for_ops (const char *arg, int from_tty,
for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
{
struct cleanup *inner;
+ const char *probe_type = probe->probe->pops->type_name (probe->probe);
inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");
+ ui_out_field_string (current_uiout, "type",probe_type);
ui_out_field_string (current_uiout, "provider", probe->probe->provider);
ui_out_field_string (current_uiout, "name", probe->probe->name);
ui_out_field_core_addr (current_uiout, "addr",
@@ -604,6 +658,8 @@ info_probes_for_ops (const char *arg, int from_tty,
++ix)
if (probe->probe->pops == po)
print_ui_out_info (probe->probe);
+ else if (exists_probe_with_pops (probes, po))
+ print_ui_out_not_applicables (po);
}
else
print_ui_out_info (probe->probe);
diff --git a/gdb/probe.h b/gdb/probe.h
index 1dd582d..5df1976 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -113,6 +113,12 @@ struct probe_ops
void (*destroy) (struct probe *probe);
+ /* Return a pointer to a name identifying the probe type. This is
+ the string that will be displayed in the "Type" column of the
+ `info probes' command. */
+
+ const char *(*type_name) (struct probe *probe);
+
/* Function responsible for providing the extra fields that will be
printed in the `info probes' command. It should fill HEADS
with whatever extra fields it needs. If the backend doesn't need
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index ffe4dd1..50ad533 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -1703,6 +1703,15 @@ stap_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
}
}
+/* Implementation of the type_name method. */
+
+static const char *
+stap_type_name (struct probe *probe)
+{
+ gdb_assert (probe->pops == &stap_probe_ops);
+ return "stap";
+}
+
static int
stap_probe_is_linespec (const char **linespecp)
{
@@ -1754,6 +1763,7 @@ const struct probe_ops stap_probe_ops =
stap_set_semaphore,
stap_clear_semaphore,
stap_probe_destroy,
+ stap_type_name,
stap_gen_info_probes_table_header,
stap_gen_info_probes_table_values,
};