public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Command to break before exiting stack frame?
@ 2019-03-16 23:15 Justin Paston-Cooper
  2019-03-17  0:01 ` Andreas Schwab
  0 siblings, 1 reply; 7+ messages in thread
From: Justin Paston-Cooper @ 2019-03-16 23:15 UTC (permalink / raw)
  To: gdb

Hello,

I would be interested to see a command which breaks just before exiting the
current stack frame. I have so far seen this implemented as a custom
command in Python, which searches for 'retq' instructions in the current
stack frame. I am not an ASM expert, but I imagine that this might not work
for all architectures.

In any case, you might ask why I can't just use that instead of expecting
it as a native command in gdb. You might also ask why I don't just give the
line number of the returns of the function in question. There are a few
reasons:

1. We already have a command to break at the beginning of a function given
its name (break).
2. We already have a command to continue to the end of the current stack
frame and then exit it (finish).
3. Analysing C/C++/other code with gcc is difficult. grep can tell me the
line numbers of returns in C/C++, but there might be other languages where
such a simple solution is not so readily available. In any case, it's still
an extra step.
4. rbreak breaks at the beginning of all functions matching a regex. It
would be simple and useful to add a "break on frame exit" command to the
commands part of an rbreak command to see the ending state of all chosen
functions.

I can't imagine that I am the first person to suggest or request this. Are
there any architectural or practical reasons as to why this is might be
difficult? I was not able to find any, but are there any existing,
equivalent and native solutions?

Thanks in advance,

Justin

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Command to break before exiting stack frame?
  2019-03-16 23:15 Command to break before exiting stack frame? Justin Paston-Cooper
@ 2019-03-17  0:01 ` Andreas Schwab
  2019-03-17  0:23   ` Simon Marchi
  0 siblings, 1 reply; 7+ messages in thread
From: Andreas Schwab @ 2019-03-17  0:01 UTC (permalink / raw)
  To: Justin Paston-Cooper; +Cc: gdb

On Mär 16 2019, Justin Paston-Cooper <paston.cooper@gmail.com> wrote:

> I can't imagine that I am the first person to suggest or request this. Are
> there any architectural or practical reasons as to why this is might be
> difficult?

There may not even be a place where the frame is exited in the current
function due to tail call.  Also, inline literal pools or jump tables
can result in false positives when searching for return insns.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Command to break before exiting stack frame?
  2019-03-17  0:01 ` Andreas Schwab
@ 2019-03-17  0:23   ` Simon Marchi
  2019-03-17 13:59     ` Justin Paston-Cooper
  2019-03-19 15:35     ` Tom Tromey
  0 siblings, 2 replies; 7+ messages in thread
From: Simon Marchi @ 2019-03-17  0:23 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Justin Paston-Cooper, gdb

On 2019-03-16 20:00, Andreas Schwab wrote:
> On Mär 16 2019, Justin Paston-Cooper <paston.cooper@gmail.com> wrote:
> 
>> I can't imagine that I am the first person to suggest or request this. 
>> Are
>> there any architectural or practical reasons as to why this is might 
>> be
>> difficult?
> 
> There may not even be a place where the frame is exited in the current
> function due to tail call.  Also, inline literal pools or jump tables
> can result in false positives when searching for return insns.
> 
> Andreas.

I suppose that the list of all function exit points (regardless of 
whether it is a jump or real return) is an information that the compiler 
could theoretically produce and encode in the DWARF information?

Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Command to break before exiting stack frame?
  2019-03-17  0:23   ` Simon Marchi
@ 2019-03-17 13:59     ` Justin Paston-Cooper
  2019-03-19 15:42       ` Tom Tromey
  2019-03-19 15:35     ` Tom Tromey
  1 sibling, 1 reply; 7+ messages in thread
From: Justin Paston-Cooper @ 2019-03-17 13:59 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb

I accidentally replied to Andreas's email without CCing the list.
Simon has addressed the jump issue. Does gcc emit jump tables when
optimisation options are not enabled anyway?

 On tail calls: I tested the behaviour of the "finish" command with a
tail-recursive function in following code, with the following gdb
commands:

------------------------------

static int f (int x);

int
main(void)
{
  f(5);
}

static int
f (int x)
{
  if (x == 0)
    {
      return 0;
    }
  else
    {
      return f(x - 1);
    }
}

------------------------------

break f
commands
finish
end

------------------------------

Given its documentation, I would have expected the "finish" command to
print the returned value at each tail call. It turns out that it
prints the returned value only for the f(0) call. I would similarly
expect a "break on exit" command to break on the exit of the frame in
which it is called even if a tail-recursion occurs. Is there a reason
that it doesn't? My first thought would be tail-call optimisation, but
in any case breaks on tail-calls of the function still work fine, and
when I disassembled the function, I saw that no tail-call optimisation
occurred in my case.

On the actual implementation of this command: Is the implementation of
such a feature feasible? If so, how much work would it take? I would
certainly be interested in helping, although I don't yet have any
experience with working on compilers/debuggers.


On Sun, 17 Mar 2019 at 00:23, Simon Marchi <simon.marchi@polymtl.ca> wrote:
>
> On 2019-03-16 20:00, Andreas Schwab wrote:
> > On Mär 16 2019, Justin Paston-Cooper <paston.cooper@gmail.com> wrote:
> >
> >> I can't imagine that I am the first person to suggest or request this.
> >> Are
> >> there any architectural or practical reasons as to why this is might
> >> be
> >> difficult?
> >
> > There may not even be a place where the frame is exited in the current
> > function due to tail call.  Also, inline literal pools or jump tables
> > can result in false positives when searching for return insns.
> >
> > Andreas.
>
> I suppose that the list of all function exit points (regardless of
> whether it is a jump or real return) is an information that the compiler
> could theoretically produce and encode in the DWARF information?
>
> Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Command to break before exiting stack frame?
  2019-03-17  0:23   ` Simon Marchi
  2019-03-17 13:59     ` Justin Paston-Cooper
@ 2019-03-19 15:35     ` Tom Tromey
  1 sibling, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2019-03-19 15:35 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Andreas Schwab, Justin Paston-Cooper, gdb

>>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:

Simon> I suppose that the list of all function exit points (regardless of
Simon> whether it is a jump or real return) is an information that the
Simon> compiler could theoretically produce and encode in the DWARF
Simon> information?

Yes, the line number program can include epilogue markers.
I don't believe gcc emits these, though.

This feature would be a good one to have in gdb.
Fixing it in the compiler is probably the best way to do it, though I
don't know whether it's the simplest way.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Command to break before exiting stack frame?
  2019-03-17 13:59     ` Justin Paston-Cooper
@ 2019-03-19 15:42       ` Tom Tromey
  2019-03-19 20:44         ` Justin Paston-Cooper
  0 siblings, 1 reply; 7+ messages in thread
From: Tom Tromey @ 2019-03-19 15:42 UTC (permalink / raw)
  To: Justin Paston-Cooper; +Cc: Simon Marchi, gdb

Justin> Given its documentation, I would have expected the "finish" command to
Justin> print the returned value at each tail call. It turns out that it
Justin> prints the returned value only for the f(0) call. I would similarly
Justin> expect a "break on exit" command to break on the exit of the frame in
Justin> which it is called even if a tail-recursion occurs. Is there a reason
Justin> that it doesn't?

It seems to me that a tail call means there just isn't a return value
from the calling function, only from the callee, because the caller
doesn't even really have a separate return statement.

I suppose, though, if it is like inlining, then this text from the
manual also applies:

   * GDB cannot locate the return value of inlined calls after using the
     'finish' command.  This is a limitation of compiler-generated
     debugging information; after 'finish', you can step to the next
     line and print a variable where your program stored the return
     value.

Justin> On the actual implementation of this command: Is the implementation of
Justin> such a feature feasible? If so, how much work would it take?

For the compiler, I couldn't say.  For gdb, doing it without help from
the compiler seems difficult, as you'd probably have to write an
instruction decoder.  gdb already has these for some architectures
(various kinds, actually, for different things), but probably not in a
useful form.

On the whole I think it would be better to start with the compiler.  If
it emits epilogue markers, then the gdb work is not difficult.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Command to break before exiting stack frame?
  2019-03-19 15:42       ` Tom Tromey
@ 2019-03-19 20:44         ` Justin Paston-Cooper
  0 siblings, 0 replies; 7+ messages in thread
From: Justin Paston-Cooper @ 2019-03-19 20:44 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb

Tom> It seems to me that a tail call means there just isn't a return value
Tom> from the calling function, only from the callee, because the caller
Tom> doesn't even really have a separate return statement.

That makes sense actually. Although I would hope that the break on
exit command would break after any tail-recursive call exits.

Tom> On the whole I think it would be better to start with the compiler.  If
Tom> it emits epilogue markers, then the gdb work is not difficult.

Thanks for the tips. I've sent a message to the gcc mailing list.

On Tue, 19 Mar 2019 at 15:42, Tom Tromey <tom@tromey.com> wrote:
>
> Justin> Given its documentation, I would have expected the "finish" command to
> Justin> print the returned value at each tail call. It turns out that it
> Justin> prints the returned value only for the f(0) call. I would similarly
> Justin> expect a "break on exit" command to break on the exit of the frame in
> Justin> which it is called even if a tail-recursion occurs. Is there a reason
> Justin> that it doesn't?
>
> It seems to me that a tail call means there just isn't a return value
> from the calling function, only from the callee, because the caller
> doesn't even really have a separate return statement.
>
> I suppose, though, if it is like inlining, then this text from the
> manual also applies:
>
>    * GDB cannot locate the return value of inlined calls after using the
>      'finish' command.  This is a limitation of compiler-generated
>      debugging information; after 'finish', you can step to the next
>      line and print a variable where your program stored the return
>      value.
>
> Justin> On the actual implementation of this command: Is the implementation of
> Justin> such a feature feasible? If so, how much work would it take?
>
> For the compiler, I couldn't say.  For gdb, doing it without help from
> the compiler seems difficult, as you'd probably have to write an
> instruction decoder.  gdb already has these for some architectures
> (various kinds, actually, for different things), but probably not in a
> useful form.
>
> On the whole I think it would be better to start with the compiler.  If
> it emits epilogue markers, then the gdb work is not difficult.
>
> Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-03-19 20:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-16 23:15 Command to break before exiting stack frame? Justin Paston-Cooper
2019-03-17  0:01 ` Andreas Schwab
2019-03-17  0:23   ` Simon Marchi
2019-03-17 13:59     ` Justin Paston-Cooper
2019-03-19 15:42       ` Tom Tromey
2019-03-19 20:44         ` Justin Paston-Cooper
2019-03-19 15:35     ` Tom Tromey

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