[RFA] Change exceptions.h functions to use gdb::function_view

Message ID 20170927165302.30177-1-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey Sept. 27, 2017, 4:53 p.m. UTC
  This changes some functions in exceptions.h to use gdb::function_view,
then fixes up the fallout.  This lead to some surprising places, like
a function pointer in target_so_ops.

While writing this I found that catch_exception_ftype was unused, so I
removed this.

Note that I did not compile the windows-nat.c change, so I don't know
if it works.

Regression tested by the buildbot.

gdb/ChangeLog
2017-09-27  Tom Tromey  <tom@tromey.com>

	* windows-nat.c (get_windows_debug_event): Update.
	(handle_load_dll): Remove argument.
	* solib-target.c (solib_target_open_symbol_file_object): Change
	type.
	* solib-svr4.c (open_symbol_file_object): Change type.
	* solib-frv.c (open_symbol_file_object): Change type.
	* solib-dsbt.c (open_symbol_file_object): Change type.
	* solib-darwin.c (open_symbol_file_object): Change type.
	* solib-aix.c (solib_aix_open_symbol_file_object): Change type.
	* thread.c (do_captured_list_thread_ids): Remove argument.
	(enum gdb_rc): Update.
	(do_captured_thread_select): Change type.
	(enum gdb_rc): Update.
	* symmisc.c (struct print_symbol_args): Remove.
	(print_symbol): Change type.
	(dump_symtab_1): Update.
	* solib.c (update_solib_list): Update.
	* solist.h (struct target_so_ops) <open_symbol_file_object>:
	Change type.
	* record-full.c (struct record_full_message_args): Remove.
	(record_full_message_wrapper): Remove.
	(record_full_message_wrapper_safe): Update.
	* objc-lang.c (find_objc_msgcall_submethod_helper): Remove.
	(find_objc_msgcall_submethod): Update.
	(struct objc_submethod_helper_data): Remove.
	* main.c (captured_command_loop): Remove parameter.
	(captured_main): Update.
	* infrun.c (hook_stop_stub): Remove.
	(normal_stop): Update.
	(restore_selected_frame): Change type.
	(restore_infcall_control_state): Update.
	* breakpoint.c (bpstat_check_watchpoint)
	(bpstat_check_breakpoint_conditions, gdb_breakpoint_query)
	(struct captured_breakpoint_query_args): Remove.
	(do_captured_breakpoint_query): Change type.
	(breakpoint_re_set): Update.
	* symfile-mem.c (add_vsyscall_page): Update.
	* remote-fileio.c (remote_fileio_request): Update.
	* exceptions.c (catch_exceptions): Use gdb::function_view.
	(catch_exceptions_with_msg, catch_errors): Likewise.
	* exceptions.h (catch_errors, catch_exceptions_with_msg)
	(catch_errors): Update.
	(catch_exceptions_ftype): Remove args.
	(catch_exception_ftype): Remove.
---
 gdb/ChangeLog       | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/breakpoint.c    | 41 +++++++++++++++++++++++------------------
 gdb/exceptions.c    | 14 ++++++--------
 gdb/exceptions.h    | 19 +++++++++----------
 gdb/infrun.c        | 25 ++++++++++---------------
 gdb/main.c          |  4 ++--
 gdb/objc-lang.c     | 33 +++++++--------------------------
 gdb/record-full.c   | 27 +++++----------------------
 gdb/remote-fileio.c |  5 ++++-
 gdb/solib-aix.c     |  2 +-
 gdb/solib-darwin.c  |  2 +-
 gdb/solib-dsbt.c    | 10 ++--------
 gdb/solib-frv.c     |  2 +-
 gdb/solib-svr4.c    | 10 ++--------
 gdb/solib-target.c  |  2 +-
 gdb/solib.c         |  5 ++++-
 gdb/solist.h        |  7 ++-----
 gdb/symfile-mem.c   |  9 +++++++--
 gdb/symmisc.c       | 29 ++++++++++++-----------------
 gdb/thread.c        | 16 ++++++++++------
 gdb/windows-nat.c   |  6 +++---
 21 files changed, 159 insertions(+), 156 deletions(-)
  

Comments

Pedro Alves Sept. 27, 2017, 7:43 p.m. UTC | #1
On 09/27/2017 05:53 PM, Tom Tromey wrote:
> This changes some functions in exceptions.h to use gdb::function_view,
> then fixes up the fallout.  This lead to some surprising places, like
> a function pointer in target_so_ops.
> 
> While writing this I found that catch_exception_ftype was unused, so I
> removed this.
> 
> Note that I did not compile the windows-nat.c change, so I don't know
> if it works.
> 
> Regression tested by the buildbot.
> 

I'm borderline about this.  I have to say that I question the value of
catch_exceptions&co, over just using TRY/CATCH + a scoped_restore(current_uiout)
in the try scope + printing the exception.  A TRY/CATCH is likely to be
easier to understand and debug, I think.  I mean, take the print_symbol
case [it was just the random one that I picked], and compare:

             TRY
               {
                 print_symbol (gdbarch, sym, depth + 1, outfile);
               }
             CATCH (ex, RETURN_MASK_ERROR)
               {
                 exception_fprintf (gdb_stderr, ex,
                                    "Error printing symbol:\n");
               }

vs
    
	      catch_errors ([&] ()
			      {
				return print_symbol (gdbarch, sym, depth + 1,
						     outfile);
			      },
		            "Error printing symbol:\n",
 			    RETURN_MASK_ERROR);


It seems like that case doesn't even need a scoped_restore for current_uiout.
And with TRY/CATCH, print_symbol can be simplified further to return void.

Did you consider this?

> -  if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
> -				 error_message, RETURN_MASK_ALL) < 0)
> +  if (catch_exceptions_with_msg
> +      (uiout,
> +       [&] (struct ui_out *)
> +         {
> +	   return do_captured_breakpoint_query (bnum);
> +	 },

We don't really need the ui_out * parameter in
catch_exceptions_with_msg's callback anymore, since
you can always access it via lambda capture.  Would you
consider removing it?

>  
>  static int
> -do_captured_thread_select (struct ui_out *uiout, void *tidstr_v)
> +do_captured_thread_select (struct ui_out *uiout, const char *tidstr)
>  {


> +         {
> +	   return do_captured_thread_select (inner_uiout, tidstr);
> +	 },

Note the patch has several cases of tabs vs spaces like above.


> @@ -1540,7 +1540,7 @@ get_windows_debug_event (struct target_ops *ops,
>        CloseHandle (current_event.u.LoadDll.hFile);
>        if (saw_create != 1 || ! windows_initialization_done)
>  	break;
> -      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
> +      catch_errors (handle_load_dll, (char *) "", RETURN_MASK_ALL);
>        ourstatus->kind = TARGET_WAITKIND_LOADED;
>        ourstatus->value.integer = 0;
>        thread_id = main_thread_id;
> @@ -1553,7 +1553,7 @@ get_windows_debug_event (struct target_ops *ops,
>  		     "UNLOAD_DLL_DEBUG_EVENT"));
>        if (saw_create != 1 || ! windows_initialization_done)
>  	break;
> -      catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
> +      catch_errors (handle_unload_dll, (char *) "", RETURN_MASK_ALL);
>        ourstatus->kind = TARGET_WAITKIND_LOADED;
>        ourstatus->value.integer = 0;
>        thread_id = main_thread_id;

I don't think we need the casts nowadays.  catch_errors takes a const string (since the -Wwrite-strings patch).

Thanks,
Pedro Alves
  
Tom Tromey Sept. 27, 2017, 8:25 p.m. UTC | #2
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> I'm borderline about this.  I have to say that I question the value of
Pedro> catch_exceptions&co, over just using TRY/CATCH + a scoped_restore(current_uiout)
Pedro> in the try scope + printing the exception.  A TRY/CATCH is likely to be
Pedro> easier to understand and debug, I think.
[...]
Pedro> Did you consider this?

Nope.  This was actually just a preparatory patch for another const change.

I can look into the change though.  I agree it would be better.

>> +         {
>> +	   return do_captured_thread_select (inner_uiout, tidstr);
>> +	 },

Pedro> Note the patch has several cases of tabs vs spaces like above.

Sorry about that.
Was there ever a decision about not using tabs?

In this case I think the problem is that Emacs isn't indenting lambdas
well.

Pedro> I don't think we need the casts nowadays.  catch_errors takes a const
Pedro> string (since the -Wwrite-strings patch).

Ok.

Tom
  

Patch

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 59cb354..d4ae985 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5189,8 +5189,11 @@  bpstat_check_watchpoint (bpstat bs)
 	    = xstrprintf ("Error evaluating expression for watchpoint %d\n",
 			  b->number);
 	  struct cleanup *cleanups = make_cleanup (xfree, message);
-	  int e = catch_errors (watchpoint_check, bs, message,
-				RETURN_MASK_ALL);
+	  int e = catch_errors ([&] ()
+				  {
+				    return watchpoint_check (bs);
+				  },
+	                        message, RETURN_MASK_ALL);
 	  do_cleanups (cleanups);
 	  switch (e)
 	    {
@@ -5421,7 +5424,10 @@  bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
 	}
       if (within_current_scope)
 	value_is_zero
-	  = catch_errors (breakpoint_cond_eval, cond,
+	  = catch_errors ([&] ()
+			    {
+			      return breakpoint_cond_eval (cond);
+			    },
 			  "Error in testing breakpoint condition:\n",
 			  RETURN_MASK_ALL);
       else
@@ -6597,22 +6603,15 @@  breakpoint_address_bits (struct breakpoint *b)
   return print_address_bits;
 }
 
-struct captured_breakpoint_query_args
-  {
-    int bnum;
-  };
-
 static int
-do_captured_breakpoint_query (struct ui_out *uiout, void *data)
+do_captured_breakpoint_query (int bnum)
 {
-  struct captured_breakpoint_query_args *args
-    = (struct captured_breakpoint_query_args *) data;
   struct breakpoint *b;
   struct bp_location *dummy_loc = NULL;
 
   ALL_BREAKPOINTS (b)
     {
-      if (args->bnum == b->number)
+      if (bnum == b->number)
 	{
 	  print_one_breakpoint (b, &dummy_loc, 0);
 	  return GDB_RC_OK;
@@ -6625,13 +6624,15 @@  enum gdb_rc
 gdb_breakpoint_query (struct ui_out *uiout, int bnum, 
 		      char **error_message)
 {
-  struct captured_breakpoint_query_args args;
-
-  args.bnum = bnum;
   /* For the moment we don't trust print_one_breakpoint() to not throw
      an error.  */
-  if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
-				 error_message, RETURN_MASK_ALL) < 0)
+  if (catch_exceptions_with_msg
+      (uiout,
+       [&] (struct ui_out *)
+         {
+	   return do_captured_breakpoint_query (bnum);
+	 },
+       error_message, RETURN_MASK_ALL) < 0)
     return GDB_RC_FAIL;
   else
     return GDB_RC_OK;
@@ -14192,7 +14193,11 @@  breakpoint_re_set (void)
 	char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
 				    b->number);
 	struct cleanup *cleanups = make_cleanup (xfree, message);
-	catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
+	catch_errors ([&] ()
+		        {
+			  return breakpoint_re_set_one (b);
+			},
+	              message, RETURN_MASK_ALL);
 	do_cleanups (cleanups);
       }
     set_language (save_language);
diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index dd11b6e..bbd97cc 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -155,17 +155,15 @@  exception_fprintf (struct ui_file *file, struct gdb_exception e,
 
 int
 catch_exceptions (struct ui_out *uiout,
-		  catch_exceptions_ftype *func,
-		  void *func_args,
+		  gdb::function_view<catch_exceptions_ftype> func,
 		  return_mask mask)
 {
-  return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
+  return catch_exceptions_with_msg (uiout, func, NULL, mask);
 }
 
 int
 catch_exceptions_with_msg (struct ui_out *func_uiout,
-		  	   catch_exceptions_ftype *func,
-		  	   void *func_args,
+			   gdb::function_view<catch_exceptions_ftype> func,
 			   char **gdberrmsg,
 		  	   return_mask mask)
 {
@@ -179,7 +177,7 @@  catch_exceptions_with_msg (struct ui_out *func_uiout,
 
   TRY
     {
-      val = (*func) (current_uiout, func_args);
+      val = func (current_uiout);
     }
   CATCH (ex, RETURN_MASK_ALL)
     {
@@ -220,7 +218,7 @@  catch_exceptions_with_msg (struct ui_out *func_uiout,
 /* This function is superseded by catch_exceptions().  */
 
 int
-catch_errors (catch_errors_ftype *func, void *func_args,
+catch_errors (gdb::function_view<catch_errors_ftype> func,
 	      const char *errstring, return_mask mask)
 {
   struct gdb_exception exception = exception_none;
@@ -232,7 +230,7 @@  catch_errors (catch_errors_ftype *func, void *func_args,
 
   TRY
     {
-      val = func (func_args);
+      val = func ();
     }
   CATCH (ex, RETURN_MASK_ALL)
     {
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index b2cdee3..c65974d 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -65,16 +65,15 @@  extern void exception_fprintf (struct ui_file *file, struct gdb_exception e,
    This function uses SETJMP() and LONGJUMP().  */
 
 struct ui_out;
-typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args);
+typedef int (catch_exceptions_ftype) (struct ui_out *ui_out);
 extern int catch_exceptions (struct ui_out *uiout,
-			     catch_exceptions_ftype *func, void *func_args,
+			     gdb::function_view<catch_exceptions_ftype> func,
 			     return_mask mask);
-typedef void (catch_exception_ftype) (struct ui_out *ui_out, void *args);
-extern int catch_exceptions_with_msg (struct ui_out *uiout,
-			     	      catch_exceptions_ftype *func, 
-			     	      void *func_args,
-			     	      char **gdberrmsg,
-				      return_mask mask);
+extern int catch_exceptions_with_msg
+    (struct ui_out *uiout,
+     gdb::function_view<catch_exceptions_ftype> func, 
+     char **gdberrmsg,
+     return_mask mask);
 
 /* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero
    otherwize the result from CATCH_ERRORS_FTYPE is returned.  It is
@@ -85,8 +84,8 @@  extern int catch_exceptions_with_msg (struct ui_out *uiout,
 
    This function is superseded by catch_exceptions().  */
 
-typedef int (catch_errors_ftype) (void *);
-extern int catch_errors (catch_errors_ftype *, void *,
+typedef int (catch_errors_ftype) ();
+extern int catch_errors (gdb::function_view<catch_errors_ftype>,
 			 const char *, return_mask);
 
 /* Compare two exception objects for print equality.  */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index f44ca91..149a358 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -80,10 +80,6 @@  static void sig_print_header (void);
 
 static void resume_cleanups (void *);
 
-static int hook_stop_stub (void *);
-
-static int restore_selected_frame (void *);
-
 static int follow_fork (void);
 
 static int follow_fork_inferior (int follow_child, int detach_fork);
@@ -8312,7 +8308,11 @@  normal_stop (void)
       struct cleanup *old_chain
 	= make_cleanup (release_stop_context_cleanup, saved_context);
 
-      catch_errors (hook_stop_stub, stop_command,
+      catch_errors ([&] ()
+		      {
+			execute_cmd_pre_hook (stop_command);
+			return 0;
+		      },
 		    "Error while running hook_stop:\n", RETURN_MASK_ALL);
 
       /* If the stop hook resumes the target, then there's no point in
@@ -8354,13 +8354,6 @@  normal_stop (void)
 
   return 0;
 }
-
-static int
-hook_stop_stub (void *cmd)
-{
-  execute_cmd_pre_hook ((struct cmd_list_element *) cmd);
-  return (0);
-}
 
 int
 signal_stop_state (int signo)
@@ -8982,9 +8975,8 @@  save_infcall_control_state (void)
 }
 
 static int
-restore_selected_frame (void *args)
+restore_selected_frame (struct frame_id *fid)
 {
-  struct frame_id *fid = (struct frame_id *) args;
   struct frame_info *frame;
 
   frame = frame_find_by_id (*fid);
@@ -9033,7 +9025,10 @@  restore_infcall_control_state (struct infcall_control_state *inf_status)
          walking the stack might encounter a garbage pointer and
          error() trying to dereference it.  */
       if (catch_errors
-	  (restore_selected_frame, &inf_status->selected_frame_id,
+	  ([&] ()
+	     {
+	       return restore_selected_frame (&inf_status->selected_frame_id);
+	     },
 	   "Unable to restore previously selected frame:\n",
 	   RETURN_MASK_ERROR) == 0)
 	/* Error in restoring the selected frame.  Select the innermost
diff --git a/gdb/main.c b/gdb/main.c
index 66ba75b..8408bfc 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -309,7 +309,7 @@  setup_alternate_signal_stack (void)
    non-zero return status.  */
 
 static int
-captured_command_loop (void *data)
+captured_command_loop ()
 {
   struct ui *ui = current_ui;
 
@@ -1147,7 +1147,7 @@  captured_main (void *data)
      change - SET_TOP_LEVEL() - has been eliminated.  */
   while (1)
     {
-      catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
+      catch_errors (captured_command_loop, "", RETURN_MASK_ALL);
     }
   /* No exit -- exit is through quit_command.  */
 }
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index dc9c934..2b84904 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -1310,37 +1310,18 @@  find_objc_msgsend (void)
  * dependent modules.
  */
 
-struct objc_submethod_helper_data {
-  int (*f) (CORE_ADDR, CORE_ADDR *);
-  CORE_ADDR pc;
-  CORE_ADDR *new_pc;
-};
-
-static int 
-find_objc_msgcall_submethod_helper (void * arg)
-{
-  struct objc_submethod_helper_data *s = 
-    (struct objc_submethod_helper_data *) arg;
-
-  if (s->f (s->pc, s->new_pc) == 0) 
-    return 1;
-  else 
-    return 0;
-}
-
 static int 
 find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
 			     CORE_ADDR pc, 
 			     CORE_ADDR *new_pc)
 {
-  struct objc_submethod_helper_data s;
-
-  s.f = f;
-  s.pc = pc;
-  s.new_pc = new_pc;
-
-  if (catch_errors (find_objc_msgcall_submethod_helper,
-		    (void *) &s,
+  if (catch_errors ([&] ()
+		      {
+			if (f (pc, new_pc) == 0)
+			  return 1;
+			else
+			  return 0;
+		      },
 		    "Unable to determine target of "
 		    "Objective-C method call (ignoring):\n",
 		    RETURN_MASK_ALL) == 0) 
diff --git a/gdb/record-full.c b/gdb/record-full.c
index 5073be3..2d9085a 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -637,32 +637,15 @@  record_full_message (struct regcache *regcache, enum gdb_signal signal)
   return 1;
 }
 
-struct record_full_message_args {
-  struct regcache *regcache;
-  enum gdb_signal signal;
-};
-
-static int
-record_full_message_wrapper (void *args)
-{
-  struct record_full_message_args *record_full_args
-    = (struct record_full_message_args *) args;
-
-  return record_full_message (record_full_args->regcache,
-			      record_full_args->signal);
-}
-
 static int
 record_full_message_wrapper_safe (struct regcache *regcache,
 				  enum gdb_signal signal)
 {
-  struct record_full_message_args args;
-
-  args.regcache = regcache;
-  args.signal = signal;
-
-  return catch_errors (record_full_message_wrapper, &args, "",
-		       RETURN_MASK_ALL);
+  return catch_errors ([&] ()
+		         {
+			   return record_full_message (regcache, signal);
+			 },
+		       "", RETURN_MASK_ALL);
 }
 
 /* Set to 1 if record_full_store_registers and record_full_xfer_partial
diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index c305171..f3e33ec 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -1189,7 +1189,10 @@  remote_fileio_request (char *buf, int ctrlc_pending_p)
   else
     {
       ex = catch_exceptions (current_uiout,
-			     do_remote_fileio_request, (void *)buf,
+			     [&] (ui_out *uiout)
+			       {
+				 return do_remote_fileio_request (uiout, buf);
+			       },
 			     RETURN_MASK_ALL);
       switch (ex)
 	{
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 633c9e6..9233e78 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -589,7 +589,7 @@  solib_aix_current_sos (void)
 /* Implement the "open_symbol_file_object" target_so_ops method.  */
 
 static int
-solib_aix_open_symbol_file_object (void *from_ttyp)
+solib_aix_open_symbol_file_object (int from_tty)
 {
   return 0;
 }
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 04bbf86..f63f924 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -222,7 +222,7 @@  find_program_interpreter (void)
     Note that darwin-nat.c implements pid_to_exec_file.  */
 
 static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
 {
   return 0;
 }
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 86b9e30..0b4055c 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -507,16 +507,10 @@  scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
   return 0;
 }
 
-/* If no open symbol file, attempt to locate and open the main symbol
-   file.
-
-   If FROM_TTYP dereferences to a non-zero integer, allow messages to
-   be printed.  This parameter is a pointer rather than an int because
-   open_symbol_file_object is called via catch_errors and
-   catch_errors requires a pointer argument. */
+/* See solist.h. */
 
 static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
 {
   /* Unimplemented.  */
   return 0;
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index 6d74652..fd748f4 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -246,7 +246,7 @@  static int enable_break2 (void);
 /* Implement the "open_symbol_file_object" target_so_ops method.  */
 
 static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
 {
   /* Unimplemented.  */
   return 0;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 405de37..d334791 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -984,20 +984,14 @@  svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
   return (name_lm >= vaddr && name_lm < vaddr + size);
 }
 
-/* Implement the "open_symbol_file_object" target_so_ops method.
-
-   If no open symbol file, attempt to locate and open the main symbol
-   file.  On SVR4 systems, this is the first link map entry.  If its
-   name is here, we can open it.  Useful when attaching to a process
-   without first loading its symbol file.  */
+/* See solist.h.  */
 
 static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
 {
   CORE_ADDR lm, l_name;
   char *filename;
   int errcode;
-  int from_tty = *(int *)from_ttyp;
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
   int l_name_size = TYPE_LENGTH (ptr_type);
diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index dcd0f85..cf569ec 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -452,7 +452,7 @@  Could not relocate shared library \"%s\": bad offsets"), so->so_name);
 }
 
 static int
-solib_target_open_symbol_file_object (void *from_ttyp)
+solib_target_open_symbol_file_object (int from_tty)
 {
   /* We can't locate the main symbol file based on the target's
      knowledge; the user has to specify it.  */
diff --git a/gdb/solib.c b/gdb/solib.c
index 4f7fd90..0349c8f 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -760,7 +760,10 @@  update_solib_list (int from_tty)
 	 have not opened a symbol file, we may be able to get its
 	 symbols now!  */
       if (inf->attach_flag && symfile_objfile == NULL)
-	catch_errors (ops->open_symbol_file_object, &from_tty,
+	catch_errors ([&] ()
+		        {
+			  return ops->open_symbol_file_object (from_tty);
+			},
 		      "Error reading attached process's symbol file.\n",
 		      RETURN_MASK_ALL);
     }
diff --git a/gdb/solist.h b/gdb/solist.h
index 5eb2d39..992986e 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -121,11 +121,8 @@  struct target_so_ops
     struct so_list *(*current_sos) (void);
 
     /* Find, open, and read the symbols for the main executable.  If
-       FROM_TTYP dereferences to a non-zero integer, allow messages to
-       be printed.  This parameter is a pointer rather than an int
-       because open_symbol_file_object is called via catch_errors and
-       catch_errors requires a pointer argument.  */
-    int (*open_symbol_file_object) (void *from_ttyp);
+       FROM_TTY is non-zero, allow messages to be printed.  */
+    int (*open_symbol_file_object) (int from_ttyp);
 
     /* Determine if PC lies in the dynamic symbol resolution code of
        the run time loader.  */
diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c
index 6f34cab..5cefbc9 100644
--- a/gdb/symfile-mem.c
+++ b/gdb/symfile-mem.c
@@ -231,8 +231,13 @@  add_vsyscall_page (struct target_ops *target, int from_tty)
 	 vsyscall DSO was not triggered by the user, even if the user
 	 typed "run" at the TTY.  */
       args.from_tty = 0;
-      catch_exceptions (current_uiout, symbol_file_add_from_memory_wrapper,
-			&args, RETURN_MASK_ALL);
+      catch_exceptions (current_uiout,
+			[&] (ui_out *uiout)
+			  {
+			    return symbol_file_add_from_memory_wrapper (uiout,
+									&args);
+			  },
+			RETURN_MASK_ALL);
     }
 }
 
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 86422e7..6236bad 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -62,7 +62,8 @@  struct print_symbol_args
     struct ui_file *outfile;
   };
 
-static int print_symbol (void *);
+static int print_symbol (struct gdbarch *gdbarch, struct symbol *symbol,
+			 int depth, struct ui_file *outfile);
 
 
 void
@@ -357,13 +358,12 @@  dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile)
 	     block, not any blocks from included symtabs.  */
 	  ALL_DICT_SYMBOLS (BLOCK_DICT (b), iter, sym)
 	    {
-	      struct print_symbol_args s;
-
-	      s.gdbarch = gdbarch;
-	      s.symbol = sym;
-	      s.depth = depth + 1;
-	      s.outfile = outfile;
-	      catch_errors (print_symbol, &s, "Error printing symbol:\n",
+	      catch_errors ([&] ()
+			      {
+				return print_symbol (gdbarch, sym, depth + 1,
+						     outfile);
+			      },
+		            "Error printing symbol:\n",
 			    RETURN_MASK_ERROR);
 	    }
 	}
@@ -515,18 +515,13 @@  maintenance_print_symbols (const char *args, int from_tty)
     }
 }
 
-/* Print symbol ARGS->SYMBOL on ARGS->OUTFILE.  ARGS->DEPTH says how
-   far to indent.  ARGS is really a struct print_symbol_args *, but is
-   declared as char * to get it past catch_errors.  Returns 0 for error,
-   1 for success.  */
+/* Print symbol SYMBOL on OUTFILE.  DEPTH says how far to indent.
+   Returns 0 for error, 1 for success.  */
 
 static int
-print_symbol (void *args)
+print_symbol (struct gdbarch *gdbarch, struct symbol *symbol,
+	      int depth, struct ui_file *outfile)
 {
-  struct gdbarch *gdbarch = ((struct print_symbol_args *) args)->gdbarch;
-  struct symbol *symbol = ((struct print_symbol_args *) args)->symbol;
-  int depth = ((struct print_symbol_args *) args)->depth;
-  struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile;
   struct obj_section *section;
 
   if (SYMBOL_OBJFILE_OWNED (symbol))
diff --git a/gdb/thread.c b/gdb/thread.c
index 91c077a..7deebf2 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -723,7 +723,7 @@  any_live_thread_of_process (int pid)
 /* Print a list of thread ids currently known, and the total number of
    threads.  To be used from within catch_errors.  */
 static int
-do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
+do_captured_list_thread_ids (struct ui_out *uiout)
 {
   struct thread_info *tp;
   int num = 0;
@@ -758,7 +758,7 @@  do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
 enum gdb_rc
 gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
 {
-  if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
+  if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids,
 				 error_message, RETURN_MASK_ALL) < 0)
     return GDB_RC_FAIL;
   return GDB_RC_OK;
@@ -1992,9 +1992,8 @@  show_print_thread_events (struct ui_file *file, int from_tty,
 }
 
 static int
-do_captured_thread_select (struct ui_out *uiout, void *tidstr_v)
+do_captured_thread_select (struct ui_out *uiout, const char *tidstr)
 {
-  const char *tidstr = (const char *) tidstr_v;
   struct thread_info *tp;
 
   if (uiout->is_mi_like_p ())
@@ -2070,8 +2069,13 @@  print_selected_thread_frame (struct ui_out *uiout,
 enum gdb_rc
 gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
 {
-  if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
-				 error_message, RETURN_MASK_ALL) < 0)
+  if (catch_exceptions_with_msg
+      (uiout,
+       [&] (struct ui_out *inner_uiout)
+         {
+	   return do_captured_thread_select (inner_uiout, tidstr);
+	 },
+       error_message, RETURN_MASK_ALL) < 0)
     return GDB_RC_FAIL;
   return GDB_RC_OK;
 }
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 3e18944..8fb6595 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -755,7 +755,7 @@  get_image_name (HANDLE h, void *address, int unicode)
    on how we handle DLL loading during that phase).  */
 
 static int
-handle_load_dll (void *dummy)
+handle_load_dll ()
 {
   LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
   char *dll_name;
@@ -1540,7 +1540,7 @@  get_windows_debug_event (struct target_ops *ops,
       CloseHandle (current_event.u.LoadDll.hFile);
       if (saw_create != 1 || ! windows_initialization_done)
 	break;
-      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
+      catch_errors (handle_load_dll, (char *) "", RETURN_MASK_ALL);
       ourstatus->kind = TARGET_WAITKIND_LOADED;
       ourstatus->value.integer = 0;
       thread_id = main_thread_id;
@@ -1553,7 +1553,7 @@  get_windows_debug_event (struct target_ops *ops,
 		     "UNLOAD_DLL_DEBUG_EVENT"));
       if (saw_create != 1 || ! windows_initialization_done)
 	break;
-      catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
+      catch_errors (handle_unload_dll, (char *) "", RETURN_MASK_ALL);
       ourstatus->kind = TARGET_WAITKIND_LOADED;
       ourstatus->value.integer = 0;
       thread_id = main_thread_id;