* RE: breaking at for-loop test line
@ 2004-07-29 13:07 Atul Talesara
0 siblings, 0 replies; 12+ messages in thread
From: Atul Talesara @ 2004-07-29 13:07 UTC (permalink / raw)
To: Allen Hopkins, gdb
First of all, my apologies for the length of the reply,
but I thought of taking a inter-mixeded code to assist
the explanation.
One-liner explanation:
When breakpoint is placed at line 7, it corresponds
to the first instruction before beginning of the
for(...)loop, which happens to be the initialization,
hence breakpoint there is hit only once.
For those who are eager for detailed explanation,
can go ahead:
Though the gdb/gcc versions are not relevant for this
discussion, I'm producing them for completeness:
gcc version 3.2
GNU gdb 5.2.1-4 for "i386-redhat-linux"
>
> 1 #include <iostream.h>
> 2
> 3 int main(int argc, char* argv[])
> 4 {
> 5 int i = 0;
> 6
> 7 for (i = 0; i < 3; i++) {
> 8 cout << i << endl;
> 9 }
> 10
> 11 while (i < 6) {
> 12 cout << i++ << endl;
> 13 }
> 14
> 15 exit(0);
> 16 }
>
> If I set a breakpoint at line 7, and another at line 11,
> and "run" and "continue" until exit, it will only break once
> on the for-loop, but it will break on each iteration of the
> while-loop. How does this make sense? Is there any way to
> get a breakpoint at the top of the for-loop to act like the
> while-loop?
Well, when you set the breakpoint at the line of for (...) loop
the break is placed on the instruction which initializes
your loop variable, 'i' in this case.
Here's the edited inter-mixed code:
------------
# objdump -S s.out
int main(int argc, char* argv[])
{
8048608: push %ebp
...
for (i = 0; i < 3; i++) {
804861f: movl $0x0,0xfffffffc(%ebp)
8048626: cmpl $0x2,0xfffffffc(%ebp)
cout << i << endl;
804862e: sub $0x8,%esp
...
8048657: jmp 8048626 <main+0x1e>
while (i < 6) {
804865a: cmpl $0x5,0xfffffffc(%ebp)
...
cout << i++ << endl;
8048662: sub $0x8,%esp
...
8048689: add $0x10,%esp
804868c: jmp 804865a <main+0x52>
------------
And here's the GDB session:
------------
(gdb) b 7
Breakpoint 1 at 0x804861f: file test.cpp, line 7.
(gdb) b 11
Breakpoint 2 at 0x804865a: file test.cpp, line 11.
------------
So if you see carefully, the breakpoint is placed at the
address "0x804861f" which corresponds to
"movl $0x0,0xfffffffc(%ebp)" which is nothing but the
initialization of for() loop "i=0" which is bound to
execute only *once* for the life of the program.
(See the jump at the end of for (..) loop: 0x8048657,
this jumps to "0x8048626" and your break was address
above that!)
On other hand if you see for while() loop, break is placed
at "0x804865a" which corresponds to the comparison instruction:
"cmpl $0x5,0xfffffffc(%ebp)" which is bound to execute
*every time* we loop to the beginning of while().
(See the jump at end of while loop: 0x804868c,
this jumps to "0x804865a" where your break is placed!)
Yes, you guessed it right ...
If you skip the initialization part in the for(...) loop,
you will get the breakpoint behaviour exactly like your
while(...) loop! Here's the mixed-disassembly snippet:
--------
# objdump -S s.out
int main(int argc, char* argv[])
{
8048608: push %ebp
...
for (; i < 3; i++) {
804861f: cmpl $0x2,0xfffffffc(%ebp)
...
cout << i << endl;
8048627: sub $0x8,%esp
...
8048650: jmp 804861f <main+0x17>
GDB Session:
(gdb) b 7
Breakpoint 1 at 0x804861f: file s.cpp, line 7.
--------
In this case the jump at the end of for() loop
(0x8048650) corresponds to the condition of the
for() loop (0x804861f) and the breakpoint at line
7 indeed behaves like break on while().
Hope the breakpoint behaviour now makes sense :-)
Allen, you can check the same with your platform,
I don't have access to Sol box.
Regards,
Atul P Talesara
----------------------------------------------------------
Begin with an End in mind.
----------------------------------------------------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* breaking at for-loop test line
@ 2004-07-29 5:10 Allen Hopkins
2004-07-29 16:29 ` Daniel Jacobowitz
0 siblings, 1 reply; 12+ messages in thread
From: Allen Hopkins @ 2004-07-29 5:10 UTC (permalink / raw)
To: gdb
Is there a way to break at the test statement of a for-loop
on every iteration, the same way a while-loop works? Here's
what I mean:
1 #include <iostream.h>
2
3 int main(int argc, char* argv[])
4 {
5 int i = 0;
6
7 for (i = 0; i < 3; i++) {
8 cout << i << endl;
9 }
10
11 while (i < 6) {
12 cout << i++ << endl;
13 }
14
15 exit(0);
16 }
If I set a breakpoint at line 7, and another at line 11,
and "run" and "continue" until exit, it will only break once
on the for-loop, but it will break on each iteration of the
while-loop. How does this make sense? Is there any way to
get a breakpoint at the top of the for-loop to act like the
while-loop?
Here's the compile command:
> g++ -ggdb -Wno-deprecated -o s s.cpp
There's no optimization going on that I'm not aware of,
is there?
Here's sample gdb output:
(gdb) break 7
Breakpoint 1 at 0x10b04: file s.cpp, line 7.
(gdb) break 11
Breakpoint 2 at 0x10b5c: file s.cpp, line 11.
(gdb) run
Starting program:
/export/home/allenh/projects/metropolis/testing/foodir/s
Breakpoint 1, main (argc=1, argv=0xffbeecac) at s.cpp:7
7 for (i = 0; i < 3; i++) {
(gdb) c
Continuing.
0
1
2
Breakpoint 2, main (argc=1, argv=0xffbeecac) at s.cpp:11
11 while (i < 6) {
(gdb) c
Continuing.
3
Breakpoint 2, main (argc=1, argv=0xffbeecac) at s.cpp:11
11 while (i < 6) {
(gdb) c
Continuing.
4
Breakpoint 2, main (argc=1, argv=0xffbeecac) at s.cpp:11
11 while (i < 6) {
(gdb) c
Continuing.
5
Breakpoint 2, main (argc=1, argv=0xffbeecac) at s.cpp:11
11 while (i < 6) {
(gdb) c
Continuing.
Program exited normally.
(gdb)
Any advice appreciated.
Oh, yeah...
Sun Solaris 2.8
gcc 3.2.2
gdb 6.0
Thanks.
-Allen Hopkins
UC Berkeley
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-07-29 5:10 Allen Hopkins
@ 2004-07-29 16:29 ` Daniel Jacobowitz
2004-07-29 18:58 ` Andre Ancelin
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Daniel Jacobowitz @ 2004-07-29 16:29 UTC (permalink / raw)
To: Allen Hopkins; +Cc: gdb
On Wed, Jul 28, 2004 at 04:09:14PM -0700, Allen Hopkins wrote:
> Is there a way to break at the test statement of a for-loop
> on every iteration, the same way a while-loop works? Here's
> what I mean:
>
> 1 #include <iostream.h>
> 2
> 3 int main(int argc, char* argv[])
> 4 {
> 5 int i = 0;
> 6
> 7 for (i = 0; i < 3; i++) {
> 8 cout << i << endl;
> 9 }
> 10
> 11 while (i < 6) {
> 12 cout << i++ << endl;
> 13 }
> 14
> 15 exit(0);
> 16 }
>
> If I set a breakpoint at line 7, and another at line 11,
> and "run" and "continue" until exit, it will only break once
> on the for-loop, but it will break on each iteration of the
> while-loop. How does this make sense? Is there any way to
> get a breakpoint at the top of the for-loop to act like the
> while-loop?
What Atul wrote is basically correct; GDB can only pick one breakpoint
location for a particular line number, and it picks the beginning of
the line.
It would be nice if there were a way to set a breakpoint at the
condition, but we don't have enough information to know for sure where
the "condition" part is; and we don't want to always set breakpoints at
every part of a line, because it makes breakpoints on simple statements
that get broken up by ptimization very awkward to work with.
I've been thinking for a while about a better interface for this, but I
haven't come up with one yet.
In the mean time, you can take a look at the disassembly, figure out
where the condition is, and set a breakpoint there using break *<addr>.
GDB could also make it much easier to figure out where the condition is
than it does now...
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-07-29 16:29 ` Daniel Jacobowitz
@ 2004-07-29 18:58 ` Andre Ancelin
[not found] ` <drow@false.org>
2004-07-30 11:32 ` Eli Zaretskii
2 siblings, 0 replies; 12+ messages in thread
From: Andre Ancelin @ 2004-07-29 18:58 UTC (permalink / raw)
To: Daniel Jacobowitz, Allen Hopkins; +Cc: gdb
On Thursday 29 July 2004 11:29, Daniel Jacobowitz wrote:
This works.
7 for (i = 0; i < 3;
8 i++) {
9 cout << i << endl;
10 }
with a breakpoint at 8. It will stop for each pass. If you try
7 for (i = 0;
8 i < 3;
9 i++) {
10 cout << i << endl;
11 }
with breakpoints at 7, 8, & 9, you stop at each line once, then at line 9 two
more times, then out. It does not, however, stop again at line 8 for each
pass or at terminus (?). You can, however, add a breakpoint on line 11 and
you will break at the next statement after line 11 upon terminus.
Some might call this style ugly or wasteful, but I have found it much more
debug friendly to leave all conditional tests on lines by themselves. Another
simple example:
if (i < 6 ||
i > 9)
{
<do_something>
}
> On Wed, Jul 28, 2004 at 04:09:14PM -0700, Allen Hopkins wrote:
> > Is there a way to break at the test statement of a for-loop
> > on every iteration, the same way a while-loop works? Here's
> > what I mean:
> >
> > 1 #include <iostream.h>
> > 2
> > 3 int main(int argc, char* argv[])
> > 4 {
> > 5 int i = 0;
> > 6
> > 7 for (i = 0; i < 3; i++) {
> > 8 cout << i << endl;
> > 9 }
> > 10
> > 11 while (i < 6) {
> > 12 cout << i++ << endl;
> > 13 }
> > 14
> > 15 exit(0);
> > 16 }
> >
> > If I set a breakpoint at line 7, and another at line 11,
> > and "run" and "continue" until exit, it will only break once
> > on the for-loop, but it will break on each iteration of the
> > while-loop. How does this make sense? Is there any way to
> > get a breakpoint at the top of the for-loop to act like the
> > while-loop?
>
> What Atul wrote is basically correct; GDB can only pick one breakpoint
> location for a particular line number, and it picks the beginning of
> the line.
>
> It would be nice if there were a way to set a breakpoint at the
> condition, but we don't have enough information to know for sure where
> the "condition" part is; and we don't want to always set breakpoints at
> every part of a line, because it makes breakpoints on simple statements
> that get broken up by ptimization very awkward to work with.
>
> I've been thinking for a while about a better interface for this, but I
> haven't come up with one yet.
>
> In the mean time, you can take a look at the disassembly, figure out
> where the condition is, and set a breakpoint there using break *<addr>.
> GDB could also make it much easier to figure out where the condition is
> than it does now...
--
Andre Ancelin
VP/CTO Adtec Digital, Inc
andrea@adtecinc.com
www.adtecinc.com
^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <drow@false.org>]
* Re: breaking at for-loop test line
[not found] ` <drow@false.org>
@ 2004-07-29 22:21 ` Felix Lee
2004-07-30 8:23 ` Baurjan Ismagulov
0 siblings, 1 reply; 12+ messages in thread
From: Felix Lee @ 2004-07-29 22:21 UTC (permalink / raw)
To: gdb
Daniel Jacobowitz <drow@false.org>:
> I've been thinking for a while about a better interface for this, but I
> haven't come up with one yet.
>
> In the mean time, you can take a look at the disassembly, figure out
> where the condition is, and set a breakpoint there using break *<addr>.
> GDB could also make it much easier to figure out where the condition is
> than it does now...
how about just that. something like "asm 30" that will print all
the machine instructions that correspond to line 30 of the
source. in a gui, this would be something like, selecting a
source line would highlight the corresponding lines in a
disassembly window. or in a mixed source/asm window, an option
to choose whether it's ordered by source or by asm.
--
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-07-29 22:21 ` Felix Lee
@ 2004-07-30 8:23 ` Baurjan Ismagulov
[not found] ` <ibr@ata.cs.hun.edu.tr>
0 siblings, 1 reply; 12+ messages in thread
From: Baurjan Ismagulov @ 2004-07-30 8:23 UTC (permalink / raw)
To: gdb
Hello Felix,
On Thu, Jul 29, 2004 at 11:58:40AM -0700, Felix Lee wrote:
> how about just that. something like "asm 30" that will print all
> the machine instructions that correspond to line 30 of the
> source.
Do you mean something like the following?
(gdb) info line 223
Line 223 of "main.c" starts at address 0x804e384 <main+64>
and ends at 0x804e3a0 <main+92>.
(gdb) disas 0x804e384 0x804e3a0
With kind regards,
Baurjan.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-07-29 16:29 ` Daniel Jacobowitz
2004-07-29 18:58 ` Andre Ancelin
[not found] ` <drow@false.org>
@ 2004-07-30 11:32 ` Eli Zaretskii
2004-08-03 19:21 ` Daniel Jacobowitz
2 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2004-07-30 11:32 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: allenh, gdb
> Date: Thu, 29 Jul 2004 11:29:40 -0400
> From: Daniel Jacobowitz <drow@false.org>
>
> I've been thinking for a while about a better interface for this, but I
> haven't come up with one yet.
Does GCC tell us in any way (via the debug info) that a single source
line has more than a single statement?
If not, the only way for GDB to figure that out is to parse the source
code by itself.
> GDB could also make it much easier to figure out where the condition is
> than it does now...
How?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-07-30 11:32 ` Eli Zaretskii
@ 2004-08-03 19:21 ` Daniel Jacobowitz
2004-08-03 20:09 ` Andrew Cagney
0 siblings, 1 reply; 12+ messages in thread
From: Daniel Jacobowitz @ 2004-08-03 19:21 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: allenh, gdb
On Fri, Jul 30, 2004 at 01:43:28PM +0200, Eli Zaretskii wrote:
> > Date: Thu, 29 Jul 2004 11:29:40 -0400
> > From: Daniel Jacobowitz <drow@false.org>
> >
> > I've been thinking for a while about a better interface for this, but I
> > haven't come up with one yet.
>
> Does GCC tell us in any way (via the debug info) that a single source
> line has more than a single statement?
>
> If not, the only way for GDB to figure that out is to parse the source
> code by itself.
No, it doesn't, but there is more information available from the
machine code than there is from the source code. For "for" statements,
it's conceivable to work out that there are multiple places in the
statement which serve as branch targets, via assembly analysis. Better
would be to record this in the debug info; there's no way to do it,
yet, but someone was bouncing around a proposal to record it in the
line table.
> > GDB could also make it much easier to figure out where the condition is
> > than it does now...
>
> How?
By providing a version of "info line" which described all the ranges of
code belonging to a line instead of just the first one, or by a command
which disassembled an entire line.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-08-03 19:21 ` Daniel Jacobowitz
@ 2004-08-03 20:09 ` Andrew Cagney
2004-08-03 20:21 ` Daniel Jacobowitz
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Cagney @ 2004-08-03 20:09 UTC (permalink / raw)
To: Daniel Jacobowitz, Eli Zaretskii, allenh; +Cc: gdb
> On Fri, Jul 30, 2004 at 01:43:28PM +0200, Eli Zaretskii wrote:
>
>>>> > Date: Thu, 29 Jul 2004 11:29:40 -0400
>>>> > From: Daniel Jacobowitz <drow@false.org>
>>>> >
>>>> > I've been thinking for a while about a better interface for this, but I
>>>> > haven't come up with one yet.
>>
>>>
>>> Does GCC tell us in any way (via the debug info) that a single source
>>> line has more than a single statement?
>>>
>>> If not, the only way for GDB to figure that out is to parse the source
>>> code by itself.
>
>
> No, it doesn't, but there is more information available from the
> machine code than there is from the source code. For "for" statements,
> it's conceivable to work out that there are multiple places in the
> statement which serve as branch targets, via assembly analysis. Better
> would be to record this in the debug info; there's no way to do it,
> yet, but someone was bouncing around a proposal to record it in the
> line table.
Does dwarf3 include column information? That would let us break:
for (i ; i < 10 ; i++)
into:
for (i ;
i < 10 ;
i++)
which, at least on a graphics device, could be very effectively
represented to the user - the section of code to next be executed could
be highlighted.
Andrew
>>>> > GDB could also make it much easier to figure out where the condition is
>>>> > than it does now...
>>
>>>
>>> How?
>
>
> By providing a version of "info line" which described all the ranges of
> code belonging to a line instead of just the first one, or by a command
> which disassembled an entire line.
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: breaking at for-loop test line
2004-08-03 20:09 ` Andrew Cagney
@ 2004-08-03 20:21 ` Daniel Jacobowitz
0 siblings, 0 replies; 12+ messages in thread
From: Daniel Jacobowitz @ 2004-08-03 20:21 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Eli Zaretskii, allenh, gdb
On Tue, Aug 03, 2004 at 04:08:54PM -0400, Andrew Cagney wrote:
> Does dwarf3 include column information? That would let us break:
>
> for (i ; i < 10 ; i++)
>
> into:
>
> for (i ;
> i < 10 ;
> i++)
>
> which, at least on a graphics device, could be very effectively
> represented to the user - the section of code to next be executed could
> be highlighted.
Hmm, yes - the line table does have a field for column. GCC is working
on tracking columns internally, so after that, it shouldn't be too
difficult to make it output appropriate line table data.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2004-08-03 20:21 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-29 13:07 breaking at for-loop test line Atul Talesara
-- strict thread matches above, loose matches on Subject: below --
2004-07-29 5:10 Allen Hopkins
2004-07-29 16:29 ` Daniel Jacobowitz
2004-07-29 18:58 ` Andre Ancelin
[not found] ` <drow@false.org>
2004-07-29 22:21 ` Felix Lee
2004-07-30 8:23 ` Baurjan Ismagulov
[not found] ` <ibr@ata.cs.hun.edu.tr>
2004-07-30 10:46 ` Felix Lee
2004-08-03 18:53 ` Daniel Jacobowitz
2004-07-30 11:32 ` Eli Zaretskii
2004-08-03 19:21 ` Daniel Jacobowitz
2004-08-03 20:09 ` Andrew Cagney
2004-08-03 20:21 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).