binutils-gdb/gdb/dummy-frame.h

75 lines
2.9 KiB
C
Raw Normal View History

/* Code dealing with dummy stack frames, for GDB, the GNU debugger.
Copyright (C) 2002-2017 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#if !defined (DUMMY_FRAME_H)
#define DUMMY_FRAME_H 1
#include "frame.h"
gdb/ Rename and move inferior_thread_state and inferior_status. * gdbthread.h (struct thread_control_state): New struct, move fields step_range_start, step_range_end, step_frame_id, step_stack_frame_id, trap_expected, proceed_to_finish, in_infcall, step_over_calls, stop_step and stop_bpstat here from struct thread_info. (struct thread_suspend_state): New struct, move field stop_signal here from struct thread_info. (struct thread_info): Move the fields above from this struct. * inferior.h: Move the inferior_thread_state and inferior_status declarations comment to their definitions at infrun.c. (struct inferior_control_state): New struct, move field stop_soon from struct inferior here. (struct inferior_suspend_state): New empty struct. (struct inferior): New fields control and suspend. Move out field stop_soon. * infrun.c (struct inferior_thread_state): Rename to ... (infcall_suspend_state): ... here. Replace field stop_signal by fields thread_suspend and inferior_suspend. (save_inferior_thread_state): Rename to ... (save_infcall_suspend_state): ... here. New variable inf. Update the code for new fields. (restore_inferior_thread_state): Rename to ... (restore_infcall_suspend_state): ... here. New variable inf. Update the code for new fields. (do_restore_inferior_thread_state_cleanup): Rename to ... (do_restore_infcall_suspend_state_cleanup): ... here. (make_cleanup_restore_inferior_thread_state): Rename to ... (make_cleanup_restore_infcall_suspend_state): ... here. (discard_inferior_thread_state): Rename to ... (discard_infcall_suspend_state): ... here. (get_inferior_thread_state_regcache): Rename to ... (get_infcall_suspend_state_regcache): ... here. (struct inferior_status): Rename to ... (struct infcall_control_state): ... here. Replace fields step_range_start, step_range_end, step_frame_id, step_stack_frame_id, trap_expected, proceed_to_finish, in_infcall, step_over_calls, stop_step, stop_bpstat and stop_soon by fields thread_control and inferior_control. (save_inferior_status): Rename to ... (save_infcall_control_state): ... here. Update the code for new fields. (restore_inferior_status): Rename to ... (restore_infcall_control_state): ... here. Update the code for new fields. (do_restore_inferior_status_cleanup): Rename to ... (do_restore_infcall_control_state_cleanup): ... here. (make_cleanup_restore_inferior_status): Rename to ... (make_cleanup_restore_infcall_control_state): ... here. (discard_inferior_status): Rename to ... (discard_infcall_control_state): ... here. * alpha-tdep.c, breakpoint.c, dummy-frame.c, dummy-frame.h, exceptions.c, fbsd-nat.c, gdbthread.h, infcall.c, infcmd.c, inferior.c, inferior.h, infrun.c, linux-nat.c, mi/mi-interp.c, mips-tdep.c, procfs.c, solib-irix.c, solib-osf.c, solib-spu.c, solib-sunos.c, solib-svr4.c, thread.c, windows-nat.c: Update all the references to the moved fields and renamed functions.
2010-11-28 12:31:25 +08:00
struct infcall_suspend_state;
struct frame_unwind;
/* Push the information needed to identify, and unwind from, a dummy
frame onto the dummy frame stack. */
/* NOTE: cagney/2004-08-02: In the case of ABIs using push_dummy_code
containing more than one instruction, this interface many need to
be expanded so that it knowns the lower/upper extent of the dummy
frame's code. */
gdb/ Rename and move inferior_thread_state and inferior_status. * gdbthread.h (struct thread_control_state): New struct, move fields step_range_start, step_range_end, step_frame_id, step_stack_frame_id, trap_expected, proceed_to_finish, in_infcall, step_over_calls, stop_step and stop_bpstat here from struct thread_info. (struct thread_suspend_state): New struct, move field stop_signal here from struct thread_info. (struct thread_info): Move the fields above from this struct. * inferior.h: Move the inferior_thread_state and inferior_status declarations comment to their definitions at infrun.c. (struct inferior_control_state): New struct, move field stop_soon from struct inferior here. (struct inferior_suspend_state): New empty struct. (struct inferior): New fields control and suspend. Move out field stop_soon. * infrun.c (struct inferior_thread_state): Rename to ... (infcall_suspend_state): ... here. Replace field stop_signal by fields thread_suspend and inferior_suspend. (save_inferior_thread_state): Rename to ... (save_infcall_suspend_state): ... here. New variable inf. Update the code for new fields. (restore_inferior_thread_state): Rename to ... (restore_infcall_suspend_state): ... here. New variable inf. Update the code for new fields. (do_restore_inferior_thread_state_cleanup): Rename to ... (do_restore_infcall_suspend_state_cleanup): ... here. (make_cleanup_restore_inferior_thread_state): Rename to ... (make_cleanup_restore_infcall_suspend_state): ... here. (discard_inferior_thread_state): Rename to ... (discard_infcall_suspend_state): ... here. (get_inferior_thread_state_regcache): Rename to ... (get_infcall_suspend_state_regcache): ... here. (struct inferior_status): Rename to ... (struct infcall_control_state): ... here. Replace fields step_range_start, step_range_end, step_frame_id, step_stack_frame_id, trap_expected, proceed_to_finish, in_infcall, step_over_calls, stop_step, stop_bpstat and stop_soon by fields thread_control and inferior_control. (save_inferior_status): Rename to ... (save_infcall_control_state): ... here. Update the code for new fields. (restore_inferior_status): Rename to ... (restore_infcall_control_state): ... here. Update the code for new fields. (do_restore_inferior_status_cleanup): Rename to ... (do_restore_infcall_control_state_cleanup): ... here. (make_cleanup_restore_inferior_status): Rename to ... (make_cleanup_restore_infcall_control_state): ... here. (discard_inferior_status): Rename to ... (discard_infcall_control_state): ... here. * alpha-tdep.c, breakpoint.c, dummy-frame.c, dummy-frame.h, exceptions.c, fbsd-nat.c, gdbthread.h, infcall.c, infcmd.c, inferior.c, inferior.h, infrun.c, linux-nat.c, mi/mi-interp.c, mips-tdep.c, procfs.c, solib-irix.c, solib-osf.c, solib-spu.c, solib-sunos.c, solib-svr4.c, thread.c, windows-nat.c: Update all the references to the moved fields and renamed functions.
2010-11-28 12:31:25 +08:00
extern void dummy_frame_push (struct infcall_suspend_state *caller_state,
Associate dummy_frame with ptid This patch is to add ptid into dummy_frame and extend frame_id to dummy_frame_id (which has a ptid field). With this change, GDB uses dummy_frame_id (thread ptid and frame_id) to find the dummy frames. Currently, dummy frames are looked up by frame_id, which isn't accurate in non-stop or multi-process mode. The test case gdb.multi/dummy-frame-restore.exp shows the problem and this patch can fix it. Test dummy-frame-restore.exp makes two inferiors stop at different functions, say, inferior 1 stops at f1 while inferior 2 stops at f2. Set a breakpoint to a function, do the inferior call in two inferiors, and GDB has two dummy frames of the same frame_id. When the inferior call is finished, GDB will look up a dummy frame from its stack/list and restore the inferior's regcache. Two inferiors are finished in different orders, the inferiors' states are restored differently, which is wrong. Running dummy-frame-restore.exp under un-patched GDB, we'll get two fails: FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 2 FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 1 With this patch applied, GDB will choose the correct dummy_frame to restore for a given inferior, because ptid is considered when looking up dummy frames. Two fails above are fixed. Regression tested on x86_64-linux, both native and gdbserver. gdb: 2014-06-27 Yao Qi <yao@codesourcery.com> * breakpoint.c (check_longjmp_breakpoint_for_call_dummy): Change parameter type to 'struct thread_info *'. Caller updated. * breakpoint.h (check_longjmp_breakpoint_for_call_dummy): Update declaration. * dummy-frame.c (struct dummy_frame_id): New. (dummy_frame_id_eq): New function. (struct dummy_frame) <id>: Change its type to 'struct dummy_frame_id'. (dummy_frame_push): Add parameter ptid and save it in dummy_frame_id. (pop_dummy_frame_bpt): Use ptid of dummy_frame instead of inferior_ptid. (pop_dummy_frame): Assert that the ptid of dummy_frame equals to inferior_ptid. (lookup_dummy_frame): Change parameter type to 'struct dummy_frame_id *'. Callers updated. Call dummy_frame_id_eq instead of frame_id_eq. (dummy_frame_pop): Add parameter ptid. Callers updated. Update comments. Compose dummy_frame_id and pass it to lookup_dummy_frame. (dummy_frame_discard): Add parameter ptid. (dummy_frame_sniffer): Compose dummy_frame_id and call dummy_frame_id_eq instead of frame_id_eq. (fprint_dummy_frames): Print ptid. * dummy-frame.h: Remove comments. (dummy_frame_push): Add ptid in declaration. (dummy_frame_pop, dummy_frame_discard): Likewise. gdb/testsuite: 2014-06-27 Yao Qi <yao@codesourcery.com> * gdb.multi/dummy-frame-restore.exp: New. * gdb.multi/dummy-frame-restore.c: New. gdb/doc: 2014-06-27 Yao Qi <yao@codesourcery.com> * gdb.texinfo (Maintenance Commands): Update the output of 'maint print dummy-frames' command.
2014-06-25 11:52:52 +08:00
const struct frame_id *dummy_id, ptid_t ptid);
* dummy-frame.c (dummy_frame): Replace regcache member with caller_state. (dummy_frame_push): Replace caller_regcache arg with caller_state. All callers updated. (remove_dummy_frame,pop_dummy_frame,lookup_dummy_frame): New fns. (dummy_frame_pop): Rewrite. Verify requested frame is in the dummy frame stack. Restore program state. (cleanup_dummy_frames): Rewrite. (dummy_frame_sniffer): Update. Make static. * dummy-frame.h (regcache,frame_info): Delete forward decls. (inferior_thread_state): New forward decl. (dummy_frame_push): Update prototype. * frame.c (frame_pop): dummy_frame_pop now does all the work for DUMMY_FRAMEs. * infcall.c (breakpoint_auto_delete_contents): Delete. (get_function_name,run_inferior_call): New fns. (call_function_by_hand): Simplify by moving some code to get_function_name, run_inferior_call. Inferior function call wrapped in TRY_CATCH so there's less need for cleanups and all exits from proceed are handled similarily. Detect program exit. Detect program stopping in a different thread. Make error messages more consistent. * inferior.h (inferior_thread_state): Declare (opaque type). (save_inferior_thread_state,restore_inferior_thread_state, make_cleanup_restore_inferior_thread_state, discard_inferior_thread_state, get_inferior_thread_state_regcache): Declare. (save_inferior_status): Update prototype. * infrun.c: (normal_stop): When stopped for the completion of an inferior function call, verify the expected stack frame kind. (inferior_thread_state): New struct. (save_inferior_thread_state,restore_inferior_thread_state, do_restore_inferior_thread_state_cleanup, make_cleanup_restore_inferior_thread_state, discard_inferior_thread_state, get_inferior_thread_state_regcache): New functions. (inferior_status): Move stop_signal, stop_pc, registers to inferior_thread_state. Remove restore_stack_info. (save_inferior_status): Remove arg restore_stack_info. All callers updated. Remove saving of state now saved by save_inferior_thread_state. (restore_inferior_status): Remove restoration of state now done by restore_inferior_thread_state. (discard_inferior_status): Remove freeing of registers, now done by discard_inferior_thread_state. * gdb.base/break.exp: Update expected gdb output. * gdb.base/sepdebug.exp: Ditto. * gdb.mi/mi-syn-frame.exp: Ditto. * gdb.mi/mi2-syn-frame.exp: Ditto. * gdb.base/call-signal-resume.exp: New file. * gdb.base/call-signals.c: New file. * gdb.base/unwindonsignal.exp: New file. * gdb.base/unwindonsignal.c: New file. * gdb.threads/interrupted-hand-call.exp: New file. * gdb.threads/interrupted-hand-call.c: New file. * gdb.threads/thread-unwindonsignal.exp: New file.
2009-01-20 03:05:01 +08:00
/* Pop the dummy frame DUMMY_ID, restoring program state to that before the
frame was created.
On return reinit_frame_cache has been called.
If the frame isn't found, flag an internal error.
NOTE: This can only pop the one frame, even if it is in the middle of the
stack, because the other frames may be for different threads, and there's
currently no way to tell which stack frame is for which thread. */
Associate dummy_frame with ptid This patch is to add ptid into dummy_frame and extend frame_id to dummy_frame_id (which has a ptid field). With this change, GDB uses dummy_frame_id (thread ptid and frame_id) to find the dummy frames. Currently, dummy frames are looked up by frame_id, which isn't accurate in non-stop or multi-process mode. The test case gdb.multi/dummy-frame-restore.exp shows the problem and this patch can fix it. Test dummy-frame-restore.exp makes two inferiors stop at different functions, say, inferior 1 stops at f1 while inferior 2 stops at f2. Set a breakpoint to a function, do the inferior call in two inferiors, and GDB has two dummy frames of the same frame_id. When the inferior call is finished, GDB will look up a dummy frame from its stack/list and restore the inferior's regcache. Two inferiors are finished in different orders, the inferiors' states are restored differently, which is wrong. Running dummy-frame-restore.exp under un-patched GDB, we'll get two fails: FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 2 FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 1 With this patch applied, GDB will choose the correct dummy_frame to restore for a given inferior, because ptid is considered when looking up dummy frames. Two fails above are fixed. Regression tested on x86_64-linux, both native and gdbserver. gdb: 2014-06-27 Yao Qi <yao@codesourcery.com> * breakpoint.c (check_longjmp_breakpoint_for_call_dummy): Change parameter type to 'struct thread_info *'. Caller updated. * breakpoint.h (check_longjmp_breakpoint_for_call_dummy): Update declaration. * dummy-frame.c (struct dummy_frame_id): New. (dummy_frame_id_eq): New function. (struct dummy_frame) <id>: Change its type to 'struct dummy_frame_id'. (dummy_frame_push): Add parameter ptid and save it in dummy_frame_id. (pop_dummy_frame_bpt): Use ptid of dummy_frame instead of inferior_ptid. (pop_dummy_frame): Assert that the ptid of dummy_frame equals to inferior_ptid. (lookup_dummy_frame): Change parameter type to 'struct dummy_frame_id *'. Callers updated. Call dummy_frame_id_eq instead of frame_id_eq. (dummy_frame_pop): Add parameter ptid. Callers updated. Update comments. Compose dummy_frame_id and pass it to lookup_dummy_frame. (dummy_frame_discard): Add parameter ptid. (dummy_frame_sniffer): Compose dummy_frame_id and call dummy_frame_id_eq instead of frame_id_eq. (fprint_dummy_frames): Print ptid. * dummy-frame.h: Remove comments. (dummy_frame_push): Add ptid in declaration. (dummy_frame_pop, dummy_frame_discard): Likewise. gdb/testsuite: 2014-06-27 Yao Qi <yao@codesourcery.com> * gdb.multi/dummy-frame-restore.exp: New. * gdb.multi/dummy-frame-restore.c: New. gdb/doc: 2014-06-27 Yao Qi <yao@codesourcery.com> * gdb.texinfo (Maintenance Commands): Update the output of 'maint print dummy-frames' command.
2014-06-25 11:52:52 +08:00
extern void dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid);
Associate dummy_frame with ptid This patch is to add ptid into dummy_frame and extend frame_id to dummy_frame_id (which has a ptid field). With this change, GDB uses dummy_frame_id (thread ptid and frame_id) to find the dummy frames. Currently, dummy frames are looked up by frame_id, which isn't accurate in non-stop or multi-process mode. The test case gdb.multi/dummy-frame-restore.exp shows the problem and this patch can fix it. Test dummy-frame-restore.exp makes two inferiors stop at different functions, say, inferior 1 stops at f1 while inferior 2 stops at f2. Set a breakpoint to a function, do the inferior call in two inferiors, and GDB has two dummy frames of the same frame_id. When the inferior call is finished, GDB will look up a dummy frame from its stack/list and restore the inferior's regcache. Two inferiors are finished in different orders, the inferiors' states are restored differently, which is wrong. Running dummy-frame-restore.exp under un-patched GDB, we'll get two fails: FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 2 FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 1 With this patch applied, GDB will choose the correct dummy_frame to restore for a given inferior, because ptid is considered when looking up dummy frames. Two fails above are fixed. Regression tested on x86_64-linux, both native and gdbserver. gdb: 2014-06-27 Yao Qi <yao@codesourcery.com> * breakpoint.c (check_longjmp_breakpoint_for_call_dummy): Change parameter type to 'struct thread_info *'. Caller updated. * breakpoint.h (check_longjmp_breakpoint_for_call_dummy): Update declaration. * dummy-frame.c (struct dummy_frame_id): New. (dummy_frame_id_eq): New function. (struct dummy_frame) <id>: Change its type to 'struct dummy_frame_id'. (dummy_frame_push): Add parameter ptid and save it in dummy_frame_id. (pop_dummy_frame_bpt): Use ptid of dummy_frame instead of inferior_ptid. (pop_dummy_frame): Assert that the ptid of dummy_frame equals to inferior_ptid. (lookup_dummy_frame): Change parameter type to 'struct dummy_frame_id *'. Callers updated. Call dummy_frame_id_eq instead of frame_id_eq. (dummy_frame_pop): Add parameter ptid. Callers updated. Update comments. Compose dummy_frame_id and pass it to lookup_dummy_frame. (dummy_frame_discard): Add parameter ptid. (dummy_frame_sniffer): Compose dummy_frame_id and call dummy_frame_id_eq instead of frame_id_eq. (fprint_dummy_frames): Print ptid. * dummy-frame.h: Remove comments. (dummy_frame_push): Add ptid in declaration. (dummy_frame_pop, dummy_frame_discard): Likewise. gdb/testsuite: 2014-06-27 Yao Qi <yao@codesourcery.com> * gdb.multi/dummy-frame-restore.exp: New. * gdb.multi/dummy-frame-restore.c: New. gdb/doc: 2014-06-27 Yao Qi <yao@codesourcery.com> * gdb.texinfo (Maintenance Commands): Update the output of 'maint print dummy-frames' command.
2014-06-25 11:52:52 +08:00
extern void dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid);
gdb/ Remove stale dummy frames. * breakpoint.c: Include dummy-frame.h. (longjmp_breakpoint_ops): New variable. (update_breakpoints_after_exec, breakpoint_init_inferior): Delete also bp_longjmp_call_dummy. (bpstat_what, bptype_string, print_one_breakpoint_location) (init_bp_location): Support bp_longjmp_call_dummy. (set_longjmp_breakpoint): Use longjmp_breakpoint_ops. Comment why. (set_longjmp_breakpoint_for_call_dummy) (check_longjmp_breakpoint_for_call_dummy, longjmp_bkpt_dtor): New functions. (initialize_breakpoint_ops): Initialize longjmp_breakpoint_ops. * breakpoint.h (enum bptype): New item bp_longjmp_call_dummy. Delete FIXME comment and extend the other comment for bp_call_dummy. (set_longjmp_breakpoint_for_call_dummy) (check_longjmp_breakpoint_for_call_dummy): New declarations. * dummy-frame.c: Include gdbthread.h. (pop_dummy_frame_bpt): New function. (pop_dummy_frame): Call pop_dummy_frame_bpt. (dummy_frame_discard): New function. (cleanup_dummy_frames): Update the comment about longjmps. * dummy-frame.h (dummy_frame_discard): New declaration. * gdbthread.h (struct thread_info): Extend initiating_frame comment. * infcall.c (call_function_by_hand): New variable longjmp_b. Call set_longjmp_breakpoint_for_call_dummy. Chain its breakpoints with BPT. * infrun.c (handle_inferior_event) <BPSTAT_WHAT_CLEAR_LONGJMP_RESUME>: Add case 4 comment. Call check_longjmp_breakpoint_for_call_dummy and keep_going if IS_LONGJMP and there is no other reason to stop. gdb/testsuite/ Remove stale dummy frames. * gdb.base/call-signal-resume.exp (maintenance print dummy-frames) (maintenance info breakpoints): New tests. * gdb.base/stale-infcall.c: New file. * gdb.base/stale-infcall.exp: New file.
2012-06-19 01:28:38 +08:00
/* If the PC falls in a dummy frame, return a dummy frame
unwinder. */
extern const struct frame_unwind dummy_frame_unwind;
/* Destructor for dummy_frame. DATA is supplied by registrant.
REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard. */
typedef void (dummy_frame_dtor_ftype) (void *data, int registers_valid);
/* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread PTID gets discarded.
Dummy frame with DUMMY_ID must exist. Multiple destructors may be
registered, they will be called in the reverse order of registrations
(LIFO). */
extern void register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid,
dummy_frame_dtor_ftype *dtor,
void *dtor_data);
/* Return 1 if there exists any dummy frame with any of its registered
destructors equal to both DTOR and DTOR_DATA. Return 0 otherwise. */
extern int find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor,
void *dtor_data);
#endif /* !defined (DUMMY_FRAME_H) */