diff options
author | Stan Shebs <shebs@codesourcery.com> | 2010-03-17 22:04:43 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 2010-03-17 22:04:43 +0000 |
commit | 400c6af0377b41453355299e9393a52263f4a834 (patch) | |
tree | 82355d6b37f45abf19392712a0c747cf989c4f6e /gdb/tracepoint.c | |
parent | a3b2a86bb7263eafa4f11a3b7cc0fb3adcfe1d39 (diff) | |
download | gdb-400c6af0377b41453355299e9393a52263f4a834.zip gdb-400c6af0377b41453355299e9393a52263f4a834.tar.gz 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.c | 103 |
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 */ |