public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* 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

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).