On Fri, Oct 21, 2011 at 9:45 AM, Kevin Pouget wrote: > On Thu, Oct 20, 2011 at 10:41 PM, Tom Tromey wrote: >>>>>>> "Kevin" == Kevin Pouget writes: >> >> Tom> You need to store a gdb.Type wrapper. >> Tom> A 'struct type' can also be invalidated when an objfile is destroyed. >> >> Kevin> I wouldn't mind, but I can't see how gdb.Type ensures validity, as far >> Kevin> as I've seen, there is no "is_valid" method and I can't and no further >> Kevin> verification during the Python -> C translation: >> >> When an objfile is destroyed, py-type.c:save_objfile_types is called. >> This makes a copy of the struct type underlying any relevant Type object. > > I'll take a look at that, I don't remember what was the problem! I understood that, and replaced 'struct type *' fields by the corresponding 'PyObject/Type' python objects >> [ out_of_scope_notif ] >> Kevin> - avoid calling `out_of_scope' every normal_stop when the breakpoint >> Kevin> is not anymore in the callstack >> >> It seems to me that manually managing this is not the best we could do. >> >> I was re-reading the code and I realized that this isn't actually >> working the way I had remembered it working: >> >> +A @fdb{finish breakpoint} is a breakpoint set at the return address of >> +a frame, based on the "finish command. @code{gdb.FinishBreakpoint} extends >> +@code{gdb.Breakpoint} >> >> This approach is fine; but once a frame is gone, it is gone -- we should >> just destroy the breakpoint at that point.  Maybe this would make the >> internal logic simpler as well. > > yes, I think you're right with that, "once a frame is gone, it is > gone", I actually don't use myself this 'permanent finish breakpoint' > feature, so I'll change it. > So basically, the BP must be deleted right after it has been it (maybe > through the 'temporary' mechanism). 'out_of_scope' will be triggered > in the same conditions as before, but instead of playing with > 'out_of_scope_notif' I'll delete the GDB breakpoint (thus invalidating > the Python BP) > > I'll post a patch going this way later today So I've changed the way FinishBreakpoints are 'garbage collected'. Now, they're more similar to Temporary Breakpoints, that is, they're deleted *soon* after they've been hit. Soon, because when Breakpoint.stop tells GDB *not* to stop at the [finish] breakpoint, there is no way to delete this breakpoint (and I guess that may be the reason why Temporary Breakpoints are not available in Python yet). So I disable it, and "b->disposition == disp_del" will ensure that the BP will be removed when it's possible. The `out_of_scope' callback will also delete the breakpoint. I've updated the doc and testsuite accordingly, and as far as I've seen, there is no regression on X86_64/Fedora (I need still need to improve my test environment) Thanks, Kevin 2011-10-24 Kevin Pouget Introduce gdb.FinishBreakpoints in Python * Makefile.in (SUBDIR_PYTHON_OBS): Add py-finishbreakpoint.o. (SUBDIR_PYTHON_SRCS): Add python/py-finishbreakpoint.c. Add build rule for this file. * breakpoint.h (struct breakpoint): New field: is_py_finish_bp. * breakpoint.c (init_raw_breakpoint_without_location): Initialize is_py_finish_bp. * infcmd.c (get_return_value): New function. (print_return_value): Split to create get_return_value. * inferior.h (get_return_value): New prototype. * infrun.c: Include python/python.h. (stop_registers): Mention FinishBreakpoint in description. (normal_stop): Set stop_registers if stopped at FinishBreakpoint. * python/py-breakpoint.c (breakpoint_object_type): Make non-static. (bppy_pending_object): Likewise (gdbpy_should_stop): Disable temporary breakpoints. (gdbpy_breakpoint_created): Set is_py_finish_bp is necessary. (struct breakpoint_object): Move to python-internal.h (BPPY_REQUIRE_VALID): Likewise. (BPPY_SET_REQUIRE_VALID): Likewise. * python/python-internal.h (breakpoint_object_type): Add as extern. (bppy_pending_object): Likewise. (typedef struct breakpoint_object) Removed. (struct breakpoint_object): Moved from py-breakpoint.c. (BPPY_REQUIRE_VALID): Likewise. (BPPY_SET_REQUIRE_VALID): Likewise. (frame_object_to_frame_info): New prototype. (gdbpy_initialize_finishbreakpoints): New prototype. (bpfinishpy_is_finish_bp): Likewise. * python/py-finishbreakpoint.c: New file. * python/py-frame.c(frame_object_to_frame_info): Make non-static and accept PyObject instead of frame_object. (frapy_is_valid): Don't cast to frame_object. (frapy_name): Likewise. (frapy_type): Likewise. (frapy_unwind_stop_reason): Likewise. (frapy_pc): Likewise. (frapy_block): Likewise. (frapy_function): Likewise. (frapy_older): Likewise. (frapy_newer): Likewise. (frapy_find_sal): Likewise. (frapy_read_var): Likewise. (frapy_select): Likewise. * python/python.c (gdbpy_is_stopped_at_finish_bp): New noop function. (_initialize_python): Add gdbpy_initialize_finishbreakpoints. * python/python.h: Include breakpoint.h (gdbpy_is_stopped_at_finish_bp): New prototype. doc/ * gdb.texinfo (Breakpoints In Python): New subsection: Finish Breakpoints. testsuite/ * gdb.python/py-breakpoint.exp (mult_line): Define and use variable instead of line number. * gdb.python/py-finish-breakpoint.c: New file. * gdb.python/py-finish-breakpoint.exp: New file. * gdb.python/py-finish-breakpoint.py: New file. * gdb.python/py-finish-breakpoint2.cc: New file. * gdb.python/py-finish-breakpoint2.exp: New file. * gdb.python/py-finish-breakpoint2.py: New file.