This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH] More tracepoint fixes
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gdb-patches at sources dot redhat dot com
- Cc: Paul Brook <paul at codesourcery dot com>
- Date: Wed, 09 Feb 2005 09:47:15 +0000
- Subject: [PATCH] More tracepoint fixes
- Organization: Codesourcery LLC
This is a more complicated tracepoint fix. The variable tracing mechanism
does not cope with COMPUTED_LOC and ARG_COMPUTED_LOC symbols, as generated
by gcc 3.4. Expressions containing said symbols are dealt with. This
patch rearranges 'collect_symbol' and 'add_local_symbols' to deal with
such computed symbols. These are dumped as if they were expressions --
hence the breakout of the expression dumping from encode_actions.
built & tested on i686-pc-linux-gnu, and an unreleased remote
architecture. ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2005-02-09 Nathan Sidwell <nathan@codesourcery.com>
* tracepoint.c: #include gdb_assert.h
(collect_symbol): Take a PC and EXP, not a symbol. Adjust. Add
LOC_COMPUTED and LOC_COMPUTED_ARG cases.
(add_local_symbols): Describe the symbol with an expression,
adjust collect_symbol calls, add LOC_COMPUTED and LOC_COMPUTED_ARG
cases.
(encode_actions): Break out expression processing into ...
(add_expression): ... here. New function.
Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.68
diff -c -3 -p -r1.68 tracepoint.c
*** tracepoint.c 2 Feb 2005 00:20:05 -0000 1.68
--- tracepoint.c 9 Feb 2005 09:26:24 -0000
***************
*** 30,35 ****
--- 30,36 ----
#include "target.h"
#include "language.h"
#include "gdb_string.h"
+ #include "gdb_assert.h"
#include "inferior.h"
#include "tracepoint.h"
#include "remote.h"
*************** static void trace_dump_command (char *,
*** 149,154 ****
--- 150,157 ----
static void trace_mention (struct tracepoint *);
struct collection_list;
+ static void add_expression (struct collection_list *, CORE_ADDR pc,
+ struct expression *);
static void add_aexpr (struct collection_list *, struct agent_expr *);
static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
static void add_register (struct collection_list *collection,
*************** add_memrange (struct collection_list *me
*** 1191,1204 ****
/* Add a symbol to a collection list. */
static void
! collect_symbol (struct collection_list *collect,
! struct symbol *sym,
long frame_regno, long frame_offset)
{
unsigned long len;
unsigned int reg;
bfd_signed_vma offset;
!
len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
switch (SYMBOL_CLASS (sym))
{
--- 1194,1210 ----
/* Add a symbol to a collection list. */
static void
! collect_symbol (struct collection_list *collect, CORE_ADDR pc,
! struct expression *exp,
long frame_regno, long frame_offset)
{
unsigned long len;
unsigned int reg;
bfd_signed_vma offset;
! struct symbol *sym;
!
! gdb_assert (exp->elts[0].opcode == OP_VAR_VALUE);
! sym = exp->elts[2].symbol;
len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
switch (SYMBOL_CLASS (sym))
{
*************** collect_symbol (struct collection_list *
*** 1300,1305 ****
--- 1306,1319 ----
printf_filtered ("%s has been optimized out of existence.\n",
DEPRECATED_SYMBOL_NAME (sym));
break;
+ case LOC_COMPUTED:
+ case LOC_COMPUTED_ARG:
+ /* collect the expression. */
+ if (info_verbose)
+ SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
+
+ add_expression (collect, pc, exp);
+ break;
}
}
*************** add_local_symbols (struct collection_lis
*** 1312,1324 ****
struct block *block;
struct dict_iterator iter;
int count = 0;
!
block = block_for_pc (pc);
while (block != 0)
{
QUIT; /* allow user to bail out with ^C */
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
switch (SYMBOL_CLASS (sym))
{
default:
--- 1326,1355 ----
struct block *block;
struct dict_iterator iter;
int count = 0;
! struct expression *exp;
! struct cleanup *old_chain = NULL;
!
! exp = xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (4));
!
! exp->language_defn = NULL;
! exp->nelts = 4;
! exp->elts[0].opcode = OP_VAR_VALUE;
! exp->elts[1].block = NULL;
! exp->elts[2].symbol = NULL;
! exp->elts[3].opcode = OP_VAR_VALUE;
!
! old_chain = make_cleanup (free_current_contents, &exp);
!
block = block_for_pc (pc);
while (block != 0)
{
+ exp->elts[1].block = block;
+
QUIT; /* allow user to bail out with ^C */
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
+ exp->elts[2].symbol = sym;
+
switch (SYMBOL_CLASS (sym))
{
default:
*************** add_local_symbols (struct collection_lis
*** 1328,1338 ****
case LOC_STATIC:
case LOC_REGISTER:
case LOC_BASEREG:
if (type == 'L') /* collecting Locals */
{
count++;
! collect_symbol (collect, sym, frame_regno,
! frame_offset);
}
break;
case LOC_ARG:
--- 1359,1370 ----
case LOC_STATIC:
case LOC_REGISTER:
case LOC_BASEREG:
+ case LOC_COMPUTED:
if (type == 'L') /* collecting Locals */
{
count++;
! collect_symbol (collect, pc, exp,
! frame_regno, frame_offset);
}
break;
case LOC_ARG:
*************** add_local_symbols (struct collection_lis
*** 1341,1351 ****
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
if (type == 'A') /* collecting Arguments */
{
count++;
! collect_symbol (collect, sym, frame_regno,
! frame_offset);
}
}
}
--- 1373,1384 ----
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
+ case LOC_COMPUTED_ARG:
if (type == 'A') /* collecting Arguments */
{
count++;
! collect_symbol (collect, pc, exp,
! frame_regno, frame_offset);
}
}
}
*************** add_local_symbols (struct collection_lis
*** 1354,1359 ****
--- 1387,1395 ----
else
block = BLOCK_SUPERBLOCK (block);
}
+
+ do_cleanups (old_chain);
+
if (count == 0)
warning ("No %s found in scope.",
type == 'L' ? "locals" : "args");
*************** encode_actions (struct tracepoint *t, ch
*** 1509,1515 ****
struct value *tempval;
struct collection_list *collect;
struct cmd_list_element *cmd;
- struct agent_expr *aexpr;
int frame_reg;
LONGEST frame_offset;
--- 1545,1550 ----
*************** encode_actions (struct tracepoint *t, ch
*** 1571,1580 ****
}
else
{
- unsigned long addr, len;
struct cleanup *old_chain = NULL;
! struct cleanup *old_chain1 = NULL;
! struct agent_reqs areqs;
exp = parse_exp_1 (&action_exp,
block_for_pc (t->address), 1);
--- 1606,1613 ----
}
else
{
struct cleanup *old_chain = NULL;
! unsigned long addr, len;
exp = parse_exp_1 (&action_exp,
block_for_pc (t->address), 1);
*************** encode_actions (struct tracepoint *t, ch
*** 1598,1646 ****
break;
case OP_VAR_VALUE:
! collect_symbol (collect,
! exp->elts[2].symbol,
! frame_reg,
! frame_offset);
break;
default: /* full-fledged expression */
! aexpr = gen_trace_for_expr (t->address, exp);
!
! 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;
! int 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);
! }
! }
! }
break;
} /* switch */
do_cleanups (old_chain);
--- 1631,1642 ----
break;
case OP_VAR_VALUE:
! collect_symbol (collect, t->address, exp,
! frame_reg, frame_offset);
break;
default: /* full-fledged expression */
! add_expression (collect, t->address, exp);
break;
} /* switch */
do_cleanups (old_chain);
*************** encode_actions (struct tracepoint *t, ch
*** 1669,1674 ****
--- 1665,1719 ----
step_buff);
}
+ /* Add an arbitrary expression. */
+
+ static void
+ add_expression (struct collection_list *collect, CORE_ADDR pc,
+ struct expression *exp)
+ {
+ struct agent_expr *aexpr;
+ struct agent_reqs areqs;
+ struct cleanup *old_chain = NULL;
+
+ aexpr = gen_trace_for_expr (pc, exp);
+
+ old_chain = 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_chain);
+
+ add_aexpr (collect, aexpr);
+
+ /* take care of the registers */
+ if (areqs.reg_mask_len > 0)
+ {
+ int ndx1;
+ int 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);
+ }
+ }
+ }
+ return;
+ }
+
static void
add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
{