aboutsummaryrefslogtreecommitdiff
path: root/gdb/tracepoint.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2010-07-01 10:36:12 +0000
committerPedro Alves <palves@redhat.com>2010-07-01 10:36:12 +0000
commit0fb4aa4bfcc2aa61c27132f94cf1656dca137dc9 (patch)
treec431424ed51b11bebcff4bc2409f79f9e802edcb /gdb/tracepoint.c
parent76fa04a48e54c68fa6f16db02634b86ff340b98e (diff)
downloadgdb-0fb4aa4bfcc2aa61c27132f94cf1656dca137dc9.zip
gdb-0fb4aa4bfcc2aa61c27132f94cf1656dca137dc9.tar.gz
gdb-0fb4aa4bfcc2aa61c27132f94cf1656dca137dc9.tar.bz2
Static tracepoints support, and UST integration.
gdb/gdbserver/ * configure.ac: Handle --with-ust. substitute ustlibs and ustinc. * mem-break.c (uninsert_all_breakpoints) (reinsert_all_breakpoints): New. * mem-break.h (reinsert_all_breakpoints, uninsert_all_breakpoints): * tracepoint.c (ust_loaded, helper_thread_id, cmd_buf): New. (gdb_agent_ust_loaded, helper_thread_id) (gdb_agent_helper_thread_id): New macros. (struct ipa_sym_addresses): Add addr_ust_loaded, addr_helper_thread_id, addr_cmd_buf. (symbol_list): Add ust_loaded, helper_thread_id, cmd_buf. (in_process_agent_loaded_ust): New. (write_e_ust_not_loaded): New. (maybe_write_ipa_ust_not_loaded): New. (struct collect_static_trace_data_action): New. (enum tracepoint_type) <static_tracepoint>: New. (struct tracepoint) <handle>: Mention static tracepoints. (struct static_tracepoint_ctx): New. (CMD_BUF_SIZE): New. (add_tracepoint_action): Handle static tracepoint actions. (unprobe_marker_at): New. (clear_installed_tracepoints): Handle static tracepoints. (cmd_qtdp): Handle static tracepoints. (probe_marker_at): New. (cmd_qtstart): Handle static tracepoints. (response_tracepoint): Handle static tracepoints. (cmd_qtfstm, cmd_qtsstm, cmd_qtstmat): New. (handle_tracepoint_query): Handle qTfSTM, qTsSTM and qTSTMat. (get_context_regcache): Handle static tracepoints. (do_action_at_tracepoint): Handle static tracepoint actions. (traceframe_find_block_type): Handle static trace data blocks. (traceframe_read_sdata): New. (download_tracepoints): Download static tracepoint actions. [HAVE_UST] Include ust/ust.h, dlfcn.h, sys/socket.h, and sys/un.h. (GDB_PROBE_NAME): New. (ust_ops): New. (GET_UST_SYM): New. (USTF): New. (dlsym_ust): New. (ust_marker_to_static_tracepoint): New. (gdb_probe): New. (collect_ust_data_at_tracepoint): New. (gdb_ust_probe): New. (UNIX_PATH_MAX, SOCK_DIR): New. (gdb_ust_connect_sync_socket): New. (resume_thread, stop_thread): New. (run_inferior_command): New. (init_named_socket): New. (gdb_ust_socket_init): New. (cstr_to_hexstr): New. (next_st): New. (first_marker, next_marker): New. (response_ust_marker): New. (cmd_qtfstm, cmd_qtsstm): New. (unprobe_marker_at, probe_marker_at): New. (cmd_qtstmat, gdb_ust_thread): New. (gdb_ust_init): New. (initialize_tracepoint_ftlib): Call gdb_ust_init. * linux-amd64-ipa.c [HAVE_UST]: Include ust/processor.h (ST_REGENTRY): New. (x86_64_st_collect_regmap): New. (X86_64_NUM_ST_COLLECT_GREGS): New. (AMD64_RIP_REGNUM): New. (supply_static_tracepoint_registers): New. * linux-i386-ipa.c [HAVE_UST]: Include ust/processor.h (ST_REGENTRY): New. (i386_st_collect_regmap): New. (i386_NUM_ST_COLLECT_GREGS): New. (supply_static_tracepoint_registers): New. * server.c (handle_query): Handle qXfer:statictrace:read. <qSupported>: Report support for StaticTracepoints, and qXfer:statictrace:read features. * server.h (traceframe_read_sdata) (supply_static_tracepoint_registers): Declare. * remote-utils.c (convert_int_to_ascii, hexchars, ishex, tohex) (unpack_varlen_hex): Include in IPA build. * Makefile.in (ustlibs, ustinc): New. (IPA_OBJS): Add remote-utils-ipa.o. ($(IPA_LIB)): Link -ldl and -lpthread. (UST_CFLAGS): New. (IPAGENT_CFLAGS): Add UST_CFLAGS. * config.in, configure: Regenerate. gdb/ * NEWS: Mention new support for static tracepoints. (New packets): Mention qTfSTM, qTsSTM, qTSTMat and qXfer:statictrace:read. (New features in the GDB remote stub, GDBserver): Mention static tracepoints support using an UST based backend. (New commands): Mention "info static-tracepoint-markers" and "strace". * breakpoint.c (is_marker_spec): New. (is_tracepoint): Handle static tracepoints. (validate_commands_for_breakpoint): Static tracepoints can't do while-stepping. (static_tracepoints_here): New. (bpstat_what): Handle static tracepoints. (print_one_breakpoint_location, allocate_bp_location, mention): Ditto. (create_breakpoint_sal): Ditto. (decode_static_tracepoint_spec): New. (create_breakpoint): Replace `hardwareflag', and `traceflag' with `type_wanted'. Adjust. Handle static tracepoint marker locations. (break_command_1): Adjust. (update_static_tracepoint): New. (update_breakpoint_locations): Handle static tracepoints. (breakpoint_re_set_one): Handle static tracepoint marker locations. (disable_command, enable_command): Handle static tracepoints. (trace_command, ftrace_command): Adjust. (strace_command): New. (create_tracepoint_from_upload): Adjust. (save_breakpoints): Handle static tracepoints. (_initialize_breakpoint): Install the "strace" command. * breakpoint.h (enum bptype): New bp_static_tracepoint type. (struct breakpoint): New fields static_trace_marker_id and static_trace_marker_id_idx. (breakpoints_here_p): Declare. (create_breakpoint): Adjust. (static_tracepoints_here): Declare. * remote.c (struct remote_state) <static_tracepoints>: New field. (PACKET_qXfer_statictrace_read, PACKET_StaticTracepoints): New. (remote_static_tracepoint_marker_at): New. (remote_static_tracepoint_markers_by_strid): New. (remote_static_tracepoint_feature): New. (remote_disconnected_tracing_feature): Handle "StaticTracepoints". (remote_xfer_partial): Handle TARGET_OBJECT_STATIC_TRACE_DATA. (remote_supports_static_tracepoints): New. (remote_download_tracepoint): Download static tracepoints. (init_remote_ops): Install remote_static_tracepoint_marker_at and remote_static_tracepoint_markers_by_strid. (_initialize_remote): Install set|show remote static-tracepoints, and set|show remote read-sdata-object commands. * target.c (update_current_target): Inherit and default to_static_tracepoint_marker_at, and to_static_tracepoint_markers_by_strid. * target.h (static_tracepoint_marker): Forward declare. (enum target_object): New object TARGET_OBJECT_STATIC_TRACE_DATA. (static_tracepoint_marker_p): New typedef. (DEF_VEC_P(static_tracepoint_marker_p)): New VEC type. (struct target_ops): New fields to_static_tracepoint_marker_at and to_static_tracepoint_markers_by_strid. (target_static_tracepoint_marker_at) (target_static_tracepoint_markers_by_strid): New. * tracepoint.c: Include source.h. (validate_actionline): Handle $_sdata. (struct collection_list): New field strace_data. (add_static_trace_data): New. (clear_collection_list): Clear strace_data. (stringify_collection_list): Account for a possible static trace data collection. (encode_actions_1): Encode an $_sdata collection. (parse_tracepoint_definition): Handle static tracepoints. (parse_static_tracepoint_marker_definition): New. (release_static_tracepoint_marker): New. (print_one_static_tracepoint_marker): New. (info_static_tracepoint_markers_command): New. (sdata_make_value): New. (_initialize_tracepoint): Create the $_sdata convenience variable. Add the "info static-tracepoint-markers" command. Mention $_sdata in the "collect" command's help output. * tracepoint.h (struct static_tracepoint_marker): New. (parse_static_tracepoint_marker_definition) (release_static_tracepoint_marker): Declare. * mi/mi-cmd-break.c (mi_cmd_break_insert): Adjust. * python/py-breakpoint.c (bppy_new): Adjust. doc/ * gdb.texinfo (Convenience Variables): Document $_sdata. (Commands to Set Tracepoints): Describe static tracepoints. Add `Listing Static Tracepoint Markers' menu entry. Document "strace". (Tracepoint Action Lists): Document collecting $_sdata. (Listing Static Tracepoint Markers): New subsection. (Tracepoints support in gdbserver): Mention static tracepoints. (remote packets, enabling and disabling): Mention read-sdata-object. (General Query Packets) <qSupported>: Document qXfer:sdata:read and StaticTracepoint. Mention qTfSTM, qTsSTM and qTSTMat as tracepoint packets. Document qXfer:sdata:read. (Tracepoint packets): Document qTfSTM, qTsSTM and qTSTMat.
Diffstat (limited to 'gdb/tracepoint.c')
-rw-r--r--gdb/tracepoint.c303
1 files changed, 298 insertions, 5 deletions
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 3aff49b..7b99b1c 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -47,7 +47,7 @@
#include "stack.h"
#include "gdbcore.h"
#include "remote.h"
-
+#include "source.h"
#include "ax.h"
#include "ax-gdb.h"
@@ -622,9 +622,10 @@ validate_actionline (char **line, struct breakpoint *t)
if (*p == '$') /* look for special pseudo-symbols */
{
- if ((0 == strncasecmp ("reg", p + 1, 3)) ||
- (0 == strncasecmp ("arg", p + 1, 3)) ||
- (0 == strncasecmp ("loc", p + 1, 3)))
+ if (0 == strncasecmp ("reg", p + 1, 3)
+ || 0 == strncasecmp ("arg", p + 1, 3)
+ || 0 == strncasecmp ("loc", p + 1, 3)
+ || 0 == strncasecmp ("_sdata", p + 1, 6))
{
p = strchr (p, ',');
continue;
@@ -747,6 +748,9 @@ struct collection_list
long next_aexpr_elt;
struct agent_expr **aexpr_list;
+ /* True is the user requested a collection of "$_sdata", "static
+ tracepoint data". */
+ int strace_data;
}
tracepoint_list, stepping_list;
@@ -1086,6 +1090,14 @@ add_local_symbols (struct collection_list *collect,
}
}
+static void
+add_static_trace_data (struct collection_list *collection)
+{
+ if (info_verbose)
+ printf_filtered ("collect static trace data\n");
+ collection->strace_data = 1;
+}
+
/* worker function */
static void
clear_collection_list (struct collection_list *list)
@@ -1100,6 +1112,7 @@ clear_collection_list (struct collection_list *list)
}
list->next_aexpr_elt = 0;
memset (list->regs_mask, 0, sizeof (list->regs_mask));
+ list->strace_data = 0;
}
/* reduce a collection list to string form (for gdb protocol) */
@@ -1114,9 +1127,19 @@ stringify_collection_list (struct collection_list *list, char *string)
char *end;
long i;
- count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
+ count = 1 + 1 + list->next_memrange + list->next_aexpr_elt + 1;
str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
+ if (list->strace_data)
+ {
+ if (info_verbose)
+ printf_filtered ("\nCollecting static trace data\n");
+ end = temp_buf;
+ *end++ = 'L';
+ (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
+ ndx++;
+ }
+
for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
break;
@@ -1276,6 +1299,11 @@ encode_actions_1 (struct command_line *action,
'L');
action_exp = strchr (action_exp, ','); /* more? */
}
+ else if (0 == strncasecmp ("$_sdata", action_exp, 7))
+ {
+ add_static_trace_data (collect);
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
else
{
unsigned long addr, len;
@@ -3476,6 +3504,11 @@ parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
p++;
p = unpack_varlen_hex (p, &orig_size);
}
+ else if (*p == 'S')
+ {
+ type = bp_static_tracepoint;
+ p++;
+ }
else if (*p == 'X')
{
p++;
@@ -4075,12 +4108,266 @@ init_tfile_ops (void)
tfile_ops.to_magic = OPS_MAGIC;
}
+/* Given a line of text defining a static tracepoint marker, parse it
+ into a "static tracepoint marker" object. Throws an error is
+ parsing fails. If PP is non-null, it points to one past the end of
+ the parsed marker definition. */
+
+void
+parse_static_tracepoint_marker_definition (char *line, char **pp,
+ struct static_tracepoint_marker *marker)
+{
+ char *p, *endp;
+ ULONGEST addr;
+ int end;
+
+ p = line;
+ p = unpack_varlen_hex (p, &addr);
+ p++; /* skip a colon */
+
+ marker->gdbarch = target_gdbarch;
+ marker->address = (CORE_ADDR) addr;
+
+ endp = strchr (p, ':');
+ if (endp == NULL)
+ error ("bad marker definition: %s", line);
+
+ marker->str_id = xmalloc (endp - p + 1);
+ end = hex2bin (p, (gdb_byte *) marker->str_id, (endp - p + 1) / 2);
+ marker->str_id[end] = '\0';
+
+ p += 2 * end;
+ p++; /* skip a colon */
+
+ marker->extra = xmalloc (strlen (p) + 1);
+ end = hex2bin (p, (gdb_byte *) marker->extra, strlen (p) / 2);
+ marker->extra[end] = '\0';
+
+ if (pp)
+ *pp = p;
+}
+
+/* Release a static tracepoint marker's contents. Note that the
+ object itself isn't released here. There objects are usually on
+ the stack. */
+
+void
+release_static_tracepoint_marker (struct static_tracepoint_marker *marker)
+{
+ xfree (marker->str_id);
+ marker->str_id = NULL;
+}
+
+/* Print MARKER to gdb_stdout. */
+
+static void
+print_one_static_tracepoint_marker (int count,
+ struct static_tracepoint_marker *marker)
+{
+ struct command_line *l;
+ struct symbol *sym;
+
+ char wrap_indent[80];
+ char extra_field_indent[80];
+ struct ui_stream *stb = ui_out_stream_new (uiout);
+ struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
+ struct cleanup *bkpt_chain;
+ VEC(breakpoint_p) *tracepoints;
+
+ struct symtab_and_line sal;
+
+ init_sal (&sal);
+
+ sal.pc = marker->address;
+
+ tracepoints = static_tracepoints_here (marker->address);
+
+ bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "marker");
+
+ /* A counter field to help readability. This is not a stable
+ identifier! */
+ ui_out_field_int (uiout, "count", count);
+
+ ui_out_field_string (uiout, "marker-id", marker->str_id);
+
+ ui_out_field_fmt (uiout, "enabled", "%c",
+ !VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n');
+ ui_out_spaces (uiout, 2);
+
+ strcpy (wrap_indent, " ");
+
+ if (gdbarch_addr_bit (marker->gdbarch) <= 32)
+ strcat (wrap_indent, " ");
+ else
+ strcat (wrap_indent, " ");
+
+ strcpy (extra_field_indent, " ");
+
+ ui_out_field_core_addr (uiout, "addr", marker->gdbarch, marker->address);
+
+ sal = find_pc_line (marker->address, 0);
+ sym = find_pc_sect_function (marker->address, NULL);
+ if (sym)
+ {
+ ui_out_text (uiout, "in ");
+ ui_out_field_string (uiout, "func",
+ SYMBOL_PRINT_NAME (sym));
+ ui_out_wrap_hint (uiout, wrap_indent);
+ ui_out_text (uiout, " at ");
+ }
+ else
+ ui_out_field_skip (uiout, "func");
+
+ if (sal.symtab != NULL)
+ {
+ ui_out_field_string (uiout, "file", sal.symtab->filename);
+ ui_out_text (uiout, ":");
+
+ if (ui_out_is_mi_like_p (uiout))
+ {
+ char *fullname = symtab_to_fullname (sal.symtab);
+
+ if (fullname)
+ ui_out_field_string (uiout, "fullname", fullname);
+ }
+ else
+ ui_out_field_skip (uiout, "fullname");
+
+ ui_out_field_int (uiout, "line", sal.line);
+ }
+ else
+ {
+ ui_out_field_skip (uiout, "fullname");
+ ui_out_field_skip (uiout, "line");
+ }
+
+ ui_out_text (uiout, "\n");
+ ui_out_text (uiout, extra_field_indent);
+ ui_out_text (uiout, _("Data: \""));
+ ui_out_field_string (uiout, "extra-data", marker->extra);
+ ui_out_text (uiout, "\"\n");
+
+ if (!VEC_empty (breakpoint_p, tracepoints))
+ {
+ struct cleanup *cleanup_chain;
+ int ix;
+ struct breakpoint *b;
+
+ cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
+ "tracepoints-at");
+
+ ui_out_text (uiout, extra_field_indent);
+ ui_out_text (uiout, _("Probed by static tracepoints: "));
+ for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
+ {
+ if (ix > 0)
+ ui_out_text (uiout, ", ");
+ ui_out_text (uiout, "#");
+ ui_out_field_int (uiout, "tracepoint-id", b->number);
+ }
+
+ do_cleanups (cleanup_chain);
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_int (uiout, "number-of-tracepoints",
+ VEC_length(breakpoint_p, tracepoints));
+ else
+ ui_out_text (uiout, "\n");
+ }
+ VEC_free (breakpoint_p, tracepoints);
+
+ do_cleanups (bkpt_chain);
+ do_cleanups (old_chain);
+}
+
+static void
+info_static_tracepoint_markers_command (char *arg, int from_tty)
+{
+ VEC(static_tracepoint_marker_p) *markers;
+ struct cleanup *old_chain;
+ struct static_tracepoint_marker *marker;
+ int i;
+
+ old_chain
+ = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
+ "StaticTracepointMarkersTable");
+
+ ui_out_table_header (uiout, 7, ui_left, "counter", "Cnt");
+
+ ui_out_table_header (uiout, 40, ui_left, "marker-id", "ID");
+
+ ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");
+ if (gdbarch_addr_bit (target_gdbarch) <= 32)
+ ui_out_table_header (uiout, 10, ui_left, "addr", "Address");
+ else
+ ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
+ ui_out_table_header (uiout, 40, ui_noalign, "what", "What");
+
+ ui_out_table_body (uiout);
+
+ markers = target_static_tracepoint_markers_by_strid (NULL);
+ make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
+
+ for (i = 0;
+ VEC_iterate (static_tracepoint_marker_p,
+ markers, i, marker);
+ i++)
+ {
+ print_one_static_tracepoint_marker (i + 1, marker);
+ release_static_tracepoint_marker (marker);
+ }
+
+ do_cleanups (old_chain);
+}
+
+/* The $_sdata convenience variable is a bit special. We don't know
+ for sure type of the value until we actually have a chance to fetch
+ the data --- the size of the object depends on what has been
+ collected. We solve this by making $_sdata be an internalvar that
+ creates a new value on access. */
+
+/* Return a new value with the correct type for the sdata object of
+ the current trace frame. Return a void value if there's no object
+ available. */
+
+static struct value *
+sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var)
+{
+ LONGEST size;
+ gdb_byte *buf;
+
+ /* We need to read the whole object before we know its size. */
+ size = target_read_alloc (&current_target,
+ TARGET_OBJECT_STATIC_TRACE_DATA,
+ NULL, &buf);
+ if (size >= 0)
+ {
+ struct value *v;
+ struct type *type;
+
+ type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
+ size);
+ v = allocate_value (type);
+ memcpy (value_contents_raw (v), buf, size);
+ xfree (buf);
+ return v;
+ }
+ else
+ return allocate_value (builtin_type (gdbarch)->builtin_void);
+}
+
/* module initialization */
void
_initialize_tracepoint (void)
{
struct cmd_list_element *c;
+ /* Explicitly create without lookup, since that tries to create a
+ value with a void typed value, and when we get here, gdbarch
+ isn't initialized yet. At this point, we're quite sure there
+ isn't another convenience variable of the same name. */
+ create_internalvar_type_lazy ("_sdata", sdata_make_value);
+
traceframe_number = -1;
tracepoint_number = -1;
@@ -4143,6 +4430,11 @@ If no arguments are supplied, delete all variables."), &deletelist);
Status of trace state variables and their values.\n\
"));
+ add_info ("static-tracepoint-markers",
+ info_static_tracepoint_markers_command, _("\
+List target static tracepoints markers.\n\
+"));
+
add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
Select a trace frame;\n\
No argument means forward by one frame; '-' means backward by one frame."),
@@ -4223,6 +4515,7 @@ Also accepts the following special arguments:\n\
$regs -- all registers.\n\
$args -- all function arguments.\n\
$locals -- all variables local to the block/function scope.\n\
+ $_sdata -- static tracepoint data (ignored for non-static tracepoints).\n\
Note: this command can only be used in a tracepoint \"actions\" list."));
add_com ("teval", class_trace, teval_pseudocommand, _("\