This is the mail archive of the 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: [patch] Workaround gcc bug 49906

On 11-10-28 05:23 PM, Jan Kratochvil wrote:
There is no code to produce for that line - for the before-part
of `for (;; anything)'.

I believe this is in the background of the gcc bug.
If you think there should be that "nop" I think GCC PR debug/49906 needs to be
extended (and/or filed a new GCC PR) as GCC PR debug/49906 probably is not
going to implement this "nop" there.

My point of view is that for source level debugging one would expect to start with what appears to be the first "something" in the source. Technically, it is correct what you are saying but if we are talking about what would be intuitive, then I think the very first line of code must be 'for' loop (even if it evaluates to 'nop').

Consider this test (which is what I was concentrating on):

(gdb) b foo
Breakpoint 1 at 0x4004ba: file foo.c, line 8.
(gdb) list foo
1       static int i;
2       static void
3       foo(void)
4       {
5         for (;;)
6               if (i++)
7                 break;
8       }

Line 8 is totally unintuitive and weird.

But I do not intend to get into discussion over cosmetics, please read on (sorry for the lengthy post) I will explain the actual motivation behind this patch.

IMO, with the fix, the result is better (beginning of the function
block is better IMO than first statement inside 'for' block).

Without the fix it stops on the first executable statement. This is a perfectly defined behavior. Not if you noticed your patch breaks access to function parameters (and probably also affects local variables some way).

Ok, this is acceptable behaviour and if it were not for the issues I will describe below, I would not even try to fix anything.

Not sure which part do you look for but including below, it is not so long.

Thanks, Jan

I am looking for line number statements alongside disassembly. From this output, I can not argue that it is wrong, at a minimum it is not obvious and I don't want to continue with this particular example (maybe on IRC later).

>   Line Number Statements:
   Extended opcode 2: set Address to 0x400454
   Special opcode 8: advance Address by 0 to 0x400454 and Line by 3 to 4
   Special opcode 105: advance Address by 7 to 0x40045b and Line by 2 to 6
   Advance PC by constant 17 to 0x40046c
   Special opcode 102: advance Address by 7 to 0x400473 and Line by -1 to 5
   Special opcode 218: advance Address by 15 to 0x400482 and Line by 3 to 8
   Special opcode 32: advance Address by 2 to 0x400484 and Line by -1 to 7
   Special opcode 20: advance Address by 1 to 0x400485 and Line by 1 to 8
   Special opcode 34: advance Address by 2 to 0x400487 and Line by 1 to 9
   Special opcode 61: advance Address by 4 to 0x40048b and Line by 0 to 9
   Advance PC by constant 17 to 0x40049c
   Extended opcode 1: End of Sequence

However, I have a real-life example that prompted work on this. On arm, with -O0 I have a for (;;) loop. The line information + current skipping over prologue in gdb, yields unreachable breakpoint which prevents stepping into the function using software single stepping (single step breakpoint is never hit) or can cause breakpoint set on the function to never be hit.

What follows is the excerpt from this sample I have on hands.

-------------- 8< ------------------- 227 void foo() { 228 int rc; 229 230 // 231 for(;;) { 232 void *e = NULL; 233 rc = bar(&e, 0); ... 248 } 249 }

void foo() {
  1029a0:   e92d4800    push    {fp, lr}
  1029a4:   e28db004    add fp, sp, #4  ; 0x4
  1029a8:   e24dd010    sub sp, sp, #16 ; 0x10
  1029ac:   ea000000    b   1029b4 <foo+0x14>
  1029b0:   e1a00000    nop         (mov r0,r0)
  1029b4:   e3a03000    mov r3, #0  ; 0x0
  102a64:   eaffffd2    b   1029b4 <foo+0x14>
  102a68:   e24bd004    sub sp, fp, #4  ; 0x4
  102a6c:   e8bd8800    pop {fp, pc}

Line Number Statements:
Special opcode 63: advance Address by 8 to 0x1029a0 and Line by 2 to 227
Advance Line by 21 to 248
Special opcode 117: advance Address by 16 to 0x1029b0 and Line by 0 to 248
Advance Line by -16 to 232
---------------- >8 ----------------------

Currently 'b foo' would yield address 0x1029b0 since gdb will look for function sal (0x1029a0, line 227) then look for the next one and find (0x1029b0, line 248). Let's leave aside for now the weird result of breakpoint for the function appearing at line 248 where function starts at line 227 and first statement that does something is at line 232, there is far more sinister consequence:

From the assembly above it is clear that this 'nop' is never reached. See branch at 0x102a64 which is the closing of the loop.

This and some other examples I have created on x86 (including the testcase proposed here) prompted me to believe that the correct line information would always contain line information for the 'for' statement, e.g. in the above, there is a line info missing, something like:

Special opcode 63: advance Address by 8 to 0x1029a0 and Line by 2 to 227
Special opcode 63: advance Address by 12 to 0x1029ac and Line by 4 to 231
Advance Line by 21 to 248
Special opcode 117: advance Address by 14 to 0x1029b0 and Line by 0 to 248

(it appears that on both arm and x86, compiler generates this "jump into" branch, which is what I would choose as the end of prologue, that is, as the instruction associated with the line where 'for' statement appears.)

In any case, I will revisit the whole thing paying attention to your test case - maybe there is no generic solution, but then again, I would choose the less bad solution over the plain broken one.



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