This is the mail archive of the gdb-patches@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: Single step vs. "tail recursion" optimization


(I'm sorry to have to be the messenger on this one...)

Here's a mini testcase.  I've also attached the resulting .s files for
-O2 and -O3.
Shudder.  Andrew's speculation about s not working because there were no
symbols
is correct.  S-ing works until the call to getpid().

I haven't actually tried to figure out why gdb isn't doing it right in
that case
because there's actually something potentially even uglier going on in
the -O3 case.
This is something that the "management" of gdb and the "management" of
gcc are going
to have to take on and resolve as either "no, you can't sanely debug
-O3" or "we need
some help from the compiler to sort this one out".  (And if the latter,
then the same
help may be useful with the -O2 case!)  (I haven't seen this addressed,
but I could
easily have missed it.)
GDB's going to have to learn to do something with -O3, even if it isn't very sane :-)

Note that in the case of -O3, foo() and bar() are NEVER actually called
from main,
but rather getpid() is called directly. (Note also the reordering of the
functions.)
(Seeing that this sort of optimization is pretty compellingly needed for
C++ code,
"don't do that" seems an unlikely outcome.)
Anyway, here's a wild guess:

- gdb stepi's into getpid() (or what ever the tail recursive function is) - detects this because its no longer in foo()

- gdb calls saved_pc_after_call() and gets an address in main, sets tempoary breakpoint at that address.
I think, if this isn't happening, GCC will have by definition, screwed up the stack frame. The stack, for getpid() and hence GDB, has to appear like it was called from main() so getpid() will correctly return there.

- gdb resumes target

- getpid() returns, hits breakpoint in main, but the logic there (hmm, Elena's `until' post) doesn't realise that its exited the function / block in question.

- gdb resumes target, target exits

I think you can see this by either setting a breakpoint on saved_pc_after_call() or by watching the target traffic (set debug target 1?).

Andrew



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