public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-sergiodj-stap-patches: New auto-sizing algorithms, new comments, etc.
@ 2012-04-20 4:19 sergiodj
0 siblings, 0 replies; only message in thread
From: sergiodj @ 2012-04-20 4:19 UTC (permalink / raw)
To: archer-commits
The branch, archer-sergiodj-stap-patches has been updated
via ccaaf2154dfffef1ac11055f9bf0b8564ec73181 (commit)
from b1f5e35562e1cc1654ccf668b0166b48c9c50f46 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit ccaaf2154dfffef1ac11055f9bf0b8564ec73181
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Fri Apr 20 01:19:11 2012 -0300
New auto-sizing algorithms, new comments, etc.
-----------------------------------------------------------------------
Summary of changes:
gdb/probe.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++-------
gdb/probe.h | 66 +++++++++++++--
gdb/stap-probe.c | 28 +++----
3 files changed, 286 insertions(+), 54 deletions(-)
First 500 lines of diff:
diff --git a/gdb/probe.c b/gdb/probe.c
index 7a5e140..8659d34 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -362,7 +362,113 @@ compare_entries (const void *a, const void *b)
return strcmp (ea->objfile->name, eb->objfile->name);
}
-/* Implementation of the `info probes' command. */
+/* Helper function that generate entries in the ui_out table being
+ crafted by `info_probes_for_ops'. */
+
+static void
+gen_ui_out_table_header_info (VEC (probe_entry) *items,
+ const struct probe_ops *p)
+{
+ VEC (const_char_ptr) *fields = NULL;
+ struct cleanup *c;
+ const char *f;
+ int jx;
+
+ gdb_assert (p != NULL);
+
+ if (p->gen_ui_out_table_header == NULL || p->gen_ui_out_fields == NULL)
+ return;
+
+ c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+ p->gen_ui_out_table_header (&fields);
+
+ for (jx = 0; VEC_iterate (const_char_ptr, fields, jx, f); ++jx)
+ {
+ probe_entry *entry;
+ int ix;
+ size_t size_max = strlen (f);
+
+ for (ix = 0; VEC_iterate (probe_entry, items, ix, entry); ++ix)
+ {
+ VEC (const_char_ptr) *values = NULL;
+ struct cleanup *c2;
+ const char *val;
+ int kx;
+
+ if (entry->probe->pops != p)
+ continue;
+
+ c2 = make_cleanup (VEC_cleanup (const_char_ptr), &values);
+ p->gen_ui_out_fields (entry->probe, entry->objfile, &values);
+
+ for (kx = 0; VEC_iterate (const_char_ptr, values, kx, val); ++kx)
+ {
+ size_t s;
+
+ /* It is valid to have a NULL value here, which means that the
+ backend does not have something to write and this particular
+ field should be skipped. */
+ if (val == NULL)
+ continue;
+
+ s = strlen (val);
+
+ if (s > size_max)
+ size_max = s;
+ }
+
+ do_cleanups (c2);
+ }
+
+ ui_out_table_header (current_uiout, size_max, ui_left, f, f);
+ }
+
+ do_cleanups (c);
+}
+
+/* Helper function to print extra information about a probe and an objfile
+ represented by ENTRY. */
+
+static void
+print_ui_out_info (probe_entry *entry)
+{
+ const char *val, *field;
+ int ix;
+ VEC (const_char_ptr) *values = NULL, *fields = NULL;
+ struct cleanup *c;
+
+ gdb_assert (entry != NULL && entry->probe != NULL
+ && entry->probe->pops != NULL);
+
+ if (entry->probe->pops->gen_ui_out_table_header == NULL
+ || entry->probe->pops->gen_ui_out_fields == NULL)
+ return;
+
+ c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+ make_cleanup (VEC_cleanup (const_char_ptr), &values);
+
+ entry->probe->pops->gen_ui_out_table_header (&fields);
+ entry->probe->pops->gen_ui_out_fields (entry->probe, entry->objfile,
+ &values);
+
+ gdb_assert (VEC_length (const_char_ptr, fields)
+ == VEC_length (const_char_ptr, values));
+
+ for (ix = 0;
+ VEC_iterate (const_char_ptr, fields, ix, field),
+ VEC_iterate (const_char_ptr, values, ix, val);
+ ++ix)
+ {
+ if (val == NULL)
+ ui_out_field_skip (current_uiout, field);
+ else
+ ui_out_field_string (current_uiout, field, val);
+ }
+
+ do_cleanups (c);
+}
+
+/* See comment in probe.h. */
void
info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
@@ -370,11 +476,16 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
char *provider, *probe = NULL, *objname = NULL;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
VEC (probe_entry) *items;
- int i, any_found, ui_out_extra_fields;
+ int i, any_found;
+ int ui_out_extra_fields = 0;
int size_addr;
+ int size_name = strlen ("Name");
+ int size_objname = strlen ("Object");
+ int size_provider = strlen ("Provider");
probe_entry *entry;
struct gdbarch *gdbarch = get_current_arch ();
+ /* Do we have a `provider:probe:objfile' style of linespec? */
provider = extract_arg (&arg);
if (provider)
{
@@ -391,7 +502,54 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
}
}
- ui_out_extra_fields = pops != NULL ? pops->ui_out_extra_fields : 0;
+ if (pops == NULL)
+ {
+ const struct probe_ops *po;
+ int ix;
+
+ /* If the probe_ops is NULL, it means the user has requested a "simple"
+ `info probes', i.e., she wants to print all information about all
+ probes. For that, we have to identify how many extra fields we will
+ need to add in the ui_out table.
+
+ 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. */
+
+ for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
+ {
+ VEC (const_char_ptr) *fields = NULL;
+ struct cleanup *c;
+
+ if (po->gen_ui_out_table_header == NULL)
+ continue;
+
+ c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+ po->gen_ui_out_table_header (&fields);
+
+ ui_out_extra_fields += VEC_length (const_char_ptr, fields);
+
+ do_cleanups (c);
+ }
+ }
+ else
+ {
+ if (pops->gen_ui_out_table_header != NULL)
+ {
+ VEC (const_char_ptr) *fields = NULL;
+ struct cleanup *c;
+
+ /* We have a probe_ops, and it exports the function used to
+ obtains the extra fields. So we just ask the backend about
+ what are those extra fields, and increment `ui_out_extra_fields'
+ accordingly. */
+
+ c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+ pops->gen_ui_out_table_header (&fields);
+ ui_out_extra_fields = VEC_length (const_char_ptr, fields);
+ do_cleanups (c);
+ }
+ }
items = collect_probes (objname, provider, probe, pops);
make_cleanup (VEC_cleanup (probe_entry), &items);
@@ -404,23 +562,47 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
qsort (VEC_address (probe_entry, items), VEC_length (probe_entry, items),
sizeof (probe_entry), compare_entries);
+ /* What's the size of an address in our architecture? */
size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
-/* FIXME: provider width auto-sizing. */
- ui_out_table_header (current_uiout, 10, ui_left, "provider", _("Provider"));
-/* FIXME: name width auto-sizing. */
- ui_out_table_header (current_uiout, 10, ui_left, "name", _("Name"));
-/* FIXME: address width auto-sizing. */
+ /* Determining the maximum size of each field (`provider', `name' and
+ `objname'). */
+ for (i = 0; VEC_iterate (probe_entry, items, i, entry); ++i)
+ {
+ int s_name = strlen (entry->probe->name);
+ int s_provider = strlen (entry->probe->provider);
+ int s_objname = strlen (entry->objfile->name);
+
+ if (s_name > size_name)
+ size_name = s_name;
+
+ if (s_provider > size_provider)
+ size_provider = s_provider;
+
+ if (s_objname > size_objname)
+ size_objname = s_objname;
+ }
+
+ ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
+ _("Provider"));
+ ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where"));
- if (pops != NULL && pops->gen_ui_out_table_header != NULL)
- pops->gen_ui_out_table_header (current_uiout, ui_left);
-
-#if 0 /* FIXME */
- ui_out_table_header (current_uiout, 10, ui_left, "semaphore",
- _("Semaphore"));
-#endif
-/* FIXME: object width auto-sizing. */
- ui_out_table_header (current_uiout, 30, ui_left, "object", _("Object"));
+
+ if (pops == NULL)
+ {
+ const struct probe_ops *po;
+ int ix;
+
+ /* We have to generate the table header for each new probe type that we
+ will print. */
+ for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
+ gen_ui_out_table_header_info (items, po);
+ }
+ else
+ gen_ui_out_table_header_info (items, pops);
+
+ ui_out_table_header (current_uiout, size_objname, ui_left, "object",
+ _("Object"));
ui_out_table_body (current_uiout);
for (i = 0; VEC_iterate (probe_entry, items, i, entry); ++i)
@@ -434,17 +616,20 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
ui_out_field_core_addr (current_uiout, "addr",
get_objfile_arch (entry->objfile),
entry->probe->address);
- if (pops != NULL && pops->gen_ui_out_fields != NULL)
- pops->gen_ui_out_fields (entry->probe, entry->objfile, current_uiout);
-#if 0 /* FIXME */
- if (entry->probe->sem_addr == 0)
- ui_out_field_skip (current_uiout, "semaphore");
+ if (pops == NULL)
+ {
+ const struct probe_ops *po;
+ int ix;
+
+ for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
+ ++ix)
+ if (entry->probe->pops == po)
+ print_ui_out_info (entry);
+ }
else
- ui_out_field_core_addr (current_uiout, "semaphore",
- get_objfile_arch (entry->objfile),
- entry->probe->sem_addr);
-#endif
+ print_ui_out_info (entry);
+
ui_out_field_string (current_uiout, "object", entry->objfile->name);
ui_out_text (current_uiout, "\n");
@@ -491,11 +676,7 @@ probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
n);
}
-/* Return specific PROBE_OPS * matching *LINESPECP and possibly updating
- *LINESPECP to skip its "-probe-type " prefix. Return &probe_ops_any if
- *LINESPECP matches "-probe ", that is any unspecific probe. Return NULL if
- *LINESPECP is not identified as any known probe type, *LINESPECP is not
- modified in such case. */
+/* See comment in probe.h. */
const struct probe_ops *
probe_linespec_to_ops (const char **linespecp)
@@ -510,7 +691,7 @@ probe_linespec_to_ops (const char **linespecp)
return NULL;
}
-/* See comments in probe.h. */
+/* See comment in probe.h. */
int
probe_is_linespec_by_keyword (const char **linespecp, const char *const *keywords)
@@ -555,7 +736,6 @@ probe_any_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
const struct probe_ops probe_ops_any =
{
- 0,
probe_any_is_linespec,
probe_any_get_probes,
};
diff --git a/gdb/probe.h b/gdb/probe.h
index 4e53098..96be016 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -22,6 +22,8 @@
#include "gdb_vecs.h"
+DEF_VEC_P (const_char_ptr);
+
struct linespec_result;
enum ui_align;
@@ -29,13 +31,25 @@ enum ui_align;
struct probe_ops
{
- int ui_out_extra_fields;
+ /* Method responsible for verifying if the linespec provided is a valid
+ linespec for a probe breakpoint. It should return 1 if it is, or zero
+ if it is not. It also should update the pointer passed in order to
+ discard the breakpoint option associated with this linespec. For
+ example, if the option is `-probe', and the linespec provided is
+ `-probe abc', the function should return 1 and set the string pointer
+ to `abc'. */
+
+ int (*is_linespec) (const char **);
+
+ /* Function that should fill the `VEC (probe_p) **' argument with
+ known probes from the objfile specified. */
- int (*is_linespec) (const char **linespecp);
+ void (*get_probes) (VEC (probe_p) **, struct objfile *);
- void (*get_probes) (VEC (probe_p) **probesp, struct objfile *objfile);
+ /* Function used to relocate a probe's addresses according to some
+ `CORE_ADDR' delta provided. */
- void (*relocate) (struct probe *probe, CORE_ADDR delta);
+ void (*relocate) (struct probe *, CORE_ADDR);
/* Return the number of arguments of this probe. */
@@ -73,21 +87,52 @@ struct probe_ops
void (*destroy) (struct probe *);
- void (*gen_ui_out_table_header) (struct ui_out *, enum ui_align);
+ /* Function responsible for providing the extra fields that will be
+ printed in the `info probes' command. It should fill the
+ `VEC (const_char_ptr) **' with whatever extra fields it needs.
+ If the backend doesn't need to print extra fields, it can set this
+ method to NULL. */
+
+ void (*gen_ui_out_table_header) (VEC (const_char_ptr) **);
+
+ /* Function that will provide a `VEC (const_char_ptr) **' containing
+ the values of the extra fields to be printed for the specified probe
+ and objfile. If the backend implements the `gen_ui_out_table_header',
+ then it should implement this method as well. The backend should also
+ guarantee that the order and the number of values in the vector is
+ exactly the same as the order of the extra fields provided in the
+ method `gen_ui_out_table_header'. If a certain field is to be skipped
+ when printing the information, you can push a NULL value in that
+ position in the vector. */
void (*gen_ui_out_fields) (struct probe *, struct objfile *,
- struct ui_out *);
+ VEC (const_char_ptr) **);
};
+/* Definition of a vector of probe_ops. */
+
typedef const struct probe_ops *probe_ops_cp;
DEF_VEC_P (probe_ops_cp);
extern VEC (probe_ops_cp) *all_probe_ops;
+/* The probe_ops associated with the generic probe. */
+
extern const struct probe_ops probe_ops_any;
+/* Helper function that, given KEYWORDS, iterate over it trying to match
+ each keyword with LINESPECP. If it succeeds, it updates the LINESPECP
+ pointer and returns 1. Otherwise, nothing is done to LINESPECP and zero
+ is returned. */
+
extern int probe_is_linespec_by_keyword (const char **linespecp,
const char *const *keywords);
+/* Return specific PROBE_OPS * matching *LINESPECP and possibly updating
+ *LINESPECP to skip its "-probe-type " prefix. Return &probe_ops_any if
+ *LINESPECP matches "-probe ", that is any unspecific probe. Return NULL if
+ *LINESPECP is not identified as any known probe type, *LINESPECP is not
+ modified in such case. */
+
extern const struct probe_ops *probe_linespec_to_ops (const char **linespecp);
/* The probe itself. The struct contains generic information about the
@@ -137,9 +182,18 @@ extern VEC (probe_p) *find_probes_in_objfile (struct objfile *objfile,
const char *provider,
const char *name);
+/* Generate a `info probes' command output for probe_ops represented by
+ POPS. It is a helper function that can be used by the probe backends
+ to print their `info probe TYPE'. */
+
extern void info_probes_for_ops (char *arg, int from_tty,
const struct probe_ops *pops);
+/* Return the `cmd_list_element' associated with the `info probes' command,
+ or create a new one if it doesn't exist. Helper function that serves the
+ purpose of avoiding the case of a backend using the `cmd_list_element'
+ associated with `info probes', without having it registered yet. */
+
extern struct cmd_list_element **info_probes_cmdlist_get (void);
/* A convenience function that finds a probe at the PC in FRAME and
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 94ca5e0..3acebd5 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -93,6 +93,9 @@ DEF_VEC_O (stap_probe_arg_s);
struct stap_probe
{
+ /* Generic information about the probe. This shall be the first element
+ of this struct, in order to maintain binary compatibility with the
+ `struct probe' and be able to fully abstract it. */
struct probe p;
/* If the probe has a semaphore associated, then this is the value of
@@ -1446,36 +1449,31 @@ stap_probe_is_linespec (const char **linespecp)
}
static void
-stap_gen_ui_out_table_header (struct ui_out *uiout, enum ui_align uialign)
+stap_gen_ui_out_table_header (VEC (const_char_ptr) **fields)
{
- struct gdbarch *gdbarch = get_current_arch ();
- int size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
-
- ui_out_table_header (uiout, size_addr, uialign, "semaphore",
- _("Semaphore"));
+ VEC_safe_push (const_char_ptr, *fields, _("Semaphore"));
}
static void
-stap_gen_ui_out_fields (struct probe *probe_generic,
- struct objfile *objfile, struct ui_out *uiout)
+stap_gen_ui_out_fields (struct probe *probe_generic, struct objfile *objfile,
+ VEC (const_char_ptr) **ret)
{
struct stap_probe *probe = (struct stap_probe *) probe_generic;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const char *val = NULL;
gdb_assert (probe_generic->pops == &stap_probe_ops);
- if (probe->sem_addr == 0)
- ui_out_field_skip (uiout, "semaphore");
- else
- ui_out_field_core_addr (uiout, "semaphore",
- get_objfile_arch (objfile),
- probe->sem_addr);
+ if (probe->sem_addr)
+ val = print_core_address (gdbarch, probe->sem_addr);
+
+ VEC_safe_push (const_char_ptr, *ret, val);
}
/* SystemTap probe_ops. */
static const struct probe_ops stap_probe_ops =
{
- 1, /* ui_out_extra_fields */
stap_probe_is_linespec,
stap_get_probes,
stap_relocate,
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-04-20 4:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-20 4:19 [SCM] archer-sergiodj-stap-patches: New auto-sizing algorithms, new comments, etc sergiodj
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).