Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GDB.
/* Perform any Ada-specific coercion first. */
if (current_language->la_language == language_ada)
- arg = ada_convert_actual (arg, type, gdbarch, sp);
+ arg = ada_convert_actual (arg, type);
/* Force the value to the target if we will need its address. At
this point, we could allocate arguments on the stack instead of
{
/* Handle function descriptors lacking debug info. */
int found_descriptor = 0;
+
funaddr = 0; /* pacify "gcc -Werror" */
if (VALUE_LVAL (function) == lval_memory)
{
CORE_ADDR nfunaddr;
+
funaddr = value_as_address (value_addr (function));
nfunaddr = funaddr;
funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
{
{
struct symbol *symbol = find_pc_function (funaddr);
+
if (symbol)
return SYMBOL_PRINT_NAME (symbol);
}
{
/* Try the minimal symbols. */
struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
+
if (msymbol)
return SYMBOL_PRINT_NAME (msymbol);
}
{
char *tmp = xstrprintf (_(RAW_FUNCTION_ADDRESS_FORMAT),
hex_string (funaddr));
+
gdb_assert (strlen (tmp) + 1 <= buf_size);
strcpy (buf, tmp);
xfree (tmp);
{
volatile struct gdb_exception e;
int saved_async = 0;
- int saved_in_infcall = call_thread->in_infcall;
+ int saved_in_infcall = call_thread->control.in_infcall;
ptid_t call_thread_ptid = call_thread->ptid;
char *saved_target_shortname = xstrdup (target_shortname);
- call_thread->in_infcall = 1;
+ call_thread->control.in_infcall = 1;
clear_proceed_status ();
disable_watchpoints_before_interactive_call_start ();
- call_thread->proceed_to_finish = 1; /* We want stop_registers, please... */
+
+ /* We want stop_registers, please... */
+ call_thread->control.proceed_to_finish = 1;
if (target_can_async_p ())
saved_async = target_async_mask (0);
if (e.reason < 0)
{
if (call_thread != NULL)
- breakpoint_auto_delete (call_thread->stop_bpstat);
+ breakpoint_auto_delete (call_thread->control.stop_bpstat);
}
if (call_thread != NULL)
- call_thread->in_infcall = saved_in_infcall;
+ call_thread->control.in_infcall = saved_in_infcall;
xfree (saved_target_shortname);
return e;
}
+/* A cleanup function that calls delete_std_terminate_breakpoint. */
+static void
+cleanup_delete_std_terminate_breakpoint (void *ignore)
+{
+ delete_std_terminate_breakpoint ();
+}
+
/* All this stuff with a dummy frame may seem unnecessarily complicated
(why not just save registers in GDB?). The purpose of pushing a dummy
frame which looks just like a real frame is so that if you call a
struct type *values_type, *target_values_type;
unsigned char struct_return = 0, lang_struct_return = 0;
CORE_ADDR struct_addr = 0;
- struct inferior_status *inf_status;
+ struct infcall_control_state *inf_status;
struct cleanup *inf_status_cleanup;
- struct inferior_thread_state *caller_state;
- struct cleanup *caller_state_cleanup;
+ struct infcall_suspend_state *caller_state;
CORE_ADDR funaddr;
CORE_ADDR real_pc;
struct type *ftype = check_typedef (value_type (function));
struct cleanup *args_cleanup;
struct frame_info *frame;
struct gdbarch *gdbarch;
- struct breakpoint *terminate_bp = NULL;
- struct minimal_symbol *tm;
- struct cleanup *terminate_bp_cleanup = NULL;
+ struct cleanup *terminate_bp_cleanup;
ptid_t call_thread_ptid;
struct gdb_exception e;
- const char *name;
char name_buf[RAW_FUNCTION_ADDRESS_SIZE];
if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
/* A cleanup for the inferior status.
This is only needed while we're preparing the inferior function call. */
- inf_status = save_inferior_status ();
- inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
+ inf_status = save_infcall_control_state ();
+ inf_status_cleanup
+ = make_cleanup_restore_infcall_control_state (inf_status);
/* Save the caller's registers and other state associated with the
inferior itself so that they can be restored once the
callee returns. To allow nested calls the registers are (further
down) pushed onto a dummy frame stack. Include a cleanup (which
is tossed once the regcache has been pushed). */
- caller_state = save_inferior_thread_state ();
- caller_state_cleanup = make_cleanup_restore_inferior_thread_state (caller_state);
+ caller_state = save_infcall_suspend_state ();
+ make_cleanup_restore_infcall_suspend_state (caller_state);
/* Ensure that the initial SP is correctly aligned. */
{
CORE_ADDR old_sp = get_frame_sp (frame);
+
if (gdbarch_frame_align_p (gdbarch))
{
sp = gdbarch_frame_align (gdbarch, old_sp);
{
int i;
+
for (i = nargs - 1; i >= 0; i--)
{
int prototyped;
if (struct_return || lang_struct_return)
{
int len = TYPE_LENGTH (values_type);
+
if (gdbarch_inner_than (gdbarch, 1, 2))
{
/* Stack grows downward. Align STRUCT_ADDR and SP after
{
struct breakpoint *bpt;
struct symtab_and_line sal;
+
init_sal (&sal); /* initialize to zeroes */
sal.pspace = current_program_space;
sal.pc = bp_addr;
call. Place a momentary breakpoint in the std::terminate function
and if triggered in the call, rewind. */
if (unwind_on_terminating_exception_p)
- {
- struct minimal_symbol *tm = lookup_minimal_symbol ("std::terminate()",
- NULL, NULL);
- if (tm != NULL)
- terminate_bp = set_momentary_breakpoint_at_pc
- (gdbarch, SYMBOL_VALUE_ADDRESS (tm), bp_breakpoint);
- }
+ set_std_terminate_breakpoint ();
/* Everything's ready, push all the info needed to restore the
caller (and identify the dummy-frame) onto the dummy-frame
discard_cleanups (inf_status_cleanup);
/* Register a clean-up for unwind_on_terminating_exception_breakpoint. */
- if (terminate_bp)
- terminate_bp_cleanup = make_cleanup_delete_breakpoint (terminate_bp);
+ terminate_bp_cleanup = make_cleanup (cleanup_delete_std_terminate_breakpoint,
+ NULL);
/* - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP -
If you're looking to implement asynchronous dummy-frames, then
const char *name = get_function_name (funaddr,
name_buf, sizeof (name_buf));
- discard_inferior_status (inf_status);
+ discard_infcall_control_state (inf_status);
/* We could discard the dummy frame here if the program exited,
but it will get garbage collected the next time the program is
/* If we try to restore the inferior status,
we'll crash as the inferior is no longer running. */
- discard_inferior_status (inf_status);
+ discard_infcall_control_state (inf_status);
/* We could discard the dummy frame here given that the program exited,
but it will get garbage collected the next time the program is
signal or breakpoint while our thread was running.
There's no point in restoring the inferior status,
we're in a different thread. */
- discard_inferior_status (inf_status);
+ discard_infcall_control_state (inf_status);
/* Keep the dummy frame record, if the user switches back to the
thread with the hand-call, we'll need it. */
if (stopped_by_random_signal)
name);
}
- if (stopped_by_random_signal || !stop_stack_dummy)
+ if (stopped_by_random_signal || stop_stack_dummy != STOP_STACK_DUMMY)
{
const char *name = get_function_name (funaddr,
name_buf, sizeof (name_buf));
/* We also need to restore inferior status to that before the
dummy call. */
- restore_inferior_status (inf_status);
+ restore_infcall_control_state (inf_status);
/* FIXME: Insert a bunch of wrap_here; name can be very
long if it's a C++ name with arguments and stuff. */
(default).
Discard inferior status, we're not at the same point
we started at. */
- discard_inferior_status (inf_status);
+ discard_infcall_control_state (inf_status);
/* FIXME: Insert a bunch of wrap_here; name can be very
long if it's a C++ name with arguments and stuff. */
}
}
- if (!stop_stack_dummy)
+ if (stop_stack_dummy == STOP_STD_TERMINATE)
{
+ /* We must get back to the frame we were before the dummy
+ call. */
+ dummy_frame_pop (dummy_id);
- /* Check if unwind on terminating exception behaviour is on. */
- if (unwind_on_terminating_exception_p)
- {
- /* Check that the breakpoint is our special std::terminate
- breakpoint. If it is, we do not want to kill the inferior
- in an inferior function call. Rewind, and warn the
- user. */
-
- if (terminate_bp != NULL
- && (inferior_thread ()->stop_bpstat->breakpoint_at->address
- == terminate_bp->loc->address))
- {
- /* We must get back to the frame we were before the
- dummy call. */
- dummy_frame_pop (dummy_id);
-
- /* We also need to restore inferior status to that before the
- dummy call. */
- restore_inferior_status (inf_status);
-
- error (_("\
+ /* We also need to restore inferior status to that before
+ the dummy call. */
+ restore_infcall_control_state (inf_status);
+
+ error (_("\
The program being debugged entered a std::terminate call, most likely\n\
caused by an unhandled C++ exception. GDB blocked this call in order\n\
to prevent the program from being terminated, and has restored the\n\
To change this behaviour use \"set unwind-on-terminating-exception off\".\n\
Evaluation of the expression containing the function (%s)\n\
will be abandoned."),
- name);
- }
- }
+ name);
+ }
+ else if (stop_stack_dummy == STOP_NONE)
+ {
+
/* We hit a breakpoint inside the FUNCTION.
Keep the dummy frame, the user may want to examine its state.
Discard inferior status, we're not at the same point
we started at. */
- discard_inferior_status (inf_status);
+ discard_infcall_control_state (inf_status);
/* The following error message used to say "The expression
which contained the function call has been discarded."
internal_error (__FILE__, __LINE__, _("... should not be here"));
}
- /* If we get here and the std::terminate() breakpoint has been set,
- it has to be cleaned manually. */
- if (terminate_bp)
- do_cleanups (terminate_bp_cleanup);
+ do_cleanups (terminate_bp_cleanup);
/* If we get here the called FUNCTION ran to completion,
and the dummy frame has already been popped. */
/* Inferior call is successful. Restore the inferior status.
At this stage, leave the RETBUF alone. */
- restore_inferior_status (inf_status);
+ restore_infcall_control_state (inf_status);
/* Figure out the value returned by the function. */