On Wed, 20 Mar 2019 at 08:31, Richard Biener <richard.guent...@gmail.com> wrote: > > On Tue, Mar 19, 2019 at 9:38 PM Justin Paston-Cooper > <paston.coo...@gmail.com> wrote: > > > > Hello, > > > > In my message https://sourceware.org/ml/gdb/2019-03/msg00042.html to > > the gdb mailing list, I asked whether it would be possible to > > implement a command which breaks at all exit points of the current > > stack frame. This would be very useful for evaluating a function's > > final state before it returns its result, independent of where in its > > definition it returns from. > > > > Tom Tromey suggested in that thread that this would be quite easy on > > gdb's side if gcc indicates exit locations in the DWARF data, for > > Did he indicate _how_ to represent this in DWARF? I suppose the breakpoint > should happen before the local frame is teared down.
Tom didn't suggest any specific implementation. Simon Marchi in the same thread said, "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?". I had a look at the DWARF5 specification. Section 6.2.2 outlines the registers of the state machine which deals with line number information. One of those registers is named "epilogue_begin". Its definition is: ----- A boolean indicating that the current address is one (of possibly many) where execution should be suspended for a breakpoint just prior to the exit of a function. ----- Section 6.2.5.2 outlines the line number information state machine's opcodes. One of them is "DW_LNS_set_epilogue_begin". Its definition is: ----- The DW_LNS_set_epilogue_begin opcode takes no operands. It sets the epilogue_begin register to “true”. When a breakpoint is set on the exit of a function or execution steps over the last executable statement of a function, it is generally desirable to suspend execution after completion of the last statement but prior to tearing down the frame (so that local variables can still be examined). Debuggers generally cannot properly determine where this point is. This command allows a compiler to communicate the location(s) to use. Note that the function to which the epilogue end applies cannot be directly determined from the line number information alone; it must be determined in combination with the subroutine information entries of the compilation (including inlined subroutines). In the case of a trivial function, both prologue end and epilogue begin may occur at the same address. ----- Shouldn't this be sufficient for gdb to work backwards and determine the _beginning_ of any exit statement of a function? I had a look into gcc's involvement with "epilogue_begin". The pass called "pass_thread_prologue_and_epilogue" transitively calls a function defined in function.c called "make_epilogue_seq", which as far as I understand emits an "epilogue_begin" note. I'm not sure how this pass ties in with each frontend. Does a frontend need to support this pass explicitly? If so, is it just not supported by a lot of frontends? Given that no one on the gdb thread mentioned this pass, is there another problem which I am not aware of? > > > instance in the C case, it would indicate the locations of return > > statements. On a related note, he mentions that the "finish" command > > does not work for inlined functions because the compiler does not emit > > the required information. > > While "finish" wants a location at the caller side, after the inlined frame is > teared down. So they are somewhat distinct. Obviously I'm not familiar with gcc/gdb internals, but superficially my idea was that if 'finish' has access to the information on the exit points of an inlined function, then it can keep track of which register/location the "return" value ends up in. > > Can you open two enhancement requests in buzilla? Will do. > > Thanks, > Richard. > > > It would be nice if this new break on exit command worked both for > > inlined functions, and also the case of breaking after tail-recursions > > exit. With a single stone, the "finish" bird above is also killed. > > > Would it be feasible to implement such a feature in gcc? If I'm not > > the first person to ask for this, are there any architectural or > > practical reasons as to why it might not be possible to implement? As > > it stands, I don't have the level of familiarity with gcc to come to > > you with a patch, but with guidance I would certainly be interested in > > working on the C/C++ case if that would be useful. > > > > Thanks, > > > > Justin