| /* Perform an inferior function call, for GDB, the GNU debugger. | 
 |  | 
 |    Copyright (C) 1986-2023 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/>.  */ | 
 |  | 
 | #include "defs.h" | 
 | #include "infcall.h" | 
 | #include "breakpoint.h" | 
 | #include "tracepoint.h" | 
 | #include "target.h" | 
 | #include "regcache.h" | 
 | #include "inferior.h" | 
 | #include "infrun.h" | 
 | #include "block.h" | 
 | #include "gdbcore.h" | 
 | #include "language.h" | 
 | #include "objfiles.h" | 
 | #include "gdbcmd.h" | 
 | #include "command.h" | 
 | #include "dummy-frame.h" | 
 | #include "ada-lang.h" | 
 | #include "f-lang.h" | 
 | #include "gdbthread.h" | 
 | #include "event-top.h" | 
 | #include "observable.h" | 
 | #include "top.h" | 
 | #include "interps.h" | 
 | #include "thread-fsm.h" | 
 | #include <algorithm> | 
 | #include "gdbsupport/scope-exit.h" | 
 | #include <list> | 
 |  | 
 | /* True if we are debugging inferior calls.  */ | 
 |  | 
 | static bool debug_infcall = false; | 
 |  | 
 | /* Print an "infcall" debug statement.  */ | 
 |  | 
 | #define infcall_debug_printf(fmt, ...) \ | 
 |   debug_prefixed_printf_cond (debug_infcall, "infcall", fmt, ##__VA_ARGS__) | 
 |  | 
 | /* Print "infcall" enter/exit debug statements.  */ | 
 |  | 
 | #define INFCALL_SCOPED_DEBUG_ENTER_EXIT \ | 
 |   scoped_debug_enter_exit (debug_infcall, "infcall") | 
 |  | 
 | /* Print "infcall" start/end debug statements.  */ | 
 |  | 
 | #define INFCALL_SCOPED_DEBUG_START_END(fmt, ...) \ | 
 |   scoped_debug_start_end (debug_infrun, "infcall", fmt, ##__VA_ARGS__) | 
 |  | 
 | /* Implement 'show debug infcall'.  */ | 
 |  | 
 | static void | 
 | show_debug_infcall (struct ui_file *file, int from_tty, | 
 | 		   struct cmd_list_element *c, const char *value) | 
 | { | 
 |   gdb_printf (file, _("Inferior call debugging is %s.\n"), value); | 
 | } | 
 |  | 
 | /* If we can't find a function's name from its address, | 
 |    we print this instead.  */ | 
 | #define RAW_FUNCTION_ADDRESS_FORMAT "at 0x%s" | 
 | #define RAW_FUNCTION_ADDRESS_SIZE (sizeof (RAW_FUNCTION_ADDRESS_FORMAT) \ | 
 | 				   + 2 * sizeof (CORE_ADDR)) | 
 |  | 
 | /* NOTE: cagney/2003-04-16: What's the future of this code? | 
 |  | 
 |    GDB needs an asynchronous expression evaluator, that means an | 
 |    asynchronous inferior function call implementation, and that in | 
 |    turn means restructuring the code so that it is event driven.  */ | 
 |  | 
 | static bool may_call_functions_p = true; | 
 | static void | 
 | show_may_call_functions_p (struct ui_file *file, int from_tty, | 
 | 			   struct cmd_list_element *c, | 
 | 			   const char *value) | 
 | { | 
 |   gdb_printf (file, | 
 | 	      _("Permission to call functions in the program is %s.\n"), | 
 | 	      value); | 
 | } | 
 |  | 
 | /* How you should pass arguments to a function depends on whether it | 
 |    was defined in K&R style or prototype style.  If you define a | 
 |    function using the K&R syntax that takes a `float' argument, then | 
 |    callers must pass that argument as a `double'.  If you define the | 
 |    function using the prototype syntax, then you must pass the | 
 |    argument as a `float', with no promotion. | 
 |  | 
 |    Unfortunately, on certain older platforms, the debug info doesn't | 
 |    indicate reliably how each function was defined.  A function type's | 
 |    TYPE_PROTOTYPED flag may be clear, even if the function was defined | 
 |    in prototype style.  When calling a function whose TYPE_PROTOTYPED | 
 |    flag is clear, GDB consults this flag to decide what to do. | 
 |  | 
 |    For modern targets, it is proper to assume that, if the prototype | 
 |    flag is clear, that can be trusted: `float' arguments should be | 
 |    promoted to `double'.  For some older targets, if the prototype | 
 |    flag is clear, that doesn't tell us anything.  The default is to | 
 |    trust the debug information; the user can override this behavior | 
 |    with "set coerce-float-to-double 0".  */ | 
 |  | 
 | static bool coerce_float_to_double_p = true; | 
 | static void | 
 | show_coerce_float_to_double_p (struct ui_file *file, int from_tty, | 
 | 			       struct cmd_list_element *c, const char *value) | 
 | { | 
 |   gdb_printf (file, | 
 | 	      _("Coercion of floats to doubles " | 
 | 		"when calling functions is %s.\n"), | 
 | 	      value); | 
 | } | 
 |  | 
 | /* This boolean tells what gdb should do if a signal is received while | 
 |    in a function called from gdb (call dummy).  If set, gdb unwinds | 
 |    the stack and restore the context to what as it was before the | 
 |    call. | 
 |  | 
 |    The default is to stop in the frame where the signal was received.  */ | 
 |  | 
 | static bool unwind_on_signal_p = false; | 
 | static void | 
 | show_unwind_on_signal_p (struct ui_file *file, int from_tty, | 
 | 			 struct cmd_list_element *c, const char *value) | 
 | { | 
 |   gdb_printf (file, | 
 | 	      _("Unwinding of stack if a signal is " | 
 | 		"received while in a call dummy is %s.\n"), | 
 | 	      value); | 
 | } | 
 |  | 
 | /* This boolean tells what gdb should do if a std::terminate call is | 
 |    made while in a function called from gdb (call dummy). | 
 |    As the confines of a single dummy stack prohibit out-of-frame | 
 |    handlers from handling a raised exception, and as out-of-frame | 
 |    handlers are common in C++, this can lead to no handler being found | 
 |    by the unwinder, and a std::terminate call.  This is a false positive. | 
 |    If set, gdb unwinds the stack and restores the context to what it | 
 |    was before the call. | 
 |  | 
 |    The default is to unwind the frame if a std::terminate call is | 
 |    made.  */ | 
 |  | 
 | static bool unwind_on_terminating_exception_p = true; | 
 |  | 
 | static void | 
 | show_unwind_on_terminating_exception_p (struct ui_file *file, int from_tty, | 
 | 					struct cmd_list_element *c, | 
 | 					const char *value) | 
 |  | 
 | { | 
 |   gdb_printf (file, | 
 | 	      _("Unwind stack if a C++ exception is " | 
 | 		"unhandled while in a call dummy is %s.\n"), | 
 | 	      value); | 
 | } | 
 |  | 
 | /* Perform the standard coercions that are specified | 
 |    for arguments to be passed to C, Ada or Fortran functions. | 
 |  | 
 |    If PARAM_TYPE is non-NULL, it is the expected parameter type. | 
 |    IS_PROTOTYPED is non-zero if the function declaration is prototyped.  */ | 
 |  | 
 | static struct value * | 
 | value_arg_coerce (struct gdbarch *gdbarch, struct value *arg, | 
 | 		  struct type *param_type, int is_prototyped) | 
 | { | 
 |   const struct builtin_type *builtin = builtin_type (gdbarch); | 
 |   struct type *arg_type = check_typedef (value_type (arg)); | 
 |   struct type *type | 
 |     = param_type ? check_typedef (param_type) : arg_type; | 
 |  | 
 |   /* Perform any Ada- and Fortran-specific coercion first.  */ | 
 |   if (current_language->la_language == language_ada) | 
 |     arg = ada_convert_actual (arg, type); | 
 |   else if (current_language->la_language == language_fortran) | 
 |     type = fortran_preserve_arg_pointer (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 | 
 |      calling malloc if we knew that their addresses would not be | 
 |      saved by the called function.  */ | 
 |   arg = value_coerce_to_target (arg); | 
 |  | 
 |   switch (type->code ()) | 
 |     { | 
 |     case TYPE_CODE_REF: | 
 |     case TYPE_CODE_RVALUE_REF: | 
 |       { | 
 | 	struct value *new_value; | 
 |  | 
 | 	if (TYPE_IS_REFERENCE (arg_type)) | 
 | 	  return value_cast_pointers (type, arg, 0); | 
 |  | 
 | 	/* Cast the value to the reference's target type, and then | 
 | 	   convert it back to a reference.  This will issue an error | 
 | 	   if the value was not previously in memory - in some cases | 
 | 	   we should clearly be allowing this, but how?  */ | 
 | 	new_value = value_cast (type->target_type (), arg); | 
 | 	new_value = value_ref (new_value, type->code ()); | 
 | 	return new_value; | 
 |       } | 
 |     case TYPE_CODE_INT: | 
 |     case TYPE_CODE_CHAR: | 
 |     case TYPE_CODE_BOOL: | 
 |     case TYPE_CODE_ENUM: | 
 |       /* If we don't have a prototype, coerce to integer type if necessary.  */ | 
 |       if (!is_prototyped) | 
 | 	{ | 
 | 	  if (type->length () < builtin->builtin_int->length ()) | 
 | 	    type = builtin->builtin_int; | 
 | 	} | 
 |       /* Currently all target ABIs require at least the width of an integer | 
 | 	 type for an argument.  We may have to conditionalize the following | 
 | 	 type coercion for future targets.  */ | 
 |       if (type->length () < builtin->builtin_int->length ()) | 
 | 	type = builtin->builtin_int; | 
 |       break; | 
 |     case TYPE_CODE_FLT: | 
 |       if (!is_prototyped && coerce_float_to_double_p) | 
 | 	{ | 
 | 	  if (type->length () < builtin->builtin_double->length ()) | 
 | 	    type = builtin->builtin_double; | 
 | 	  else if (type->length () > builtin->builtin_double->length ()) | 
 | 	    type = builtin->builtin_long_double; | 
 | 	} | 
 |       break; | 
 |     case TYPE_CODE_FUNC: | 
 |       type = lookup_pointer_type (type); | 
 |       break; | 
 |     case TYPE_CODE_ARRAY: | 
 |       /* Arrays are coerced to pointers to their first element, unless | 
 | 	 they are vectors, in which case we want to leave them alone, | 
 | 	 because they are passed by value.  */ | 
 |       if (current_language->c_style_arrays_p ()) | 
 | 	if (!type->is_vector ()) | 
 | 	  type = lookup_pointer_type (type->target_type ()); | 
 |       break; | 
 |     case TYPE_CODE_UNDEF: | 
 |     case TYPE_CODE_PTR: | 
 |     case TYPE_CODE_STRUCT: | 
 |     case TYPE_CODE_UNION: | 
 |     case TYPE_CODE_VOID: | 
 |     case TYPE_CODE_SET: | 
 |     case TYPE_CODE_RANGE: | 
 |     case TYPE_CODE_STRING: | 
 |     case TYPE_CODE_ERROR: | 
 |     case TYPE_CODE_MEMBERPTR: | 
 |     case TYPE_CODE_METHODPTR: | 
 |     case TYPE_CODE_METHOD: | 
 |     case TYPE_CODE_COMPLEX: | 
 |     default: | 
 |       break; | 
 |     } | 
 |  | 
 |   return value_cast (type, arg); | 
 | } | 
 |  | 
 | /* See infcall.h.  */ | 
 |  | 
 | CORE_ADDR | 
 | find_function_addr (struct value *function, | 
 | 		    struct type **retval_type, | 
 | 		    struct type **function_type) | 
 | { | 
 |   struct type *ftype = check_typedef (value_type (function)); | 
 |   struct gdbarch *gdbarch = ftype->arch (); | 
 |   struct type *value_type = NULL; | 
 |   /* Initialize it just to avoid a GCC false warning.  */ | 
 |   CORE_ADDR funaddr = 0; | 
 |  | 
 |   /* If it's a member function, just look at the function | 
 |      part of it.  */ | 
 |  | 
 |   /* Determine address to call.  */ | 
 |   if (ftype->code () == TYPE_CODE_FUNC | 
 |       || ftype->code () == TYPE_CODE_METHOD) | 
 |     funaddr = value_address (function); | 
 |   else if (ftype->code () == TYPE_CODE_PTR) | 
 |     { | 
 |       funaddr = value_as_address (function); | 
 |       ftype = check_typedef (ftype->target_type ()); | 
 |       if (ftype->code () == TYPE_CODE_FUNC | 
 | 	  || ftype->code () == TYPE_CODE_METHOD) | 
 | 	funaddr = gdbarch_convert_from_func_ptr_addr | 
 | 	  (gdbarch, funaddr, current_inferior ()->top_target()); | 
 |     } | 
 |   if (ftype->code () == TYPE_CODE_FUNC | 
 |       || ftype->code () == TYPE_CODE_METHOD) | 
 |     { | 
 |       if (ftype->is_gnu_ifunc ()) | 
 | 	{ | 
 | 	  CORE_ADDR resolver_addr = funaddr; | 
 |  | 
 | 	  /* Resolve the ifunc.  Note this may call the resolver | 
 | 	     function in the inferior.  */ | 
 | 	  funaddr = gnu_ifunc_resolve_addr (gdbarch, resolver_addr); | 
 |  | 
 | 	  /* Skip querying the function symbol if no RETVAL_TYPE or | 
 | 	     FUNCTION_TYPE have been asked for.  */ | 
 | 	  if (retval_type != NULL || function_type != NULL) | 
 | 	    { | 
 | 	      type *target_ftype = find_function_type (funaddr); | 
 | 	      /* If we don't have debug info for the target function, | 
 | 		 see if we can instead extract the target function's | 
 | 		 type from the type that the resolver returns.  */ | 
 | 	      if (target_ftype == NULL) | 
 | 		target_ftype = find_gnu_ifunc_target_type (resolver_addr); | 
 | 	      if (target_ftype != NULL) | 
 | 		{ | 
 | 		  value_type = check_typedef (target_ftype)->target_type (); | 
 | 		  ftype = target_ftype; | 
 | 		} | 
 | 	    } | 
 | 	} | 
 |       else | 
 | 	value_type = ftype->target_type (); | 
 |     } | 
 |   else if (ftype->code () == TYPE_CODE_INT) | 
 |     { | 
 |       /* Handle the case of functions lacking debugging info. | 
 | 	 Their values are characters since their addresses are char.  */ | 
 |       if (ftype->length () == 1) | 
 | 	funaddr = value_as_address (value_addr (function)); | 
 |       else | 
 | 	{ | 
 | 	  /* 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, current_inferior ()->top_target ()); | 
 | 	      if (funaddr != nfunaddr) | 
 | 		found_descriptor = 1; | 
 | 	    } | 
 | 	  if (!found_descriptor) | 
 | 	    /* Handle integer used as address of a function.  */ | 
 | 	    funaddr = (CORE_ADDR) value_as_long (function); | 
 | 	} | 
 |     } | 
 |   else | 
 |     error (_("Invalid data type for function to be called.")); | 
 |  | 
 |   if (retval_type != NULL) | 
 |     *retval_type = value_type; | 
 |   if (function_type != NULL) | 
 |     *function_type = ftype; | 
 |   return funaddr + gdbarch_deprecated_function_start_offset (gdbarch); | 
 | } | 
 |  | 
 | /* For CALL_DUMMY_ON_STACK, push a breakpoint sequence that the called | 
 |    function returns to.  */ | 
 |  | 
 | static CORE_ADDR | 
 | push_dummy_code (struct gdbarch *gdbarch, | 
 | 		 CORE_ADDR sp, CORE_ADDR funaddr, | 
 | 		 gdb::array_view<value *> args, | 
 | 		 struct type *value_type, | 
 | 		 CORE_ADDR *real_pc, CORE_ADDR *bp_addr, | 
 | 		 struct regcache *regcache) | 
 | { | 
 |   gdb_assert (gdbarch_push_dummy_code_p (gdbarch)); | 
 |  | 
 |   return gdbarch_push_dummy_code (gdbarch, sp, funaddr, | 
 | 				  args.data (), args.size (), | 
 | 				  value_type, real_pc, bp_addr, | 
 | 				  regcache); | 
 | } | 
 |  | 
 | /* See infcall.h.  */ | 
 |  | 
 | void | 
 | error_call_unknown_return_type (const char *func_name) | 
 | { | 
 |   if (func_name != NULL) | 
 |     error (_("'%s' has unknown return type; " | 
 | 	     "cast the call to its declared return type"), | 
 | 	   func_name); | 
 |   else | 
 |     error (_("function has unknown return type; " | 
 | 	     "cast the call to its declared return type")); | 
 | } | 
 |  | 
 | /* Fetch the name of the function at FUNADDR. | 
 |    This is used in printing an error message for call_function_by_hand. | 
 |    BUF is used to print FUNADDR in hex if the function name cannot be | 
 |    determined.  It must be large enough to hold formatted result of | 
 |    RAW_FUNCTION_ADDRESS_FORMAT.  */ | 
 |  | 
 | static const char * | 
 | get_function_name (CORE_ADDR funaddr, char *buf, int buf_size) | 
 | { | 
 |   { | 
 |     struct symbol *symbol = find_pc_function (funaddr); | 
 |  | 
 |     if (symbol) | 
 |       return symbol->print_name (); | 
 |   } | 
 |  | 
 |   { | 
 |     /* Try the minimal symbols.  */ | 
 |     struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr); | 
 |  | 
 |     if (msymbol.minsym) | 
 |       return msymbol.minsym->print_name (); | 
 |   } | 
 |  | 
 |   { | 
 |     std::string tmp = string_printf (_(RAW_FUNCTION_ADDRESS_FORMAT), | 
 | 				     hex_string (funaddr)); | 
 |  | 
 |     gdb_assert (tmp.length () + 1 <= buf_size); | 
 |     return strcpy (buf, tmp.c_str ()); | 
 |   } | 
 | } | 
 |  | 
 | /* All the meta data necessary to extract the call's return value.  */ | 
 |  | 
 | struct call_return_meta_info | 
 | { | 
 |   /* The caller frame's architecture.  */ | 
 |   struct gdbarch *gdbarch; | 
 |  | 
 |   /* The called function.  */ | 
 |   struct value *function; | 
 |  | 
 |   /* The return value's type.  */ | 
 |   struct type *value_type; | 
 |  | 
 |   /* Are we returning a value using a structure return or a normal | 
 |      value return?  */ | 
 |   int struct_return_p; | 
 |  | 
 |   /* If using a structure return, this is the structure's address.  */ | 
 |   CORE_ADDR struct_addr; | 
 | }; | 
 |  | 
 | /* Extract the called function's return value.  */ | 
 |  | 
 | static struct value * | 
 | get_call_return_value (struct call_return_meta_info *ri) | 
 | { | 
 |   struct value *retval = NULL; | 
 |   thread_info *thr = inferior_thread (); | 
 |   bool stack_temporaries = thread_stack_temporaries_enabled_p (thr); | 
 |  | 
 |   if (ri->value_type->code () == TYPE_CODE_VOID) | 
 |     retval = allocate_value (ri->value_type); | 
 |   else if (ri->struct_return_p) | 
 |     { | 
 |       if (stack_temporaries) | 
 | 	{ | 
 | 	  retval = value_from_contents_and_address (ri->value_type, NULL, | 
 | 						    ri->struct_addr); | 
 | 	  push_thread_stack_temporary (thr, retval); | 
 | 	} | 
 |       else | 
 | 	retval = value_at_non_lval (ri->value_type, ri->struct_addr); | 
 |     } | 
 |   else | 
 |     { | 
 |       gdbarch_return_value_as_value (ri->gdbarch, ri->function, ri->value_type, | 
 | 				     get_current_regcache (), | 
 | 				     &retval, NULL); | 
 |       if (stack_temporaries && class_or_union_p (ri->value_type)) | 
 | 	{ | 
 | 	  /* Values of class type returned in registers are copied onto | 
 | 	     the stack and their lval_type set to lval_memory.  This is | 
 | 	     required because further evaluation of the expression | 
 | 	     could potentially invoke methods on the return value | 
 | 	     requiring GDB to evaluate the "this" pointer.  To evaluate | 
 | 	     the this pointer, GDB needs the memory address of the | 
 | 	     value.  */ | 
 | 	  value_force_lval (retval, ri->struct_addr); | 
 | 	  push_thread_stack_temporary (thr, retval); | 
 | 	} | 
 |     } | 
 |  | 
 |   gdb_assert (retval != NULL); | 
 |   return retval; | 
 | } | 
 |  | 
 | /* Data for the FSM that manages an infcall.  It's main job is to | 
 |    record the called function's return value.  */ | 
 |  | 
 | struct call_thread_fsm : public thread_fsm | 
 | { | 
 |   /* All the info necessary to be able to extract the return | 
 |      value.  */ | 
 |   struct call_return_meta_info return_meta_info; | 
 |  | 
 |   /* The called function's return value.  This is extracted from the | 
 |      target before the dummy frame is popped.  */ | 
 |   struct value *return_value = nullptr; | 
 |  | 
 |   /* The top level that started the infcall (and is synchronously | 
 |      waiting for it to end).  */ | 
 |   struct ui *waiting_ui; | 
 |  | 
 |   call_thread_fsm (struct ui *waiting_ui, struct interp *cmd_interp, | 
 | 		   struct gdbarch *gdbarch, struct value *function, | 
 | 		   struct type *value_type, | 
 | 		   int struct_return_p, CORE_ADDR struct_addr); | 
 |  | 
 |   bool should_stop (struct thread_info *thread) override; | 
 |  | 
 |   bool should_notify_stop () override; | 
 | }; | 
 |  | 
 | /* Allocate a new call_thread_fsm object.  */ | 
 |  | 
 | call_thread_fsm::call_thread_fsm (struct ui *waiting_ui, | 
 | 				  struct interp *cmd_interp, | 
 | 				  struct gdbarch *gdbarch, | 
 | 				  struct value *function, | 
 | 				  struct type *value_type, | 
 | 				  int struct_return_p, CORE_ADDR struct_addr) | 
 |   : thread_fsm (cmd_interp), | 
 |     waiting_ui (waiting_ui) | 
 | { | 
 |   return_meta_info.gdbarch = gdbarch; | 
 |   return_meta_info.function = function; | 
 |   return_meta_info.value_type = value_type; | 
 |   return_meta_info.struct_return_p = struct_return_p; | 
 |   return_meta_info.struct_addr = struct_addr; | 
 | } | 
 |  | 
 | /* Implementation of should_stop method for infcalls.  */ | 
 |  | 
 | bool | 
 | call_thread_fsm::should_stop (struct thread_info *thread) | 
 | { | 
 |   INFCALL_SCOPED_DEBUG_ENTER_EXIT; | 
 |  | 
 |   if (stop_stack_dummy == STOP_STACK_DUMMY) | 
 |     { | 
 |       /* Done.  */ | 
 |       set_finished (); | 
 |  | 
 |       /* Stash the return value before the dummy frame is popped and | 
 | 	 registers are restored to what they were before the | 
 | 	 call..  */ | 
 |       return_value = get_call_return_value (&return_meta_info); | 
 |  | 
 |       /* Break out of wait_sync_command_done.  */ | 
 |       scoped_restore save_ui = make_scoped_restore (¤t_ui, waiting_ui); | 
 |       target_terminal::ours (); | 
 |       waiting_ui->prompt_state = PROMPT_NEEDED; | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Implementation of should_notify_stop method for infcalls.  */ | 
 |  | 
 | bool | 
 | call_thread_fsm::should_notify_stop () | 
 | { | 
 |   if (finished_p ()) | 
 |     { | 
 |       /* Infcall succeeded.  Be silent and proceed with evaluating the | 
 | 	 expression.  */ | 
 |       return false; | 
 |     } | 
 |  | 
 |   /* Something wrong happened.  E.g., an unexpected breakpoint | 
 |      triggered, or a signal was intercepted.  Notify the stop.  */ | 
 |   return true; | 
 | } | 
 |  | 
 | /* Subroutine of call_function_by_hand to simplify it. | 
 |    Start up the inferior and wait for it to stop. | 
 |    Return the exception if there's an error, or an exception with | 
 |    reason >= 0 if there's no error. | 
 |  | 
 |    This is done inside a TRY_CATCH so the caller needn't worry about | 
 |    thrown errors.  The caller should rethrow if there's an error.  */ | 
 |  | 
 | static struct gdb_exception | 
 | run_inferior_call (std::unique_ptr<call_thread_fsm> sm, | 
 | 		   struct thread_info *call_thread, CORE_ADDR real_pc) | 
 | { | 
 |   INFCALL_SCOPED_DEBUG_ENTER_EXIT; | 
 |  | 
 |   struct gdb_exception caught_error; | 
 |   ptid_t call_thread_ptid = call_thread->ptid; | 
 |   int was_running = call_thread->state == THREAD_RUNNING; | 
 |  | 
 |   infcall_debug_printf ("call function at %s in thread %s, was_running = %d", | 
 | 			core_addr_to_string (real_pc), | 
 | 			call_thread_ptid.to_string ().c_str (), | 
 | 			was_running); | 
 |  | 
 |   current_ui->unregister_file_handler (); | 
 |  | 
 |   scoped_restore restore_in_infcall | 
 |     = make_scoped_restore (&call_thread->control.in_infcall, 1); | 
 |  | 
 |   clear_proceed_status (0); | 
 |  | 
 |   /* Associate the FSM with the thread after clear_proceed_status | 
 |      (otherwise it'd clear this FSM).  */ | 
 |   call_thread->set_thread_fsm (std::move (sm)); | 
 |  | 
 |   disable_watchpoints_before_interactive_call_start (); | 
 |  | 
 |   /* We want to print return value, please...  */ | 
 |   call_thread->control.proceed_to_finish = 1; | 
 |  | 
 |   try | 
 |     { | 
 |       /* Infcalls run synchronously, in the foreground.  */ | 
 |       scoped_restore restore_prompt_state | 
 | 	= make_scoped_restore (¤t_ui->prompt_state, PROMPT_BLOCKED); | 
 |  | 
 |       /* So that we don't print the prompt prematurely in | 
 | 	 fetch_inferior_event.  */ | 
 |       scoped_restore restore_ui_async | 
 | 	= make_scoped_restore (¤t_ui->async, 0); | 
 |  | 
 |       proceed (real_pc, GDB_SIGNAL_0); | 
 |  | 
 |       infrun_debug_show_threads ("non-exited threads after proceed for inferior-call", | 
 | 				 all_non_exited_threads ()); | 
 |  | 
 |       /* Inferior function calls are always synchronous, even if the | 
 | 	 target supports asynchronous execution.  */ | 
 |       wait_sync_command_done (); | 
 |  | 
 |       infcall_debug_printf ("inferior call completed successfully"); | 
 |     } | 
 |   catch (gdb_exception &e) | 
 |     { | 
 |       infcall_debug_printf ("exception while making inferior call (%d): %s", | 
 | 			    e.reason, e.what ()); | 
 |       caught_error = std::move (e); | 
 |     } | 
 |  | 
 |   infcall_debug_printf ("thread is now: %s", | 
 | 			inferior_ptid.to_string ().c_str ()); | 
 |  | 
 |   /* If GDB has the prompt blocked before, then ensure that it remains | 
 |      so.  normal_stop calls async_enable_stdin, so reset the prompt | 
 |      state again here.  In other cases, stdin will be re-enabled by | 
 |      inferior_event_handler, when an exception is thrown.  */ | 
 |   if (current_ui->prompt_state == PROMPT_BLOCKED) | 
 |     current_ui->unregister_file_handler (); | 
 |   else | 
 |     current_ui->register_file_handler (); | 
 |  | 
 |   /* If the infcall does NOT succeed, normal_stop will have already | 
 |      finished the thread states.  However, on success, normal_stop | 
 |      defers here, so that we can set back the thread states to what | 
 |      they were before the call.  Note that we must also finish the | 
 |      state of new threads that might have spawned while the call was | 
 |      running.  The main cases to handle are: | 
 |  | 
 |      - "(gdb) print foo ()", or any other command that evaluates an | 
 |      expression at the prompt.  (The thread was marked stopped before.) | 
 |  | 
 |      - "(gdb) break foo if return_false()" or similar cases where we | 
 |      do an infcall while handling an event (while the thread is still | 
 |      marked running).  In this example, whether the condition | 
 |      evaluates true and thus we'll present a user-visible stop is | 
 |      decided elsewhere.  */ | 
 |   if (!was_running | 
 |       && call_thread_ptid == inferior_ptid | 
 |       && stop_stack_dummy == STOP_STACK_DUMMY) | 
 |     finish_thread_state (call_thread->inf->process_target (), | 
 | 			 user_visible_resume_ptid (0)); | 
 |  | 
 |   enable_watchpoints_after_interactive_call_stop (); | 
 |  | 
 |   /* Call breakpoint_auto_delete on the current contents of the bpstat | 
 |      of inferior call thread. | 
 |      If all error()s out of proceed ended up calling normal_stop | 
 |      (and perhaps they should; it already does in the special case | 
 |      of error out of resume()), then we wouldn't need this.  */ | 
 |   if (caught_error.reason < 0) | 
 |     { | 
 |       if (call_thread->state != THREAD_EXITED) | 
 | 	breakpoint_auto_delete (call_thread->control.stop_bpstat); | 
 |     } | 
 |  | 
 |   return caught_error; | 
 | } | 
 |  | 
 | /* Reserve space on the stack for a value of the given type. | 
 |    Return the address of the allocated space. | 
 |    Make certain that the value is correctly aligned. | 
 |    The SP argument is modified.  */ | 
 |  | 
 | static CORE_ADDR | 
 | reserve_stack_space (const type *values_type, CORE_ADDR &sp) | 
 | { | 
 |   frame_info_ptr frame = get_current_frame (); | 
 |   struct gdbarch *gdbarch = get_frame_arch (frame); | 
 |   CORE_ADDR addr = 0; | 
 |  | 
 |   if (gdbarch_inner_than (gdbarch, 1, 2)) | 
 |     { | 
 |       /* Stack grows downward.  Align STRUCT_ADDR and SP after | 
 | 	 making space.  */ | 
 |       sp -= values_type->length (); | 
 |       if (gdbarch_frame_align_p (gdbarch)) | 
 | 	sp = gdbarch_frame_align (gdbarch, sp); | 
 |       addr = sp; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Stack grows upward.  Align the frame, allocate space, and | 
 | 	 then again, re-align the frame???  */ | 
 |       if (gdbarch_frame_align_p (gdbarch)) | 
 | 	sp = gdbarch_frame_align (gdbarch, sp); | 
 |       addr = sp; | 
 |       sp += values_type->length (); | 
 |       if (gdbarch_frame_align_p (gdbarch)) | 
 | 	sp = gdbarch_frame_align (gdbarch, sp); | 
 |     } | 
 |  | 
 |   return addr; | 
 | } | 
 |  | 
 | /* The data structure which keeps a destructor function and | 
 |    its implicit 'this' parameter.  */ | 
 |  | 
 | struct destructor_info | 
 | { | 
 |   destructor_info (struct value *function, struct value *self) | 
 |     : function (function), self (self) { } | 
 |  | 
 |   struct value *function; | 
 |   struct value *self; | 
 | }; | 
 |  | 
 |  | 
 | /* Auxiliary function that takes a list of destructor functions | 
 |    with their 'this' parameters, and invokes the functions.  */ | 
 |  | 
 | static void | 
 | call_destructors (const std::list<destructor_info> &dtors_to_invoke, | 
 | 		  struct type *default_return_type) | 
 | { | 
 |   for (auto vals : dtors_to_invoke) | 
 |     { | 
 |       call_function_by_hand (vals.function, default_return_type, | 
 | 			     gdb::make_array_view (&(vals.self), 1)); | 
 |     } | 
 | } | 
 |  | 
 | /* See infcall.h.  */ | 
 |  | 
 | struct value * | 
 | call_function_by_hand (struct value *function, | 
 | 		       type *default_return_type, | 
 | 		       gdb::array_view<value *> args) | 
 | { | 
 |   return call_function_by_hand_dummy (function, default_return_type, | 
 | 				      args, NULL, NULL); | 
 | } | 
 |  | 
 | /* 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 | 
 |    function and then hit a breakpoint (get a signal, etc), "backtrace" | 
 |    will look right.  Whether the backtrace needs to actually show the | 
 |    stack at the time the inferior function was called is debatable, but | 
 |    it certainly needs to not display garbage.  So if you are contemplating | 
 |    making dummy frames be different from normal frames, consider that.  */ | 
 |  | 
 | /* Perform a function call in the inferior. | 
 |    ARGS is a vector of values of arguments. | 
 |    FUNCTION is a value, the function to be called. | 
 |    Returns a value representing what the function returned. | 
 |    May fail to return, if a breakpoint or signal is hit | 
 |    during the execution of the function. | 
 |  | 
 |    ARGS is modified to contain coerced values.  */ | 
 |  | 
 | struct value * | 
 | call_function_by_hand_dummy (struct value *function, | 
 | 			     type *default_return_type, | 
 | 			     gdb::array_view<value *> args, | 
 | 			     dummy_frame_dtor_ftype *dummy_dtor, | 
 | 			     void *dummy_dtor_data) | 
 | { | 
 |   INFCALL_SCOPED_DEBUG_ENTER_EXIT; | 
 |  | 
 |   CORE_ADDR sp; | 
 |   struct type *target_values_type; | 
 |   function_call_return_method return_method = return_method_normal; | 
 |   CORE_ADDR struct_addr = 0; | 
 |   CORE_ADDR real_pc; | 
 |   CORE_ADDR bp_addr; | 
 |   struct frame_id dummy_id; | 
 |   frame_info_ptr frame; | 
 |   struct gdbarch *gdbarch; | 
 |   ptid_t call_thread_ptid; | 
 |   struct gdb_exception e; | 
 |   char name_buf[RAW_FUNCTION_ADDRESS_SIZE]; | 
 |  | 
 |   if (!may_call_functions_p) | 
 |     error (_("Cannot call functions in the program: " | 
 | 	     "may-call-functions is off.")); | 
 |  | 
 |   if (!target_has_execution ()) | 
 |     noprocess (); | 
 |  | 
 |   if (get_traceframe_number () >= 0) | 
 |     error (_("May not call functions while looking at trace frames.")); | 
 |  | 
 |   if (execution_direction == EXEC_REVERSE) | 
 |     error (_("Cannot call functions in reverse mode.")); | 
 |  | 
 |   /* We're going to run the target, and inspect the thread's state | 
 |      afterwards.  Hold a strong reference so that the pointer remains | 
 |      valid even if the thread exits.  */ | 
 |   thread_info_ref call_thread | 
 |     = thread_info_ref::new_reference (inferior_thread ()); | 
 |  | 
 |   bool stack_temporaries = thread_stack_temporaries_enabled_p (call_thread.get ()); | 
 |  | 
 |   frame = get_current_frame (); | 
 |   frame.prepare_reinflate (); | 
 |   gdbarch = get_frame_arch (frame); | 
 |  | 
 |   if (!gdbarch_push_dummy_call_p (gdbarch)) | 
 |     error (_("This target does not support function calls.")); | 
 |  | 
 |   /* Find the function type and do a sanity check.  */ | 
 |   type *ftype; | 
 |   type *values_type; | 
 |   CORE_ADDR funaddr = find_function_addr (function, &values_type, &ftype); | 
 |  | 
 |   if (is_nocall_function (ftype)) | 
 |     error (_("Cannot call the function '%s' which does not follow the " | 
 | 	     "target calling convention."), | 
 | 	   get_function_name (funaddr, name_buf, sizeof (name_buf))); | 
 |  | 
 |   frame.reinflate (); | 
 |  | 
 |   if (values_type == NULL || values_type->is_stub ()) | 
 |     values_type = default_return_type; | 
 |   if (values_type == NULL) | 
 |     { | 
 |       const char *name = get_function_name (funaddr, | 
 | 					    name_buf, sizeof (name_buf)); | 
 |       error (_("'%s' has unknown return type; " | 
 | 	       "cast the call to its declared return type"), | 
 | 	     name); | 
 |     } | 
 |  | 
 |   values_type = check_typedef (values_type); | 
 |  | 
 |   if (args.size () < ftype->num_fields ()) | 
 |     error (_("Too few arguments in function call.")); | 
 |  | 
 |   infcall_debug_printf ("calling %s", get_function_name (funaddr, name_buf, | 
 | 							 sizeof (name_buf))); | 
 |  | 
 |   /* A holder for the inferior status. | 
 |      This is only needed while we're preparing the inferior function call.  */ | 
 |   infcall_control_state_up inf_status (save_infcall_control_state ()); | 
 |  | 
 |   /* 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.  This unique pointer | 
 |      is released once the regcache has been pushed).  */ | 
 |   infcall_suspend_state_up caller_state (save_infcall_suspend_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); | 
 | 	/* NOTE: cagney/2003-08-13: Skip the "red zone".  For some | 
 | 	   ABIs, a function can use memory beyond the inner most stack | 
 | 	   address.  AMD64 called that region the "red zone".  Skip at | 
 | 	   least the "red zone" size before allocating any space on | 
 | 	   the stack.  */ | 
 | 	if (gdbarch_inner_than (gdbarch, 1, 2)) | 
 | 	  sp -= gdbarch_frame_red_zone_size (gdbarch); | 
 | 	else | 
 | 	  sp += gdbarch_frame_red_zone_size (gdbarch); | 
 | 	/* Still aligned?  */ | 
 | 	gdb_assert (sp == gdbarch_frame_align (gdbarch, sp)); | 
 | 	/* NOTE: cagney/2002-09-18: | 
 | 	    | 
 | 	   On a RISC architecture, a void parameterless generic dummy | 
 | 	   frame (i.e., no parameters, no result) typically does not | 
 | 	   need to push anything the stack and hence can leave SP and | 
 | 	   FP.  Similarly, a frameless (possibly leaf) function does | 
 | 	   not push anything on the stack and, hence, that too can | 
 | 	   leave FP and SP unchanged.  As a consequence, a sequence of | 
 | 	   void parameterless generic dummy frame calls to frameless | 
 | 	   functions will create a sequence of effectively identical | 
 | 	   frames (SP, FP and TOS and PC the same).  This, not | 
 | 	   surprisingly, results in what appears to be a stack in an | 
 | 	   infinite loop --- when GDB tries to find a generic dummy | 
 | 	   frame on the internal dummy frame stack, it will always | 
 | 	   find the first one. | 
 |  | 
 | 	   To avoid this problem, the code below always grows the | 
 | 	   stack.  That way, two dummy frames can never be identical. | 
 | 	   It does burn a few bytes of stack but that is a small price | 
 | 	   to pay :-).  */ | 
 | 	if (sp == old_sp) | 
 | 	  { | 
 | 	    if (gdbarch_inner_than (gdbarch, 1, 2)) | 
 | 	      /* Stack grows down.  */ | 
 | 	      sp = gdbarch_frame_align (gdbarch, old_sp - 1); | 
 | 	    else | 
 | 	      /* Stack grows up.  */ | 
 | 	      sp = gdbarch_frame_align (gdbarch, old_sp + 1); | 
 | 	  } | 
 | 	/* SP may have underflown address zero here from OLD_SP.  Memory access | 
 | 	   functions will probably fail in such case but that is a target's | 
 | 	   problem.  */ | 
 |       } | 
 |     else | 
 |       /* FIXME: cagney/2002-09-18: Hey, you loose! | 
 |  | 
 | 	 Who knows how badly aligned the SP is! | 
 |  | 
 | 	 If the generic dummy frame ends up empty (because nothing is | 
 | 	 pushed) GDB won't be able to correctly perform back traces. | 
 | 	 If a target is having trouble with backtraces, first thing to | 
 | 	 do is add FRAME_ALIGN() to the architecture vector.  If that | 
 | 	 fails, try dummy_id(). | 
 |  | 
 | 	 If the ABI specifies a "Red Zone" (see the doco) the code | 
 | 	 below will quietly trash it.  */ | 
 |       sp = old_sp; | 
 |  | 
 |     /* Skip over the stack temporaries that might have been generated during | 
 |        the evaluation of an expression.  */ | 
 |     if (stack_temporaries) | 
 |       { | 
 | 	struct value *lastval; | 
 |  | 
 | 	lastval = get_last_thread_stack_temporary (call_thread.get ()); | 
 | 	if (lastval != NULL) | 
 | 	  { | 
 | 	    CORE_ADDR lastval_addr = value_address (lastval); | 
 |  | 
 | 	    if (gdbarch_inner_than (gdbarch, 1, 2)) | 
 | 	      { | 
 | 		gdb_assert (sp >= lastval_addr); | 
 | 		sp = lastval_addr; | 
 | 	      } | 
 | 	    else | 
 | 	      { | 
 | 		gdb_assert (sp <= lastval_addr); | 
 | 		sp = lastval_addr + value_type (lastval)->length (); | 
 | 	      } | 
 |  | 
 | 	    if (gdbarch_frame_align_p (gdbarch)) | 
 | 	      sp = gdbarch_frame_align (gdbarch, sp); | 
 | 	  } | 
 |       } | 
 |   } | 
 |  | 
 |   /* Are we returning a value using a structure return?  */ | 
 |  | 
 |   if (gdbarch_return_in_first_hidden_param_p (gdbarch, values_type)) | 
 |     { | 
 |       return_method = return_method_hidden_param; | 
 |  | 
 |       /* Tell the target specific argument pushing routine not to | 
 | 	 expect a value.  */ | 
 |       target_values_type = builtin_type (gdbarch)->builtin_void; | 
 |     } | 
 |   else | 
 |     { | 
 |       if (using_struct_return (gdbarch, function, values_type)) | 
 | 	return_method = return_method_struct; | 
 |       target_values_type = values_type; | 
 |     } | 
 |  | 
 |   gdb::observers::inferior_call_pre.notify (inferior_ptid, funaddr); | 
 |  | 
 |   /* Determine the location of the breakpoint (and possibly other | 
 |      stuff) that the called function will return to.  The SPARC, for a | 
 |      function returning a structure or union, needs to make space for | 
 |      not just the breakpoint but also an extra word containing the | 
 |      size (?) of the structure being passed.  */ | 
 |  | 
 |   switch (gdbarch_call_dummy_location (gdbarch)) | 
 |     { | 
 |     case ON_STACK: | 
 |       { | 
 | 	const gdb_byte *bp_bytes; | 
 | 	CORE_ADDR bp_addr_as_address; | 
 | 	int bp_size; | 
 |  | 
 | 	/* Be careful BP_ADDR is in inferior PC encoding while | 
 | 	   BP_ADDR_AS_ADDRESS is a plain memory address.  */ | 
 |  | 
 | 	sp = push_dummy_code (gdbarch, sp, funaddr, args, | 
 | 			      target_values_type, &real_pc, &bp_addr, | 
 | 			      get_current_regcache ()); | 
 |  | 
 | 	/* Write a legitimate instruction at the point where the infcall | 
 | 	   breakpoint is going to be inserted.  While this instruction | 
 | 	   is never going to be executed, a user investigating the | 
 | 	   memory from GDB would see this instruction instead of random | 
 | 	   uninitialized bytes.  We chose the breakpoint instruction | 
 | 	   as it may look as the most logical one to the user and also | 
 | 	   valgrind 3.7.0 needs it for proper vgdb inferior calls. | 
 |  | 
 | 	   If software breakpoints are unsupported for this target we | 
 | 	   leave the user visible memory content uninitialized.  */ | 
 |  | 
 | 	bp_addr_as_address = bp_addr; | 
 | 	bp_bytes = gdbarch_breakpoint_from_pc (gdbarch, &bp_addr_as_address, | 
 | 					       &bp_size); | 
 | 	if (bp_bytes != NULL) | 
 | 	  write_memory (bp_addr_as_address, bp_bytes, bp_size); | 
 |       } | 
 |       break; | 
 |     case AT_ENTRY_POINT: | 
 |       { | 
 | 	CORE_ADDR dummy_addr; | 
 |  | 
 | 	real_pc = funaddr; | 
 | 	dummy_addr = entry_point_address (); | 
 |  | 
 | 	/* A call dummy always consists of just a single breakpoint, so | 
 | 	   its address is the same as the address of the dummy. | 
 |  | 
 | 	   The actual breakpoint is inserted separatly so there is no need to | 
 | 	   write that out.  */ | 
 | 	bp_addr = dummy_addr; | 
 | 	break; | 
 |       } | 
 |     default: | 
 |       internal_error (_("bad switch")); | 
 |     } | 
 |  | 
 |   /* Coerce the arguments and handle pass-by-reference. | 
 |      We want to remember the destruction required for pass-by-ref values. | 
 |      For these, store the dtor function and the 'this' argument | 
 |      in DTORS_TO_INVOKE.  */ | 
 |   std::list<destructor_info> dtors_to_invoke; | 
 |  | 
 |   for (int i = args.size () - 1; i >= 0; i--) | 
 |     { | 
 |       int prototyped; | 
 |       struct type *param_type; | 
 |  | 
 |       /* FIXME drow/2002-05-31: Should just always mark methods as | 
 | 	 prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */ | 
 |       if (ftype->code () == TYPE_CODE_METHOD) | 
 | 	prototyped = 1; | 
 |       else if (ftype->target_type () == NULL && ftype->num_fields () == 0 | 
 | 	       && default_return_type != NULL) | 
 | 	{ | 
 | 	  /* Calling a no-debug function with the return type | 
 | 	     explicitly cast.  Assume the function is prototyped, | 
 | 	     with a prototype matching the types of the arguments. | 
 | 	     E.g., with: | 
 | 	     float mult (float v1, float v2) { return v1 * v2; } | 
 | 	     This: | 
 | 	     (gdb) p (float) mult (2.0f, 3.0f) | 
 | 	     Is a simpler alternative to: | 
 | 	     (gdb) p ((float (*) (float, float)) mult) (2.0f, 3.0f) | 
 | 	  */ | 
 | 	  prototyped = 1; | 
 | 	} | 
 |       else if (i < ftype->num_fields ()) | 
 | 	prototyped = ftype->is_prototyped (); | 
 |       else | 
 | 	prototyped = 0; | 
 |  | 
 |       if (i < ftype->num_fields ()) | 
 | 	param_type = ftype->field (i).type (); | 
 |       else | 
 | 	param_type = NULL; | 
 |  | 
 |       value *original_arg = args[i]; | 
 |       args[i] = value_arg_coerce (gdbarch, args[i], | 
 | 				  param_type, prototyped); | 
 |  | 
 |       if (param_type == NULL) | 
 | 	continue; | 
 |  | 
 |       auto info = language_pass_by_reference (param_type); | 
 |       if (!info.copy_constructible) | 
 | 	error (_("expression cannot be evaluated because the type '%s' " | 
 | 		 "is not copy constructible"), param_type->name ()); | 
 |  | 
 |       if (!info.destructible) | 
 | 	error (_("expression cannot be evaluated because the type '%s' " | 
 | 		 "is not destructible"), param_type->name ()); | 
 |  | 
 |       if (info.trivially_copyable) | 
 | 	continue; | 
 |  | 
 |       /* Make a copy of the argument on the stack.  If the argument is | 
 | 	 trivially copy ctor'able, copy bit by bit.  Otherwise, call | 
 | 	 the copy ctor to initialize the clone.  */ | 
 |       CORE_ADDR addr = reserve_stack_space (param_type, sp); | 
 |       value *clone | 
 | 	= value_from_contents_and_address (param_type, nullptr, addr); | 
 |       push_thread_stack_temporary (call_thread.get (), clone); | 
 |       value *clone_ptr | 
 | 	= value_from_pointer (lookup_pointer_type (param_type), addr); | 
 |  | 
 |       if (info.trivially_copy_constructible) | 
 | 	{ | 
 | 	  int length = param_type->length (); | 
 | 	  write_memory (addr, value_contents (args[i]).data (), length); | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  value *copy_ctor; | 
 | 	  value *cctor_args[2] = { clone_ptr, original_arg }; | 
 | 	  find_overload_match (gdb::make_array_view (cctor_args, 2), | 
 | 			       param_type->name (), METHOD, | 
 | 			       &clone_ptr, nullptr, ©_ctor, nullptr, | 
 | 			       nullptr, 0, EVAL_NORMAL); | 
 |  | 
 | 	  if (copy_ctor == nullptr) | 
 | 	    error (_("expression cannot be evaluated because a copy " | 
 | 		     "constructor for the type '%s' could not be found " | 
 | 		     "(maybe inlined?)"), param_type->name ()); | 
 |  | 
 | 	  call_function_by_hand (copy_ctor, default_return_type, | 
 | 				 gdb::make_array_view (cctor_args, 2)); | 
 | 	} | 
 |  | 
 |       /* If the argument has a destructor, remember it so that we | 
 | 	 invoke it after the infcall is complete.  */ | 
 |       if (!info.trivially_destructible) | 
 | 	{ | 
 | 	  /* Looking up the function via overload resolution does not | 
 | 	     work because the compiler (in particular, gcc) adds an | 
 | 	     artificial int parameter in some cases.  So we look up | 
 | 	     the function by using the "~" name.  This should be OK | 
 | 	     because there can be only one dtor definition.  */ | 
 | 	  const char *dtor_name = nullptr; | 
 | 	  for (int fieldnum = 0; | 
 | 	       fieldnum < TYPE_NFN_FIELDS (param_type); | 
 | 	       fieldnum++) | 
 | 	    { | 
 | 	      fn_field *fn | 
 | 		= TYPE_FN_FIELDLIST1 (param_type, fieldnum); | 
 | 	      const char *field_name | 
 | 		= TYPE_FN_FIELDLIST_NAME (param_type, fieldnum); | 
 |  | 
 | 	      if (field_name[0] == '~') | 
 | 		dtor_name = TYPE_FN_FIELD_PHYSNAME (fn, 0); | 
 | 	    } | 
 |  | 
 | 	  if (dtor_name == nullptr) | 
 | 	    error (_("expression cannot be evaluated because a destructor " | 
 | 		     "for the type '%s' could not be found " | 
 | 		     "(maybe inlined?)"), param_type->name ()); | 
 |  | 
 | 	  value *dtor | 
 | 	    = find_function_in_inferior (dtor_name, 0); | 
 |  | 
 | 	  /* Insert the dtor to the front of the list to call them | 
 | 	     in reverse order later.  */ | 
 | 	  dtors_to_invoke.emplace_front (dtor, clone_ptr); | 
 | 	} | 
 |  | 
 |       args[i] = clone_ptr; | 
 |     } | 
 |  | 
 |   /* Reserve space for the return structure to be written on the | 
 |      stack, if necessary. | 
 |  | 
 |      While evaluating expressions, we reserve space on the stack for | 
 |      return values of class type even if the language ABI and the target | 
 |      ABI do not require that the return value be passed as a hidden first | 
 |      argument.  This is because we want to store the return value as an | 
 |      on-stack temporary while the expression is being evaluated.  This | 
 |      enables us to have chained function calls in expressions. | 
 |  | 
 |      Keeping the return values as on-stack temporaries while the expression | 
 |      is being evaluated is OK because the thread is stopped until the | 
 |      expression is completely evaluated.  */ | 
 |  | 
 |   if (return_method != return_method_normal | 
 |       || (stack_temporaries && class_or_union_p (values_type))) | 
 |     struct_addr = reserve_stack_space (values_type, sp); | 
 |  | 
 |   std::vector<struct value *> new_args; | 
 |   if (return_method == return_method_hidden_param) | 
 |     { | 
 |       /* Add the new argument to the front of the argument list.  */ | 
 |       new_args.reserve (args.size ()); | 
 |       new_args.push_back | 
 | 	(value_from_pointer (lookup_pointer_type (values_type), struct_addr)); | 
 |       new_args.insert (new_args.end (), args.begin (), args.end ()); | 
 |       args = new_args; | 
 |     } | 
 |  | 
 |   /* Create the dummy stack frame.  Pass in the call dummy address as, | 
 |      presumably, the ABI code knows where, in the call dummy, the | 
 |      return address should be pointed.  */ | 
 |   sp = gdbarch_push_dummy_call (gdbarch, function, get_current_regcache (), | 
 | 				bp_addr, args.size (), args.data (), | 
 | 				sp, return_method, struct_addr); | 
 |  | 
 |   /* Set up a frame ID for the dummy frame so we can pass it to | 
 |      set_momentary_breakpoint.  We need to give the breakpoint a frame | 
 |      ID so that the breakpoint code can correctly re-identify the | 
 |      dummy breakpoint.  */ | 
 |   /* Sanity.  The exact same SP value is returned by PUSH_DUMMY_CALL, | 
 |      saved as the dummy-frame TOS, and used by dummy_id to form | 
 |      the frame ID's stack address.  */ | 
 |   dummy_id = frame_id_build (sp, bp_addr); | 
 |  | 
 |   /* Create a momentary breakpoint at the return address of the | 
 |      inferior.  That way it breaks when it returns.  */ | 
 |  | 
 |   { | 
 |     symtab_and_line sal; | 
 |     sal.pspace = current_program_space; | 
 |     sal.pc = bp_addr; | 
 |     sal.section = find_pc_overlay (sal.pc); | 
 |  | 
 |     /* Sanity.  The exact same SP value is returned by | 
 |        PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by | 
 |        dummy_id to form the frame ID's stack address.  */ | 
 |     breakpoint *bpt | 
 |       = set_momentary_breakpoint (gdbarch, sal, | 
 | 				  dummy_id, bp_call_dummy).release (); | 
 |  | 
 |     /* set_momentary_breakpoint invalidates FRAME.  */ | 
 |     frame = NULL; | 
 |  | 
 |     bpt->disposition = disp_del; | 
 |     gdb_assert (bpt->related_breakpoint == bpt); | 
 |  | 
 |     breakpoint *longjmp_b = set_longjmp_breakpoint_for_call_dummy (); | 
 |     if (longjmp_b) | 
 |       { | 
 | 	/* Link BPT into the chain of LONGJMP_B.  */ | 
 | 	bpt->related_breakpoint = longjmp_b; | 
 | 	while (longjmp_b->related_breakpoint != bpt->related_breakpoint) | 
 | 	  longjmp_b = longjmp_b->related_breakpoint; | 
 | 	longjmp_b->related_breakpoint = bpt; | 
 |       } | 
 |   } | 
 |  | 
 |   /* Create a breakpoint in std::terminate. | 
 |      If a C++ exception is raised in the dummy-frame, and the | 
 |      exception handler is (normally, and expected to be) out-of-frame, | 
 |      the default C++ handler will (wrongly) be called in an inferior | 
 |      function call.  This is wrong, as an exception can be  normally | 
 |      and legally handled out-of-frame.  The confines of the dummy frame | 
 |      prevent the unwinder from finding the correct handler (or any | 
 |      handler, unless it is in-frame).  The default handler calls | 
 |      std::terminate.  This will kill the inferior.  Assert that | 
 |      terminate should never be called in an inferior function | 
 |      call.  Place a momentary breakpoint in the std::terminate function | 
 |      and if triggered in the call, rewind.  */ | 
 |   if (unwind_on_terminating_exception_p) | 
 |     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 | 
 |      stack.  */ | 
 |   dummy_frame_push (caller_state.release (), &dummy_id, call_thread.get ()); | 
 |   if (dummy_dtor != NULL) | 
 |     register_dummy_frame_dtor (dummy_id, call_thread.get (), | 
 | 			       dummy_dtor, dummy_dtor_data); | 
 |  | 
 |   /* Register a clean-up for unwind_on_terminating_exception_breakpoint.  */ | 
 |   SCOPE_EXIT { delete_std_terminate_breakpoint (); }; | 
 |  | 
 |   /* - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - | 
 |      If you're looking to implement asynchronous dummy-frames, then | 
 |      just below is the place to chop this function in two..  */ | 
 |  | 
 |   { | 
 |     /* Save the current FSM.  We'll override it.  */ | 
 |     std::unique_ptr<thread_fsm> saved_sm = call_thread->release_thread_fsm (); | 
 |     struct call_thread_fsm *sm; | 
 |  | 
 |     /* Save this thread's ptid, we need it later but the thread | 
 |        may have exited.  */ | 
 |     call_thread_ptid = call_thread->ptid; | 
 |  | 
 |     /* Run the inferior until it stops.  */ | 
 |  | 
 |     /* Create the FSM used to manage the infcall.  It tells infrun to | 
 |        not report the stop to the user, and captures the return value | 
 |        before the dummy frame is popped.  run_inferior_call registers | 
 |        it with the thread ASAP.  */ | 
 |     sm = new call_thread_fsm (current_ui, command_interp (), | 
 | 			      gdbarch, function, | 
 | 			      values_type, | 
 | 			      return_method != return_method_normal, | 
 | 			      struct_addr); | 
 |     { | 
 |       std::unique_ptr<call_thread_fsm> sm_up (sm); | 
 |       e = run_inferior_call (std::move (sm_up), call_thread.get (), real_pc); | 
 |     } | 
 |  | 
 |     if (e.reason < 0) | 
 |       infcall_debug_printf ("after inferior call, exception (%d): %s", | 
 | 			    e.reason, e.what ()); | 
 |     infcall_debug_printf ("after inferior call, thread state is: %s", | 
 | 			  thread_state_string (call_thread->state)); | 
 |  | 
 |     gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr); | 
 |  | 
 |     if (call_thread->state != THREAD_EXITED) | 
 |       { | 
 | 	/* The FSM should still be the same.  */ | 
 | 	gdb_assert (call_thread->thread_fsm () == sm); | 
 |  | 
 | 	if (call_thread->thread_fsm ()->finished_p ()) | 
 | 	  { | 
 | 	    struct value *retval; | 
 |  | 
 | 	    infcall_debug_printf ("call completed"); | 
 |  | 
 | 	    /* The inferior call is successful.  Pop the dummy frame, | 
 | 	       which runs its destructors and restores the inferior's | 
 | 	       suspend state, and restore the inferior control | 
 | 	       state.  */ | 
 | 	    dummy_frame_pop (dummy_id, call_thread.get ()); | 
 | 	    restore_infcall_control_state (inf_status.release ()); | 
 |  | 
 | 	    /* Get the return value.  */ | 
 | 	    retval = sm->return_value; | 
 |  | 
 | 	    /* Restore the original FSM and clean up / destroh the call FSM. | 
 | 	       Doing it in this order ensures that if the call to clean_up | 
 | 	       throws, the original FSM is properly restored.  */ | 
 | 	    { | 
 | 	      std::unique_ptr<thread_fsm> finalizing | 
 | 		= call_thread->release_thread_fsm (); | 
 | 	      call_thread->set_thread_fsm (std::move (saved_sm)); | 
 |  | 
 | 	      finalizing->clean_up (call_thread.get ()); | 
 | 	    } | 
 |  | 
 | 	    maybe_remove_breakpoints (); | 
 |  | 
 | 	    gdb_assert (retval != NULL); | 
 |  | 
 | 	    /* Destruct the pass-by-ref argument clones.  */ | 
 | 	    call_destructors (dtors_to_invoke, default_return_type); | 
 |  | 
 | 	    return retval; | 
 | 	  } | 
 | 	else | 
 | 	  infcall_debug_printf ("call did not complete"); | 
 |  | 
 | 	/* Didn't complete.  Clean up / destroy the call FSM, and restore the | 
 | 	   previous state machine, and handle the error.  */ | 
 | 	{ | 
 | 	  std::unique_ptr<thread_fsm> finalizing | 
 | 	    = call_thread->release_thread_fsm (); | 
 | 	  call_thread->set_thread_fsm (std::move (saved_sm)); | 
 |  | 
 | 	  finalizing->clean_up (call_thread.get ()); | 
 | 	} | 
 |       } | 
 |   } | 
 |  | 
 |   /* Rethrow an error if we got one trying to run the inferior.  */ | 
 |  | 
 |   if (e.reason < 0) | 
 |     { | 
 |       const char *name = get_function_name (funaddr, | 
 | 					    name_buf, sizeof (name_buf)); | 
 |  | 
 |       discard_infcall_control_state (inf_status.release ()); | 
 |  | 
 |       /* We could discard the dummy frame here if the program exited, | 
 | 	 but it will get garbage collected the next time the program is | 
 | 	 run anyway.  */ | 
 |  | 
 |       switch (e.reason) | 
 | 	{ | 
 | 	case RETURN_ERROR: | 
 | 	  throw_error (e.error, _("%s\n\ | 
 | An error occurred while in a function called from GDB.\n\ | 
 | Evaluation of the expression containing the function\n\ | 
 | (%s) will be abandoned.\n\ | 
 | When the function is done executing, GDB will silently stop."), | 
 | 		       e.what (), name); | 
 | 	case RETURN_QUIT: | 
 | 	default: | 
 | 	  throw_exception (std::move (e)); | 
 | 	} | 
 |     } | 
 |  | 
 |   /* If the program has exited, or we stopped at a different thread, | 
 |      exit and inform the user.  */ | 
 |  | 
 |   if (! target_has_execution ()) | 
 |     { | 
 |       const char *name = get_function_name (funaddr, | 
 | 					    name_buf, sizeof (name_buf)); | 
 |  | 
 |       /* If we try to restore the inferior status, | 
 | 	 we'll crash as the inferior is no longer running.  */ | 
 |       discard_infcall_control_state (inf_status.release ()); | 
 |  | 
 |       /* We could discard the dummy frame here given that the program exited, | 
 | 	 but it will get garbage collected the next time the program is | 
 | 	 run anyway.  */ | 
 |  | 
 |       error (_("The program being debugged exited while in a function " | 
 | 	       "called from GDB.\n" | 
 | 	       "Evaluation of the expression containing the function\n" | 
 | 	       "(%s) will be abandoned."), | 
 | 	     name); | 
 |     } | 
 |  | 
 |   if (call_thread_ptid != inferior_ptid) | 
 |     { | 
 |       const char *name = get_function_name (funaddr, | 
 | 					    name_buf, sizeof (name_buf)); | 
 |  | 
 |       /* We've switched threads.  This can happen if another thread gets a | 
 | 	 signal or breakpoint while our thread was running. | 
 | 	 There's no point in restoring the inferior status, | 
 | 	 we're in a different thread.  */ | 
 |       discard_infcall_control_state (inf_status.release ()); | 
 |       /* 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) | 
 | 	error (_("\ | 
 | The program received a signal in another thread while\n\ | 
 | making a function call from GDB.\n\ | 
 | Evaluation of the expression containing the function\n\ | 
 | (%s) will be abandoned.\n\ | 
 | When the function is done executing, GDB will silently stop."), | 
 | 	       name); | 
 |       else | 
 | 	error (_("\ | 
 | The program stopped in another thread while making a function call from GDB.\n\ | 
 | Evaluation of the expression containing the function\n\ | 
 | (%s) will be abandoned.\n\ | 
 | When the function is done executing, GDB will silently stop."), | 
 | 	       name); | 
 |     } | 
 |  | 
 |     { | 
 |       /* Make a copy as NAME may be in an objfile freed by dummy_frame_pop.  */ | 
 |       std::string name = get_function_name (funaddr, name_buf, | 
 | 					    sizeof (name_buf)); | 
 |  | 
 |       if (stopped_by_random_signal) | 
 | 	{ | 
 | 	  /* We stopped inside the FUNCTION because of a random | 
 | 	     signal.  Further execution of the FUNCTION is not | 
 | 	     allowed.  */ | 
 |  | 
 | 	  if (unwind_on_signal_p) | 
 | 	    { | 
 | 	      /* The user wants the context restored.  */ | 
 |  | 
 | 	      /* We must get back to the frame we were before the | 
 | 		 dummy call.  */ | 
 | 	      dummy_frame_pop (dummy_id, call_thread.get ()); | 
 |  | 
 | 	      /* We also need to restore inferior status to that before the | 
 | 		 dummy call.  */ | 
 | 	      restore_infcall_control_state (inf_status.release ()); | 
 |  | 
 | 	      /* FIXME: Insert a bunch of wrap_here; name can be very | 
 | 		 long if it's a C++ name with arguments and stuff.  */ | 
 | 	      error (_("\ | 
 | The program being debugged was signaled while in a function called from GDB.\n\ | 
 | GDB has restored the context to what it was before the call.\n\ | 
 | To change this behavior use \"set unwindonsignal off\".\n\ | 
 | Evaluation of the expression containing the function\n\ | 
 | (%s) will be abandoned."), | 
 | 		     name.c_str ()); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      /* The user wants to stay in the frame where we stopped | 
 | 		 (default). | 
 | 		 Discard inferior status, we're not at the same point | 
 | 		 we started at.  */ | 
 | 	      discard_infcall_control_state (inf_status.release ()); | 
 |  | 
 | 	      /* FIXME: Insert a bunch of wrap_here; name can be very | 
 | 		 long if it's a C++ name with arguments and stuff.  */ | 
 | 	      error (_("\ | 
 | The program being debugged was signaled while in a function called from GDB.\n\ | 
 | GDB remains in the frame where the signal was received.\n\ | 
 | To change this behavior use \"set unwindonsignal on\".\n\ | 
 | Evaluation of the expression containing the function\n\ | 
 | (%s) will be abandoned.\n\ | 
 | When the function is done executing, GDB will silently stop."), | 
 | 		     name.c_str ()); | 
 | 	    } | 
 | 	} | 
 |  | 
 |       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, call_thread.get ()); | 
 |  | 
 | 	  /* We also need to restore inferior status to that before | 
 | 	     the dummy call.  */ | 
 | 	  restore_infcall_control_state (inf_status.release ()); | 
 |  | 
 | 	  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\ | 
 | context to its original state before the call.\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.c_str ()); | 
 | 	} | 
 |       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_infcall_control_state (inf_status.release ()); | 
 |  | 
 | 	  /* The following error message used to say "The expression | 
 | 	     which contained the function call has been discarded." | 
 | 	     It is a hard concept to explain in a few words.  Ideally, | 
 | 	     GDB would be able to resume evaluation of the expression | 
 | 	     when the function finally is done executing.  Perhaps | 
 | 	     someday this will be implemented (it would not be easy).  */ | 
 | 	  /* FIXME: Insert a bunch of wrap_here; name can be very long if it's | 
 | 	     a C++ name with arguments and stuff.  */ | 
 | 	  error (_("\ | 
 | The program being debugged stopped while in a function called from GDB.\n\ | 
 | Evaluation of the expression containing the function\n\ | 
 | (%s) will be abandoned.\n\ | 
 | When the function is done executing, GDB will silently stop."), | 
 | 		 name.c_str ()); | 
 | 	} | 
 |  | 
 |     } | 
 |  | 
 |   /* The above code errors out, so ...  */ | 
 |   gdb_assert_not_reached ("... should not be here"); | 
 | } | 
 |  | 
 | void _initialize_infcall (); | 
 | void | 
 | _initialize_infcall () | 
 | { | 
 |   add_setshow_boolean_cmd ("may-call-functions", no_class, | 
 | 			   &may_call_functions_p, _("\ | 
 | Set permission to call functions in the program."), _("\ | 
 | Show permission to call functions in the program."), _("\ | 
 | When this permission is on, GDB may call functions in the program.\n\ | 
 | Otherwise, any sort of attempt to call a function in the program\n\ | 
 | will result in an error."), | 
 | 			   NULL, | 
 | 			   show_may_call_functions_p, | 
 | 			   &setlist, &showlist); | 
 |  | 
 |   add_setshow_boolean_cmd ("coerce-float-to-double", class_obscure, | 
 | 			   &coerce_float_to_double_p, _("\ | 
 | Set coercion of floats to doubles when calling functions."), _("\ | 
 | Show coercion of floats to doubles when calling functions."), _("\ | 
 | Variables of type float should generally be converted to doubles before\n\ | 
 | calling an unprototyped function, and left alone when calling a prototyped\n\ | 
 | function.  However, some older debug info formats do not provide enough\n\ | 
 | information to determine that a function is prototyped.  If this flag is\n\ | 
 | set, GDB will perform the conversion for a function it considers\n\ | 
 | unprototyped.\n\ | 
 | The default is to perform the conversion."), | 
 | 			   NULL, | 
 | 			   show_coerce_float_to_double_p, | 
 | 			   &setlist, &showlist); | 
 |  | 
 |   add_setshow_boolean_cmd ("unwindonsignal", no_class, | 
 | 			   &unwind_on_signal_p, _("\ | 
 | Set unwinding of stack if a signal is received while in a call dummy."), _("\ | 
 | Show unwinding of stack if a signal is received while in a call dummy."), _("\ | 
 | The unwindonsignal lets the user determine what gdb should do if a signal\n\ | 
 | is received while in a function called from gdb (call dummy).  If set, gdb\n\ | 
 | unwinds the stack and restore the context to what as it was before the call.\n\ | 
 | The default is to stop in the frame where the signal was received."), | 
 | 			   NULL, | 
 | 			   show_unwind_on_signal_p, | 
 | 			   &setlist, &showlist); | 
 |  | 
 |   add_setshow_boolean_cmd ("unwind-on-terminating-exception", no_class, | 
 | 			   &unwind_on_terminating_exception_p, _("\ | 
 | Set unwinding of stack if std::terminate is called while in call dummy."), _("\ | 
 | Show unwinding of stack if std::terminate() is called while in a call dummy."), | 
 | 			   _("\ | 
 | The unwind on terminating exception flag lets the user determine\n\ | 
 | what gdb should do if a std::terminate() call is made from the\n\ | 
 | default exception handler.  If set, gdb unwinds the stack and restores\n\ | 
 | the context to what it was before the call.  If unset, gdb allows the\n\ | 
 | std::terminate call to proceed.\n\ | 
 | The default is to unwind the frame."), | 
 | 			   NULL, | 
 | 			   show_unwind_on_terminating_exception_p, | 
 | 			   &setlist, &showlist); | 
 |  | 
 |   add_setshow_boolean_cmd | 
 |     ("infcall", class_maintenance, &debug_infcall, | 
 |      _("Set inferior call debugging."), | 
 |      _("Show inferior call debugging."), | 
 |      _("When on, inferior function call specific debugging is enabled."), | 
 |      NULL, show_debug_infcall, &setdebuglist, &showdebuglist); | 
 | } |