Thanks for the help and advice. I will ping back the list with more stuff when I'm done.
Regards, Filipe On Fri, Jul 22, 2011 at 16:23, Jim Ingham <[email protected]> wrote: > > On Jul 22, 2011, at 3:46 PM, Filipe Cabecinhas wrote: > > > > > > > On Fri, Jul 22, 2011 at 15:18, Jim Ingham <[email protected]> wrote: > > Filipe, > > > > Thanks for working on this. > > > > Note, gdb's "return" command doesn't do anything to attempt to clean up > local objects. It just pops the frames off the stack & returns the value. > This, like moving the PC by hand, is one of those commands that you just > shouldn't use if you don't know what could go wrong... Anyway, people > mostly use this to hack system routines to do something else, in which case > you stop at the very beginning and return directly - you haven't gotten far > enough to need to do any cleanup. > > > > Seems to me that the sensible thing to do about the return expression is > take whatever the user gives you and cast it to the return type of the > function you are returning from, if you know it. If you don't then just > write it as whatever they have given you, and the user will have to get it > right when they write the expression. That's the best you can do in this > case. > > > > OK. > > > > It also seems to me that much more of this could be generic. The > algorithm gdb uses is to get the register context one frame up on the stack, > and write that to the real registers, and then throw away the cached stack > and remake it from the changed registers. That can all be done generically. > Mind there are target specific bits but they are all hidden under the > register code. It is the unwinder's job to know what the register state of > the functions up on the stack are, you should rely on that. > > > > The only ABI specific bit is that you need to ask the ABI where to store > the return value. For things smaller than a register that is easy. For > struct returns it can be hard, because the compiler usually passes in a > pointer to the save location, but you would have to track the history of > that value to know where it is stored at the point you are trying to return > from, and that's not trivial. Again, if you are at the beginning of the > function you're returning from, this is easy to do. > > > > Ok. You're suggesting taking the code out of the ABI and putting it on > the command (or maybe the StackFrame)? I initially wrote the code thinking > calling conventions could vary a lot but, for the returns, they don't vary > that much (and lldb allows us to abstract most of what varies). Or would it > be preferred to just contain the code in the command object? > > Yes. This functionality seems generally useful, so the code to do this > should go somewhere in the core. Then the command would just be a thin > wrapper. StackFrame doesn't seem right to me, since you are operating on > the list of frames more than the individual frame. So either > StackFrameList, or its owner Thread, seem good places. > > > > > I suppose the command should also be changed to the "frame" command, to > mimic gdb (it returns from the current frame, not the bottom-most). > > > > Yes, that makes sense, you would either return from the currently selected > frame, or from a frame given explicitly in the command. Note in general in > lldb we try to avoid positional arguments, so I would do: > > frame return --frame <FRAME NUMBER> <expression> > > BTW, you can also make LLDB commands "RAW" commands, which means that > everything after the options is passed unparsed to the command. That's very > convenient for commands that take an expression as their argument, since > then you don't end up having to backslash yourself to death. See the > "expression" command for an example of this. > > Oh, yeah, another thing, though very trivial, since you defined your > command with: > > eFlagProcessMustBeLaunched | eFlagProcessMustBePaused > > you don't have to check whether the process & target are valid, the command > interpreter shouldn't call you if they are not. > > Again, thanks for working on this! > > Jim > > > > You can also check whether the block you are in is inlined, and if it is, > then all you do is move the PC to the end of the block. You can't really do > anything about the return value then, because you can't really tell where it > is going, but at least you can return properly from the inlined function. > > > > Hope that helps... > > I will try that one too, thanks. > > > > Regards, > > > > Filipe > > > > > > Jim > > > > On Jul 22, 2011, at 12:35 PM, Filipe Cabecinhas wrote: > > > > > > > > > > > On Mon, Jul 18, 2011 at 18:05, Greg Clayton <[email protected]> > wrote: > > > On Jul 18, 2011, at 5:23 PM, Filipe Cabecinhas wrote: > > > > > > > Hi, > > > > > > > > Is there a way to mimic gdb's "return <expr>" command? > > > > > > Not if you want to change the return value. > > > > > > If you don't want to change the return value you can use "thread > step-out". "thread step-out" (which is aliased to "finish"), is context > sensitive to the frame you are currently in, so if you run and stop in a > frame and then do a "frame select 12", and then to a "thread step-out", you > will return to frame 13. > > > > > > Yes, that command will run until the frame returns (like gdb's finish > command), but what if we want to return immediately? > > > > > > > (gdb) help return > > > > Make selected stack frame return to its caller. > > > > Control remains in the debugger, but when you continue > > > > execution will resume in the frame above the one now selected. > > > > If an argument is given, it is an expression for the value to return. > > > > > > > > > > > > I've been looking at the StackFrame class, but it doesn't look like > it can do that. > > > > If I wanted to implement it, where should I look first? I can get the > return address (StackFrame.GetRegisterContext().get().GetReturnAddress(), I > think) write it to the PC (StackFrame.ChangePC()), but I have no idea how to > get the expression's result into the return registers/memory. > > > > > > LLDB currently doesn't have any real idea of where the return address > goes, we currently let the compiler handle all ABI issues by the way we make > expressions. > > > > > > There is another issue where if a function isn't external, the compiler > can make a call to this function and how the function returns the value, > violate the ABI. In most cases you won't get affected by this, but it would > be nice if we knew for sure from the compiler or debug info where the return > value is. The old ARM compiler used to inject artificial DW_TAG_variable > debug information entries into the DWARF that would tell you the result of > functions which has a location that describes the returned value and where > it is. > > > > > > > > > > ClangExpression isn't a big help there, since the result comes to > debugger-land. > > > > > > Yep, and even so there is the issue that internal functions can violate > the ABI... > > > > > > FYI: anything ABI related is currently in the ABI plug-ins: > > > > > > lldb/source/Plugins/ABI/* > > > > > > The ABI function: > > > > > > virtual bool > > > ABI::GetReturnValue (Thread &thread, > > > Value &value) const = 0; > > > > > > Take a look a the ABIMacOSX_i386 and ABIMacOSX_x86_64 versions of this > function and see if this does close to what you want. You can also fill in > more functionality inside these for types you want it to support. Currently > we fill the "value" argument with the result, but we don't fill in the > context (See the "void Value::SetContext (ContextType context_type, void > *p)" function for details, but the ABI::GetReturnValue functions can be > modified to fill in the register context for return values that are returned > in registers, and the address (See the "Value::SetValueType (...)" function) > if needed. > > > > > > These functions currently will attempt to extract the return value for > a function according to the ABI rules for simple pointer size or less types > only (no structs, floats, complex etc). So this might help you for the > simple cases. If you were to implement this command you would want to add a > new "return" subcommand in the "thread" multi-word command. In the "Execute" > function of the new "return" command you would want to evaluate an > expression an store the result, set a breakpoint at the return address, > install a breakpoint callback and run and hit the breakpoint, then try and > instert the expression result into the appropriate location (you would need > to modify the "ABI::GetReturnValue(...)" to fill in the "value" param more > completely with the location of the return type. > > > > > > Greg Clayton > > > > > > > > > I implemented a thread return command, which works (right now) for > integers and pointers, for i386 and x86-64. The command has some caveats > (like the ones discussed here), but it works (at least) for a few simple > examples in C. > > > > > > "thread return <expr>" returns the result of evaluating that > expression. I'm not casting the expression, so there may be some problems > (especially when returning floating point types is implemented). > > > > > > But… > > > We have no idea if the compiler generated a stackframe for this > function or not. We may be returning from two functions, and not one. > > > We have no ideia if the compiler changed the calling conventions for > this code. > > > We don't know about the callee-saved registers (I suppose there isn't a > way to find out the epilogue of the function… Especially since it may be > mixed with "regular code") > > > > > > There are a lot more issues for C++ code (e.g: calling dtors). > > > > > > I also have some problems updating the state lldb thinks the thread is > in. > > > > > > "register read pc" won't read the real value > > > "thread backtrace" doesn't get updated. > > > > > > How can I fix that? I am also looking for comments on stuff to > fix/improve. > > > > > > I also have some tests (a directory to put in lldb/test/). > > > > > > Regards, > > > > > > Filipe Cabecinhas > > > > > > P.S: Converting between a ValueObject object and > > > > <thread-return.patch><thread_return.zip>_______________________________________________ > > > lldb-dev mailing list > > > [email protected] > > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev > > > > > >
_______________________________________________ lldb-dev mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
