This is the mail archive of the gdb@sources.redhat.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]
Other format: [Raw text]

Re: does bpstat_print stop printing prematurely?


Eli Zaretskii writes:
 > Do you actually have an example of this, or can craft one?

Trivially.

 > You see, I think it's all but impossible to have a breakpoint and a 
 > watchpoint trigger at the same PC.  That's because the CPU carefully 
 > designs its faults and traps so that one always preceeds the other.

Nope.  When control stops, all gdb may know is that _some_ breakpoint hit.
[where "breakpoint" here includes "watchpoint" but no matter]
Some targets may assist gdb in partially distinguishing them, but
such a distinction is insufficient.

Note for example that you can have multiple pc breakpoints at the
same location.  This is useful if each has its own condition and commands.
When execution stops, gdb can't know which of the two triggered because
it hasn't evaluated the conditions yet.  The distinction between the
two is a gdb artifact and there's nothing the O/S (*) can do to tell
gdb which of the two fired: all gdb told the O/S was "stop at this pc
value please."

Thus when execution stops there can be several reasons.
The `stop_bpstat' list records all of them.
And gdb makes an effort to print all of them (or some of them) which is great,
but it'd be nice if the effort was complete.

Now, if the gdb maintainers want to make the bug go away by defining
it away that's their prerogative.  It's a step backwards though.

(*): or embedded system or simulator or ... etc.

 > Cannot reproduce this on my machine with GDB 5.1.1: if I set two 
 > watchpoints on the same address, GDB announces both of them.  Please tell 
 > what OS did you try that on, and which version of GDB was that.

You need to recreate the conditions of having the stop_bpstat list contain
a watchpoint, then a pc breakpoint, then another watchpoint.
bpstat_print will stop printing at the pc breakpoint, but it hasn't
printed the final watchpoint yet.

Here's a session showing how to recreate it.

The first gdb session shows gdb printing all 3 breakpoints: two watchpoints
and a pc breakpoint.  It does this because of the order in which the 3 were
created.  The second gdb session shows gdb not printing the second watchpoint.
In this case the second watchpoint was created after the pc breakpoint.

A quick skim of the code will explain why gdb is behaving this way.
I'm hoping people will agree it's a bug rather than defining the problem away.

casey:~$ cat -n foo.c
     1	int foo;
     2	int bar;
     3	
     4	int
     5	main ()
     6	{
     7	    foo = 42;
     8	    return 0;
     9	}
casey:~$ gcc -g foo.c


casey:~$ gdb-5.1.1 a.out
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) watch foo
Hardware watchpoint 1: foo
(gdb) cond 1 bar != -1
(gdb) watch foo
Hardware watchpoint 2: foo
(gdb) cond 2 bar >= 0
(gdb) b foo.c:8
Breakpoint 3 at 0x80483ad: file foo.c, line 8.
(gdb) b main
Breakpoint 4 at 0x80483a3: file foo.c, line 7.
(gdb) r
Starting program: /home/dje/a.out 
Hardware watchpoint 1: foo
Hardware watchpoint 2: foo
Hardware watchpoint 1: foo
Hardware watchpoint 2: foo

Breakpoint 4, main () at foo.c:7
7	    foo = 42;
(gdb) c
Continuing.
Hardware watchpoint 1: foo

Old value = 0
New value = 42
Hardware watchpoint 2: foo

Old value = 0
New value = 42

Breakpoint 3, main () at foo.c:8
8	    return 0;
(gdb) q
The program is running.  Exit anyway? (y or n) y


casey:~$ gdb-5.1.1 a.out
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) watch foo
Hardware watchpoint 1: foo
(gdb) cond 1 bar != -1
(gdb) b foo.c:8
Breakpoint 2 at 0x80483ad: file foo.c, line 8.
(gdb) watch foo
Hardware watchpoint 3: foo
(gdb) cond 3 bar >= 0
(gdb) b main
Breakpoint 4 at 0x80483a3: file foo.c, line 7.
(gdb) i b
Num Type           Disp Enb Address    What
1   hw watchpoint  keep y              foo
	stop only if bar != -1
2   breakpoint     keep y   0x080483ad in main at foo.c:8
3   hw watchpoint  keep y              foo
	stop only if bar >= 0
4   breakpoint     keep y   0x080483a3 in main at foo.c:7
(gdb) r
Starting program: /home/dje/a.out 
Hardware watchpoint 1: foo
Hardware watchpoint 3: foo
Hardware watchpoint 1: foo
Hardware watchpoint 3: foo

Breakpoint 4, main () at foo.c:7
7	    foo = 42;
(gdb) c
Continuing.
Hardware watchpoint 1: foo

Old value = 0
New value = 42

Breakpoint 2, main () at foo.c:8
8	    return 0;
(gdb) q
The program is running.  Exit anyway? (y or n) y
casey:~$ 


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