Re: [RFC] breakpoints and function prologues...

Joel Brobecker
2002-07-31T01:34:56Z

> There's already a convention for this, I think. Now, where was it
> described??? Here it is:
>
> int
> in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
> {
> struct symtab_and_line sal;
> CORE_ADDR func_addr, func_end;
>
> /* We have several sources of information we can consult to figure
> this out.
> - Compilers usually emit line number info that marks the prologue
> as its own "source line". So the ending address of that "line"
> is the end of the prologue. If available, this is the most
> reliable method.
[...]
> So, just emit an extra line entry for the prologue.

If I understand the description above correctly, emitting a new line
entry for the prologue shouldn't be necessary. A glance at the
implemenation seems to confirm it. Basically, this function performs
the following actions:

- try to find the function containing a given PC address, to get
the address of the begining of the function

- from the start of function address, it tries to find a line entry.

- If it found a line entry, it uses the end address as the end of the
prologue.

GCC already generates this line entry. I don't know if it was generated
for this exact purpose but consider the example:

5 int
6 main (void)
7 {
8 return 0;
9 }

GCC will generate a line entry for line 7 which will point at the
begining of the prologue of main. The next line entry is for the first
real line of code, so the prologue ends up having its own source line.
Here is a dump from the assembly file generated by a recent version of
GCC on x86-linux:

main:
.stabn 68,0,7,.LM1-main
.LM1:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
.stabn 68,0,8,.LM2-main
.LM2:
movl $0, %eax
.stabn 68,0,9,.LM3-main
.LM3:
leave
ret

The trouble is that, when using "break file:line", GDB does not use this
kind of information to skip the prologue, it does not even try to skip
it.

So far, I see the following 2 ways out:

1. We move line 7 to .LM2. But then we have a small problem, because
the prologue instructions become orphaned (no line number
associated). This may cause a bit of grief to the developpers that
sometimes step into the function prologue. This is why we suggested
setting the line number to 0. But this is also a bit weak, because
how is the debugger going to relate this line 0 to the appropriate
line number in the source?

2. We leave line 7 at .LM1 (ie the begining of the function, at the
begining of the prologue), but then GDB a putting a breakpoint
at line 7 will cause GDB to stop before the prologue (actually, if
it ever stops, remember the case of Tru64 where the first 2
instructions in the prologue setting the gp are often optimized
out, thank you mister linker).

In this case, the most sensible change for me seems to modify GDB to
skip prologues when putting breakpoints by line number. The idea of
modifying the compiler was that the compiler would help GDB locating the
bounds of the prologue, but it seems that the information is already
there. So no change in the compiler is warranted anymore. Only GDB needs
to be upgraded to take advantage of it. We could also use this
information when putting a breakpoint by function name. This is where my
"BTW:" below becomes interesting.

Does this seem a reasonable approach?

--
Joel

BTW:

In fact, I wonder if there is a function somewhere that returns the
address of the first instruction past the prologue that uses this
algorithm? In all the places I've looked, we usually use SKIP_PROLOGUE.
See for instance find_function_start_sal which uses SKIP_PROLOGUE as its
sole method to find the first real instruction address.

Should I suggest that we write a small function generic_skip_prologue
that does exactly what in_prologue does, execpt that it returns the
address of first instruction past the prologue, rather than returning
just an indication whether we are in the prologue or not. in_prologue
can then be implemented by invoking generic_skip_prologue and checking
whether the returned address is equal to the initial pc address.