diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2015-05-13 20:47:32 +0200 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2015-05-13 20:49:08 +0200 |
commit | 8a6c40311297f60ad13827650fdde13da301b505 (patch) | |
tree | 6637b3cd8faf502557b9f40b3e469bb86180a883 /gdb/infcmd.c | |
parent | 109896905babca2d99e13f74bc887acf14cd1ab7 (diff) | |
download | fsf-binutils-gdb-8a6c40311297f60ad13827650fdde13da301b505.zip fsf-binutils-gdb-8a6c40311297f60ad13827650fdde13da301b505.tar.gz fsf-binutils-gdb-8a6c40311297f60ad13827650fdde13da301b505.tar.bz2 |
infcall: stop_registers -> register_dummy_frame_dtor
With dummy_frame destructors GDB no longer has to use global stop_registers.
dummy_frame's registers can be now stored associated with their specific
dummy_frame.
gdb/ChangeLog
2015-05-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* infcall.c (struct dummy_frame_context_saver)
(dummy_frame_context_saver_data_free, dummy_frame_context_saver_dtor)
(dummy_frame_context_saver_drop, dummy_frame_context_saver_cleanup)
(dummy_frame_context_saver_get_regs, dummy_frame_context_saver_setup):
New.
(call_function_by_hand_dummy): Move discard_cleanups of
inf_status_cleanup before dummy_frame_push. Call
dummy_frame_context_saver_setup and prepare context_saver_cleanup.
Use dummy_frame_context_saver_get_regs instead of stop_registers.
* infcall.h (struct dummy_frame_context_saver)
(dummy_frame_context_saver_drop, dummy_frame_context_saver_cleanup)
(dummy_frame_context_saver_get_regs, dummy_frame_context_saver_setup):
New declarations.
* infcmd.c: Include infcall.h.
(get_return_value): Add parameter ctx_saver, use it instead of
stop_registers.
(print_return_value): Add parameter ctx_saver, pass it.
(struct finish_command_continuation_args): Add field ctx_saver.
(finish_command_continuation): Update print_return_value caller.
(finish_command_continuation_free_arg): Free also ctx_saver.
(finish_forward): Call dummy_frame_context_saver_setup.
* inferior.h (struct dummy_frame_context_saver): New declaration.
(get_return_value): Add parameter ctx_saver.
* python/py-finishbreakpoint.c (bpfinishpy_pre_stop_hook): Update
get_return_value caller.
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r-- | gdb/infcmd.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 11d5310..3d6c4c9 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -54,6 +54,7 @@ #include "continuations.h" #include "linespec.h" #include "cli/cli-utils.h" +#include "infcall.h" /* Local functions: */ @@ -1506,18 +1507,22 @@ advance_command (char *arg, int from_tty) } /* Return the value of the result of a function at the end of a 'finish' - command/BP. */ + command/BP. DTOR_DATA (if not NULL) can represent inferior registers + right after an inferior call has finished. */ struct value * -get_return_value (struct value *function, struct type *value_type) +get_return_value (struct value *function, struct type *value_type, + struct dummy_frame_context_saver *ctx_saver) { - struct regcache *stop_regs = stop_registers; + struct regcache *stop_regs = NULL; struct gdbarch *gdbarch; struct value *value; struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); /* If stop_registers were not saved, use the current registers. */ - if (!stop_regs) + if (ctx_saver != NULL) + stop_regs = dummy_frame_context_saver_get_regs (ctx_saver); + else { stop_regs = regcache_dup (get_current_regcache ()); make_cleanup_regcache_xfree (stop_regs); @@ -1557,12 +1562,15 @@ get_return_value (struct value *function, struct type *value_type) return value; } -/* Print the result of a function at the end of a 'finish' command. */ +/* Print the result of a function at the end of a 'finish' command. + DTOR_DATA (if not NULL) can represent inferior registers right after + an inferior call has finished. */ static void -print_return_value (struct value *function, struct type *value_type) +print_return_value (struct value *function, struct type *value_type, + struct dummy_frame_context_saver *ctx_saver) { - struct value *value = get_return_value (function, value_type); + struct value *value = get_return_value (function, value_type, ctx_saver); struct ui_out *uiout = current_uiout; if (value) @@ -1613,6 +1621,11 @@ struct finish_command_continuation_args int thread; struct breakpoint *breakpoint; struct symbol *function; + + /* Inferior registers stored right before dummy_frame has been freed + after an inferior call. It can be NULL if no inferior call was + involved, GDB will then use current inferior registers. */ + struct dummy_frame_context_saver *ctx_saver; }; static void @@ -1653,7 +1666,7 @@ finish_command_continuation (void *arg, int err) /* print_return_value can throw an exception in some circumstances. We need to catch this so that we still delete the breakpoint. */ - print_return_value (func, value_type); + print_return_value (func, value_type, a->ctx_saver); } CATCH (ex, RETURN_MASK_ALL) { @@ -1677,7 +1690,11 @@ finish_command_continuation (void *arg, int err) static void finish_command_continuation_free_arg (void *arg) { - xfree (arg); + struct finish_command_continuation_args *cargs = arg; + + if (cargs->ctx_saver != NULL) + dummy_frame_context_saver_drop (cargs->ctx_saver); + xfree (cargs); } /* finish_backward -- helper function for finish_command. */ @@ -1742,13 +1759,21 @@ finish_forward (struct symbol *function, struct frame_info *frame) struct symtab_and_line sal; struct thread_info *tp = inferior_thread (); struct breakpoint *breakpoint; - struct cleanup *old_chain; + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); struct finish_command_continuation_args *cargs; int thread = tp->num; + struct dummy_frame_context_saver *saver = NULL; sal = find_pc_line (get_frame_pc (frame), 0); sal.pc = get_frame_pc (frame); + if (get_frame_type (frame) == DUMMY_FRAME) + { + saver = dummy_frame_context_saver_setup (get_stack_frame_id (frame), + inferior_ptid); + make_cleanup (dummy_frame_context_saver_cleanup, saver); + } + breakpoint = set_momentary_breakpoint (gdbarch, sal, get_stack_frame_id (frame), bp_finish); @@ -1756,7 +1781,7 @@ finish_forward (struct symbol *function, struct frame_info *frame) /* set_momentary_breakpoint invalidates FRAME. */ frame = NULL; - old_chain = make_cleanup_delete_breakpoint (breakpoint); + make_cleanup_delete_breakpoint (breakpoint); set_longjmp_breakpoint (tp, frame_id); make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); @@ -1768,6 +1793,7 @@ finish_forward (struct symbol *function, struct frame_info *frame) cargs->thread = thread; cargs->breakpoint = breakpoint; cargs->function = function; + cargs->ctx_saver = saver; add_continuation (tp, finish_command_continuation, cargs, finish_command_continuation_free_arg); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); |