aboutsummaryrefslogtreecommitdiff
path: root/gdb/tracepoint.c
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>2010-03-17 22:04:43 +0000
committerStan Shebs <shebs@codesourcery.com>2010-03-17 22:04:43 +0000
commit400c6af0377b41453355299e9393a52263f4a834 (patch)
tree82355d6b37f45abf19392712a0c747cf989c4f6e /gdb/tracepoint.c
parenta3b2a86bb7263eafa4f11a3b7cc0fb3adcfe1d39 (diff)
downloadfsf-binutils-gdb-400c6af0377b41453355299e9393a52263f4a834.zip
fsf-binutils-gdb-400c6af0377b41453355299e9393a52263f4a834.tar.gz
fsf-binutils-gdb-400c6af0377b41453355299e9393a52263f4a834.tar.bz2
2010-03-17 Stan Shebs <stan@codesourcery.com>
* ax-gdb.h (struct axs_value): New field optimized_out. (gen_trace_for_var): Add gdbarch argument. * ax-gdb.c (gen_trace_static_fields): New function. (gen_traced_pop): Call it, add gdbarch argument. (gen_trace_for_expr): Update call to it. (gen_trace_for_var): Ditto, and report optimized-out variables. (gen_struct_ref_recursive): Check for optimized-out value. (gen_struct_elt_for_reference): Ditto. (gen_static_field): Pass gdbarch instead of expression, assume optimization if field not found. (gen_var_ref): Set the optimized_out flag. (gen_expr): Error on optimized-out variable. * tracepoint.c (collect_symbol): Handle struct-valued vars as expressions, skip optimized-out variables with computed locations. * dwarf2loc.c (dwarf2_tracepoint_var_ref): Flag instead of erroring out if location expression missing. (loclist_tracepoint_var_ref): Don't error out here.
Diffstat (limited to 'gdb/tracepoint.c')
-rw-r--r--gdb/tracepoint.c103
1 files changed, 61 insertions, 42 deletions
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index e1679fa..b621334 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -949,6 +949,7 @@ collect_symbol (struct collection_list *collect,
unsigned long len;
unsigned int reg;
bfd_signed_vma offset;
+ int treat_as_expr = 0;
len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
switch (SYMBOL_CLASS (sym))
@@ -973,7 +974,12 @@ collect_symbol (struct collection_list *collect,
SYMBOL_PRINT_NAME (sym), len,
tmp /* address */);
}
- add_memrange (collect, memrange_absolute, offset, len);
+ /* A struct may be a C++ class with static fields, go to general
+ expression handling. */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
+ treat_as_expr = 1;
+ else
+ add_memrange (collect, memrange_absolute, offset, len);
break;
case LOC_REGISTER:
reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
@@ -1038,49 +1044,62 @@ collect_symbol (struct collection_list *collect,
break;
case LOC_COMPUTED:
- {
- struct agent_expr *aexpr;
- struct cleanup *old_chain1 = NULL;
- struct agent_reqs areqs;
-
- aexpr = gen_trace_for_var (scope, sym);
-
- old_chain1 = make_cleanup_free_agent_expr (aexpr);
-
- ax_reqs (aexpr, &areqs);
- if (areqs.flaw != agent_flaw_none)
- error (_("malformed expression"));
-
- if (areqs.min_height < 0)
- error (_("gdb: Internal error: expression has min height < 0"));
- if (areqs.max_height > 20)
- error (_("expression too complicated, try simplifying"));
-
- discard_cleanups (old_chain1);
- add_aexpr (collect, aexpr);
-
- /* take care of the registers */
- if (areqs.reg_mask_len > 0)
- {
- int ndx1, ndx2;
-
- for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
- {
- QUIT; /* allow user to bail out with ^C */
- if (areqs.reg_mask[ndx1] != 0)
- {
- /* assume chars have 8 bits */
- for (ndx2 = 0; ndx2 < 8; ndx2++)
- if (areqs.reg_mask[ndx1] & (1 << ndx2))
- /* it's used -- record it */
- add_register (collect,
- ndx1 * 8 + ndx2);
- }
- }
- }
- }
+ treat_as_expr = 1;
break;
}
+
+ /* Expressions are the most general case. */
+ if (treat_as_expr)
+ {
+ struct agent_expr *aexpr;
+ struct cleanup *old_chain1 = NULL;
+ struct agent_reqs areqs;
+
+ aexpr = gen_trace_for_var (scope, gdbarch, sym);
+
+ /* It can happen that the symbol is recorded as a computed
+ location, but it's been optimized away and doesn't actually
+ have a location expression. */
+ if (!aexpr)
+ {
+ printf_filtered ("%s has been optimized out of existence.\n",
+ SYMBOL_PRINT_NAME (sym));
+ return;
+ }
+
+ old_chain1 = make_cleanup_free_agent_expr (aexpr);
+
+ ax_reqs (aexpr, &areqs);
+ if (areqs.flaw != agent_flaw_none)
+ error (_("malformed expression"));
+
+ if (areqs.min_height < 0)
+ error (_("gdb: Internal error: expression has min height < 0"));
+ if (areqs.max_height > 20)
+ error (_("expression too complicated, try simplifying"));
+
+ discard_cleanups (old_chain1);
+ add_aexpr (collect, aexpr);
+
+ /* take care of the registers */
+ if (areqs.reg_mask_len > 0)
+ {
+ int ndx1, ndx2;
+
+ for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (areqs.reg_mask[ndx1] != 0)
+ {
+ /* assume chars have 8 bits */
+ for (ndx2 = 0; ndx2 < 8; ndx2++)
+ if (areqs.reg_mask[ndx1] & (1 << ndx2))
+ /* it's used -- record it */
+ add_register (collect, ndx1 * 8 + ndx2);
+ }
+ }
+ }
+ }
}
/* Add all locals (or args) symbols to collection list */