diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 44d27b535f..2c3e57e60a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2002-07-03 Andrew Cagney + + * valops.c (hand_function_call): Move declaration of retbuf to + start of function, allocate using malloc, add a cleanup but before + the inf_status cleanup, cleanup the buffer. Rename local variable + old_chain to inf_status_cleanup. + 2002-07-03 Martin M. Hunt * top.c (execute_command): Use cmd_func() and cmd_func_p(). diff --git a/gdb/valops.c b/gdb/valops.c index 514a9f14b7..3e72e9495c 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1316,8 +1316,10 @@ hand_function_call (struct value *function, int nargs, struct value **args) struct type *value_type; unsigned char struct_return; CORE_ADDR struct_addr = 0; + char *retbuf; + struct cleanup *retbuf_cleanup; struct inferior_status *inf_status; - struct cleanup *old_chain; + struct cleanup *inf_status_cleanup; CORE_ADDR funaddr; int using_gcc; /* Set to version of gcc in use, or zero if not gcc */ CORE_ADDR real_pc; @@ -1333,8 +1335,18 @@ hand_function_call (struct value *function, int nargs, struct value **args) if (!target_has_execution) noprocess (); + /* Create a cleanup chain that contains the retbuf (buffer + containing the register values). This chain is create BEFORE the + inf_status chain so that the inferior status can cleaned up + (restored or discarded) without having the retbuf freed. */ + retbuf = xmalloc (REGISTER_BYTES); + retbuf_cleanup = make_cleanup (xfree, retbuf); + + /* A cleanup for the inferior status. Create this AFTER the retbuf + so that this can be discarded or applied without interfering with + the regbuf. */ inf_status = save_inferior_status (1); - old_chain = make_cleanup_restore_inferior_status (inf_status); + inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status); /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers (and POP_FRAME for restoring them). (At least on most machines) @@ -1656,7 +1668,6 @@ You must use a pointer to function type variable. Command ignored.", arg_name); SAVE_DUMMY_FRAME_TOS (sp); { - char *retbuf = (char*) alloca (REGISTER_BYTES); char *name; struct symbol *symbol; @@ -1715,11 +1726,12 @@ Evaluation of the expression containing the function (%s) will be abandoned.", { /* The user wants to stay in the frame where we stopped (default).*/ - /* If we did the cleanups, we would print a spurious error - message (Unable to restore previously selected frame), - would write the registers from the inf_status (which is - wrong), and would do other wrong things. */ - discard_cleanups (old_chain); + /* If we restored the inferior status (via the cleanup), + we would print a spurious error message (Unable to + restore previously selected frame), would write the + registers from the inf_status (which is wrong), and + would do other wrong things. */ + discard_cleanups (inf_status_cleanup); discard_inferior_status (inf_status); /* FIXME: Insert a bunch of wrap_here; name can be very long if it's @@ -1737,11 +1749,12 @@ Evaluation of the expression containing the function (%s) will be abandoned.", { /* We hit a breakpoint inside the FUNCTION. */ - /* If we did the cleanups, we would print a spurious error - message (Unable to restore previously selected frame), - would write the registers from the inf_status (which is - wrong), and would do other wrong things. */ - discard_cleanups (old_chain); + /* If we restored the inferior status (via the cleanup), we + would print a spurious error message (Unable to restore + previously selected frame), would write the registers from + the inf_status (which is wrong), and would do other wrong + things. */ + discard_cleanups (inf_status_cleanup); discard_inferior_status (inf_status); /* The following error message used to say "The expression @@ -1761,7 +1774,10 @@ the function call).", name); } /* If we get here the called FUNCTION run to completion. */ - do_cleanups (old_chain); + + /* Restore the inferior status, via its cleanup. At this stage, + leave the RETBUF alone. */ + do_cleanups (inf_status_cleanup); /* Figure out the value returned by the function. */ /* elz: I defined this new macro for the hppa architecture only. @@ -1774,10 +1790,17 @@ the function call).", name); #ifdef VALUE_RETURNED_FROM_STACK if (struct_return) - return (struct value *) VALUE_RETURNED_FROM_STACK (value_type, struct_addr); + { + do_cleanups (retbuf_cleanup); + return VALUE_RETURNED_FROM_STACK (value_type, struct_addr); + } #endif - return value_being_returned (value_type, retbuf, struct_return); + { + struct value *retval = value_being_returned (value_type, retbuf, struct_return); + do_cleanups (retbuf_cleanup); + return retval; + } } }