This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Hardware watchpoints



> What expressions did you try to watch?  What chains of values did they
> produce?  Which ones are lazy, and which ones aren't?

Thanks for the explanations.

A simple test program is attached at the end of this message.  (It's a
program I used for testing several different aspects of watchpoints,
so not everything it includes is relevant to the issue at hand.)

An abridged script of a GDB session follows.  As you see, I watched
two different members of a struct variable `foo_var': `foo_var.iv' and
`foo_var.jv'.  GDB produced two value chains, each one including the
struct member and the struct itself--all of them marked as lazy.

Perhaps we could use v->type.code in the decision whether to watch any
values but the first one on the value chain?

One question that I still can't figure out is why does GDB at all
_need_ to have the parent struct on the value chain?  Where is that
information used?

Also, the v->type member for the parent struct has a NULL type.name
member.  Unless I misunderstood gdbtypes.h, it seems to imply that
name should be "struct" or "struct foo".

Here's the GDB session:

e:/src/gnu/gdb-4.18/gdb> gdb gdb.exe
...
(top-gdb) b breakpoint.c:781
Breakpoint 3 at 0x2c61: file breakpoint.c, line 781
(top-gdb) r fptest4
Starting program: e:/src/gnu/gdb-4.18/gdb/gdb.exe fptest4
...
(gdb) b main
Breakpoint 1 at 0x15bf: file fptest.c, line 7
(gdb) r
Starting program: e:/src/gnu/gdb-4.18/gdb/fptest4

Breakpoint 1, main (argv=1, argv=0x911c4) at fptest.c:7
7	  volatile double a = M_SQRT2;

(gdb) l 21,24
21	argc = a * a;
22	foo_var.iv = argc + 2;
23	foo_var.jv = argc + 3;
24	if (foo_var.iv < 0)
(gdb) watch foo_var.iv
Hardware watchpoint 2: foo_var.iv
(gdb) watch foo_var.jv
Hardware watchpoint 3: foo_var.jv
(gdb) c
Continuing.

Breakpoint 3, insert_breakpoints () at breakpoint.c:781
781		      v = evaluate_expression (b->exp);
(top-gdb) p b->exp_string
$1 = 0x1eabe8 "foo_var.iv"
(top-gdb) p *b->exp
$2 = {language_defn =
During symbol reading, stub type has NULL name.
0xc188, nelts = 9, elts = {{opcode = STRUCTOP_STRUCT, symbol = 0x56,
     ...}}}
(top-gdb) n
782		      value_release_to_mark (mark);
(top-gdb) p *v
$3 = {lval = lval_memory, modifiable = 1, location = {address = 0x90904,
    ...}, offset = 0, bitsize = 0, bitpos = 0, frame_addr = 0,
  type = 0x1e7710, enclosing_type = 0x1e7710, next = 0x1ea6f8,
  substring_addr = {memaddr = 0xea890, ...}, regno = -1, lazy = 1 '\001',
  optimized_out = 0 '\000', embedded_offset = 0, pointed_to_offset = 0,
  bfd_section = 0x0, aligner = {...}}
(top-gdb)p *(struct type *)v->type
$4 = {code = TYPE_CODE_INT, name = 0x1e7754 "int", tag_name = 0x0, length = 4,
    upper_bound_type = 0, lower_bound_type = 0, ..., cv_type = 0x1e7710,
  flags = 0, nfields = 0, fields = 0x0, ..., type_specific = {
    arg_types = 0x0, cplus_stuff = 0x0}}
(top-gdb)p *v->next
$5 = {lval = lval_memory, modifiable = 1, location = {address = 0x90904,
    ...}, offset = 0, bitsize = 0, bitpos = 0, frame_addr = 0,
  type = 0x1e7a3c, enclosing_type = 0x1e7a3c, next = 0x0,
  substring_addr = {memaddr = 0xea890, ...}, regno = -1, lazy = 1 '\001',
  optimized_out = 0 '\000', embedded_offset = 0, pointed_to_offset = 0,
  bfd_section = 0x0, aligner = {...}}
(top-gdb) p *(struct type *)v->next->type
$6 = {code = TYPE_CODE_STRUCT, name = 0x0, tag_name = 0x1ea390 "foo", 
    length = 20, upper_bound_type = 0, lower_bound_type = 0, ...,
  cv_type = 0x1e7a3c, flags = 0, nfields = 5, fields = 0x0x1e7ad4,
  vptr_basetype = 0x0, vptr_fieldno = -1, type_specific = {
    arg_types = 0x13c120, cplus_stuff = 0x13c120}}
(top-gdb) c
Continuing.

Breakpoint 3, insert_breakpoints () at breakpoint.c:781
781		      v = evaluate_expression (b->exp);
(top-gdb) p b->exp_string
$7 = 0x1eabe8 "foo_var.jv"
(top-gdb) n
782		      value_release_to_mark (mark);
(top-gdb) p *v
$8 = {lval = lval_memory, modifiable = 1, location = {address = 0x90904,
    ...}, offset = 16, bitsize = 0, bitpos = 0, frame_addr = 0,
  type = 0x1e7710, enclosing_type = 0x1e7710, next = 0x1ea6f8,
  substring_addr = {memaddr = 0xea890, ...}, regno = -1, lazy = 1 '\001',
  optimized_out = 0 '\000', embedded_offset = 0, pointed_to_offset = 0,
  bfd_section = 0x0, aligner = {...}}
(top-gdb)p *(struct type *)v->type
$9 = {code = TYPE_CODE_INT, name = 0x1e7754 "int", tag_name = 0x0, length = 4,
    upper_bound_type = 0, lower_bound_type = 0, ..., cv_type = 0x1e7710,
  flags = 0, nfields = 0, fields = 0x0, ..., type_specific = {
    arg_types = 0x0, cplus_stuff = 0x0}}
(top-gdb)p *v->next
$10 = {lval = lval_memory, modifiable = 1, location = {address = 0x90904,
     ...}, offset = 0, bitsize = 0, bitpos = 0, frame_addr = 0,
  type = 0x1e7a3c, enclosing_type = 0x1e7a3c, next = 0x0,
  substring_addr = {memaddr = 0xea890, ...}, regno = -1, lazy = 1 '\001',
  optimized_out = 0 '\000', embedded_offset = 0, pointed_to_offset = 0,
  bfd_section = 0x0, aligner = {...}}
(top-gdb) p *(struct type *)v->next->type
$11 = {code = TYPE_CODE_STRUCT, name = 0x0, tag_name = 0x1ea390 "foo", 
    length = 20, upper_bound_type = 0, lower_bound_type = 0, ...,
  cv_type = 0x1e7a3c, flags = 0, nfields = 5, fields = 0x0x1e7ad4,
  vptr_basetype = 0x0, vptr_fieldno = -1, type_specific = {
    arg_types = 0x13c120, cplus_stuff = 0x13c120}}
(top-gdb)

Here's teh source of the test program (the DOS-specific function
getch() reads a single character from the console device in binary
mode):

#include <float.h>
#include <math.h>
#include <stdio.h>

int main (int argc, char *argv[])
{
  volatile double a = M_SQRT2;
  struct foo {
    int iv;
    double dv;
    unsigned flag1:1;
    unsigned flag2:2;
    int jv;
  } foo_var;

  printf ("a squared = %f (should be 2.0)\n", a * a);
  a *= argc + 1;
  getch ();
  printf ("10 log10 (0.5) returns %f (should be -3)\n",
	  10 * log10 (1.0/(a*a)));
  argc = a * a;
  foo_var.iv = argc + 2;
  foo_var.jv = argc + 3;
  if (foo_var.iv < 10)
    foo_var.flag1 = 1;
  if (foo_var.jv < 100)
    foo_var.flag2 = 2;
  return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]