Split rank_one_type_parm_complex from rank_one_type
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 150288264f4aaf2420627b8a4833b66e6fa03443..33e5d434b3582cdf189887fb985331ab64f0b6a4 100644 (file)
@@ -25,7 +25,7 @@
 #include "frame.h"
 #include "inferior.h"
 #include "breakpoint.h"
-#include "gdb_wait.h"
+#include "common/gdb_wait.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "cli/cli-script.h"
@@ -67,6 +67,8 @@
 #include "progspace-and-thread.h"
 #include "common/gdb_optional.h"
 #include "arch-utils.h"
+#include "common/scope-exit.h"
+#include "common/forward-scope-exit.h"
 
 /* Prototypes for local functions */
 
@@ -305,20 +307,19 @@ update_observer_mode (void)
 
 /* Tables of how to react to signals; the user sets them.  */
 
-static unsigned char *signal_stop;
-static unsigned char *signal_print;
-static unsigned char *signal_program;
+static unsigned char signal_stop[GDB_SIGNAL_LAST];
+static unsigned char signal_print[GDB_SIGNAL_LAST];
+static unsigned char signal_program[GDB_SIGNAL_LAST];
 
 /* Table of signals that are registered with "catch signal".  A
    non-zero entry indicates that the signal is caught by some "catch
-   signal" command.  This has size GDB_SIGNAL_LAST, to accommodate all
-   signals.  */
-static unsigned char *signal_catch;
+   signal" command.  */
+static unsigned char signal_catch[GDB_SIGNAL_LAST];
 
 /* Table of signals that the target may silently handle.
    This is automatically determined from the flags above,
    and simply cached here.  */
-static unsigned char *signal_pass;
+static unsigned char signal_pass[GDB_SIGNAL_LAST];
 
 #define SET_SIGS(nsigs,sigs,flags) \
   do { \
@@ -342,7 +343,7 @@ static unsigned char *signal_pass;
 void
 update_signals_program_target (void)
 {
-  target_program_signals ((int) GDB_SIGNAL_LAST, signal_program);
+  target_program_signals (signal_program);
 }
 
 /* Value to pass to target_resume() to cause all threads to resume.  */
@@ -1159,8 +1160,6 @@ follow_exec (ptid_t ptid, char *exec_file_target)
   /* We've followed the inferior through an exec.  Therefore, the
      inferior has essentially been killed & reborn.  */
 
-  gdb_flush (gdb_stdout);
-
   breakpoint_init_inferior (inf_execd);
 
   gdb::unique_xmalloc_ptr<char> exec_file_host
@@ -1598,14 +1597,9 @@ displaced_step_clear (struct displaced_step_inferior_state *displaced)
   displaced->step_closure = NULL;
 }
 
-static void
-displaced_step_clear_cleanup (void *arg)
-{
-  struct displaced_step_inferior_state *state
-    = (struct displaced_step_inferior_state *) arg;
-
-  displaced_step_clear (state);
-}
+/* A cleanup that wraps displaced_step_clear.  */
+using displaced_step_clear_cleanup
+  = FORWARD_SCOPE_EXIT (displaced_step_clear);
 
 /* Dump LEN bytes at BUF in hex to FILE, followed by a newline.  */
 void
@@ -1754,13 +1748,14 @@ displaced_step_prepare_throw (thread_info *tp)
   displaced->step_original = original;
   displaced->step_copy = copy;
 
-  cleanup *ignore_cleanups
-    = make_cleanup (displaced_step_clear_cleanup, displaced);
+  {
+    displaced_step_clear_cleanup cleanup (displaced);
 
-  /* Resume execution at the copy.  */
-  regcache_write_pc (regcache, copy);
+    /* Resume execution at the copy.  */
+    regcache_write_pc (regcache, copy);
 
-  discard_cleanups (ignore_cleanups);
+    cleanup.release ();
+  }
 
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to %s\n",
@@ -1850,7 +1845,6 @@ displaced_step_restore (struct displaced_step_inferior_state *displaced,
 static int
 displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
 {
-  struct cleanup *old_cleanups;
   struct displaced_step_inferior_state *displaced
     = get_displaced_stepping_state (event_thread->inf);
   int ret;
@@ -1859,7 +1853,7 @@ displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
   if (displaced->step_thread != event_thread)
     return 0;
 
-  old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
+  displaced_step_clear_cleanup cleanup (displaced);
 
   displaced_step_restore (displaced, displaced->step_thread->ptid);
 
@@ -1894,10 +1888,6 @@ displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
       ret = -1;
     }
 
-  do_cleanups (old_cleanups);
-
-  displaced->step_thread = nullptr;
-
   return ret;
 }
 
@@ -2218,9 +2208,9 @@ do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
        valid.  */
   if (step_over_info_valid_p ()
       || displaced_step_in_progress (tp->inf))
-    target_pass_signals (0, NULL);
+    target_pass_signals ({});
   else
-    target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+    target_pass_signals (signal_pass);
 
   target_resume (resume_ptid, step, sig);
 
@@ -2710,7 +2700,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   if (!signal_pass_state (tp->suspend.stop_signal))
     tp->suspend.stop_signal = GDB_SIGNAL_0;
 
-  thread_fsm_delete (tp->thread_fsm);
+  delete tp->thread_fsm;
   tp->thread_fsm = NULL;
 
   tp->control.trap_expected = 0;
@@ -3247,14 +3237,6 @@ delete_just_stopped_threads_single_step_breakpoints (void)
   for_each_just_stopped_thread (delete_single_step_breakpoints);
 }
 
-/* A cleanup wrapper.  */
-
-static void
-delete_just_stopped_threads_infrun_breakpoints_cleanup (void *arg)
-{
-  delete_just_stopped_threads_infrun_breakpoints ();
-}
-
 /* See infrun.h.  */
 
 void
@@ -3538,15 +3520,11 @@ prepare_for_detach (void)
 void
 wait_for_inferior (void)
 {
-  struct cleanup *old_cleanups;
-
   if (debug_infrun)
     fprintf_unfiltered
       (gdb_stdlog, "infrun: wait_for_inferior ()\n");
 
-  old_cleanups
-    = make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup,
-                   NULL);
+  SCOPE_EXIT { delete_just_stopped_threads_infrun_breakpoints (); };
 
   /* If an error happens while handling the event, propagate GDB's
      knowledge of the executing state to the frontend/user running
@@ -3583,8 +3561,6 @@ wait_for_inferior (void)
 
   /* No error, don't finish the state yet.  */
   finish_state.release ();
-
-  do_cleanups (old_cleanups);
 }
 
 /* Cleanup that reinstalls the readline callback handler, if the
@@ -3598,7 +3574,7 @@ wait_for_inferior (void)
    input.  */
 
 static void
-reinstall_readline_callback_handler_cleanup (void *arg)
+reinstall_readline_callback_handler_cleanup ()
 {
   struct ui *ui = current_ui;
 
@@ -3624,8 +3600,7 @@ clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
 {
   if (ecs->event_thread != NULL
       && ecs->event_thread->thread_fsm != NULL)
-    thread_fsm_clean_up (ecs->event_thread->thread_fsm,
-                        ecs->event_thread);
+    ecs->event_thread->thread_fsm->clean_up (ecs->event_thread);
 
   if (!non_stop)
     {
@@ -3637,7 +3612,7 @@ clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
            continue;
 
          switch_to_thread (thr);
-         thread_fsm_clean_up (thr->thread_fsm, thr);
+         thr->thread_fsm->clean_up (thr);
        }
 
       if (ecs->event_thread != NULL)
@@ -3700,7 +3675,6 @@ fetch_inferior_event (void *client_data)
 {
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   int cmd_done = 0;
   ptid_t waiton_ptid = minus_one_ptid;
 
@@ -3712,114 +3686,116 @@ fetch_inferior_event (void *client_data)
   scoped_restore save_ui = make_scoped_restore (&current_ui, main_ui);
 
   /* End up with readline processing input, if necessary.  */
-  make_cleanup (reinstall_readline_callback_handler_cleanup, NULL);
-
-  /* We're handling a live event, so make sure we're doing live
-     debugging.  If we're looking at traceframes while the target is
-     running, we're going to need to get back to that mode after
-     handling the event.  */
-  gdb::optional<scoped_restore_current_traceframe> maybe_restore_traceframe;
-  if (non_stop)
-    {
-      maybe_restore_traceframe.emplace ();
-      set_current_traceframe (-1);
-    }
-
-  gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
-
-  if (non_stop)
-    /* In non-stop mode, the user/frontend should not notice a thread
-       switch due to internal events.  Make sure we reverse to the
-       user selected thread and frame after handling the event and
-       running any breakpoint commands.  */
-    maybe_restore_thread.emplace ();
-
-  overlay_cache_invalid = 1;
-  /* Flush target cache before starting to handle each event.  Target
-     was running and cache could be stale.  This is just a heuristic.
-     Running threads may modify target memory, but we don't get any
-     event.  */
-  target_dcache_invalidate ();
-
-  scoped_restore save_exec_dir
-    = make_scoped_restore (&execution_direction, target_execution_direction ());
-
-  ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
-                             target_can_async_p () ? TARGET_WNOHANG : 0);
-
-  if (debug_infrun)
-    print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
-
-  /* If an error happens while handling the event, propagate GDB's
-     knowledge of the executing state to the frontend/user running
-     state.  */
-  ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
-  scoped_finish_thread_state finish_state (finish_ptid);
-
-  /* Get executed before make_cleanup_restore_current_thread above to apply
-     still for the thread which has thrown the exception.  */
-  struct cleanup *ts_old_chain = make_bpstat_clear_actions_cleanup ();
-
-  make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup, NULL);
-
-  /* Now figure out what to do with the result of the result.  */
-  handle_inferior_event (ecs);
+  {
+    SCOPE_EXIT { reinstall_readline_callback_handler_cleanup (); };
+
+    /* We're handling a live event, so make sure we're doing live
+       debugging.  If we're looking at traceframes while the target is
+       running, we're going to need to get back to that mode after
+       handling the event.  */
+    gdb::optional<scoped_restore_current_traceframe> maybe_restore_traceframe;
+    if (non_stop)
+      {
+       maybe_restore_traceframe.emplace ();
+       set_current_traceframe (-1);
+      }
 
-  if (!ecs->wait_some_more)
-    {
-      struct inferior *inf = find_inferior_ptid (ecs->ptid);
-      int should_stop = 1;
-      struct thread_info *thr = ecs->event_thread;
+    gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
+
+    if (non_stop)
+      /* In non-stop mode, the user/frontend should not notice a thread
+        switch due to internal events.  Make sure we reverse to the
+        user selected thread and frame after handling the event and
+        running any breakpoint commands.  */
+      maybe_restore_thread.emplace ();
+
+    overlay_cache_invalid = 1;
+    /* Flush target cache before starting to handle each event.  Target
+       was running and cache could be stale.  This is just a heuristic.
+       Running threads may modify target memory, but we don't get any
+       event.  */
+    target_dcache_invalidate ();
+
+    scoped_restore save_exec_dir
+      = make_scoped_restore (&execution_direction,
+                            target_execution_direction ());
+
+    ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
+                               target_can_async_p () ? TARGET_WNOHANG : 0);
+
+    if (debug_infrun)
+      print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
+
+    /* If an error happens while handling the event, propagate GDB's
+       knowledge of the executing state to the frontend/user running
+       state.  */
+    ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
+    scoped_finish_thread_state finish_state (finish_ptid);
+
+    /* Get executed before scoped_restore_current_thread above to apply
+       still for the thread which has thrown the exception.  */
+    auto defer_bpstat_clear
+      = make_scope_exit (bpstat_clear_actions);
+    auto defer_delete_threads
+      = make_scope_exit (delete_just_stopped_threads_infrun_breakpoints);
+
+    /* Now figure out what to do with the result of the result.  */
+    handle_inferior_event (ecs);
+
+    if (!ecs->wait_some_more)
+      {
+       struct inferior *inf = find_inferior_ptid (ecs->ptid);
+       int should_stop = 1;
+       struct thread_info *thr = ecs->event_thread;
 
-      delete_just_stopped_threads_infrun_breakpoints ();
+       delete_just_stopped_threads_infrun_breakpoints ();
 
-      if (thr != NULL)
-       {
-         struct thread_fsm *thread_fsm = thr->thread_fsm;
+       if (thr != NULL)
+         {
+           struct thread_fsm *thread_fsm = thr->thread_fsm;
 
-         if (thread_fsm != NULL)
-           should_stop = thread_fsm_should_stop (thread_fsm, thr);
-       }
+           if (thread_fsm != NULL)
+             should_stop = thread_fsm->should_stop (thr);
+         }
 
-      if (!should_stop)
-       {
-         keep_going (ecs);
-       }
-      else
-       {
-         int should_notify_stop = 1;
-         int proceeded = 0;
+       if (!should_stop)
+         {
+           keep_going (ecs);
+         }
+       else
+         {
+           bool should_notify_stop = true;
+           int proceeded = 0;
 
-         clean_up_just_stopped_threads_fsms (ecs);
+           clean_up_just_stopped_threads_fsms (ecs);
 
-         if (thr != NULL && thr->thread_fsm != NULL)
-           {
-             should_notify_stop
-               = thread_fsm_should_notify_stop (thr->thread_fsm);
-           }
+           if (thr != NULL && thr->thread_fsm != NULL)
+             should_notify_stop = thr->thread_fsm->should_notify_stop ();
 
-         if (should_notify_stop)
-           {
-             /* We may not find an inferior if this was a process exit.  */
-             if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
-               proceeded = normal_stop ();
-           }
+           if (should_notify_stop)
+             {
+               /* We may not find an inferior if this was a process exit.  */
+               if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
+                 proceeded = normal_stop ();
+             }
 
-         if (!proceeded)
-           {
-             inferior_event_handler (INF_EXEC_COMPLETE, NULL);
-             cmd_done = 1;
-           }
-       }
-    }
+           if (!proceeded)
+             {
+               inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+               cmd_done = 1;
+             }
+         }
+      }
 
-  discard_cleanups (ts_old_chain);
+    defer_delete_threads.release ();
+    defer_bpstat_clear.release ();
 
-  /* No error, don't finish the thread states yet.  */
-  finish_state.release ();
+    /* No error, don't finish the thread states yet.  */
+    finish_state.release ();
 
-  /* Revert thread and frame.  */
-  do_cleanups (old_chain);
+    /* This scope is used to ensure that readline callbacks are
+       reinstalled here.  */
+  }
 
   /* If a UI was in sync execution mode, and now isn't, restore its
      prompt (a synchronous execution command has finished, and we're
@@ -4284,14 +4260,6 @@ save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
     }
 }
 
-/* A cleanup that disables thread create/exit events.  */
-
-static void
-disable_thread_events (void *arg)
-{
-  target_thread_events (0);
-}
-
 /* See infrun.h.  */
 
 void
@@ -4300,7 +4268,6 @@ stop_all_threads (void)
   /* We may need multiple passes to discover all threads.  */
   int pass;
   int iterations = 0;
-  struct cleanup *old_chain;
 
   gdb_assert (target_is_non_stop_p ());
 
@@ -4310,7 +4277,7 @@ stop_all_threads (void)
   scoped_restore_current_thread restore_thread;
 
   target_thread_events (1);
-  old_chain = make_cleanup (disable_thread_events, NULL);
+  SCOPE_EXIT { target_thread_events (0); };
 
   /* Request threads to stop, and then wait for the stops.  Because
      threads we already know about can spawn more threads while we're
@@ -4495,8 +4462,6 @@ stop_all_threads (void)
        }
     }
 
-  do_cleanups (old_chain);
-
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog, "infrun: stop_all_threads done\n");
 }
@@ -7907,11 +7872,11 @@ print_stop_event (struct ui_out *uiout)
 
   tp = inferior_thread ();
   if (tp->thread_fsm != NULL
-      && thread_fsm_finished_p (tp->thread_fsm))
+      && tp->thread_fsm->finished_p ())
     {
       struct return_value_info *rv;
 
-      rv = thread_fsm_return_value (tp->thread_fsm);
+      rv = tp->thread_fsm->return_value ();
       if (rv != NULL)
        print_return_value (uiout, rv);
     }
@@ -8181,7 +8146,8 @@ normal_stop (void)
   if (target_has_execution)
     {
       if (last.kind != TARGET_WAITKIND_SIGNALLED
-         && last.kind != TARGET_WAITKIND_EXITED)
+         && last.kind != TARGET_WAITKIND_EXITED
+         && last.kind != TARGET_WAITKIND_NO_RESUMED)
        /* Delete the breakpoint we stopped at, if it wants to be deleted.
           Delete any breakpoint that is to be deleted at the next stop.  */
        breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat);
@@ -8271,7 +8237,7 @@ signal_catch_update (const unsigned int *info)
   for (i = 0; i < GDB_SIGNAL_LAST; ++i)
     signal_catch[i] = info[i] > 0;
   signal_cache_update (-1);
-  target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+  target_pass_signals (signal_pass);
 }
 
 static void
@@ -8307,8 +8273,6 @@ handle_command (const char *args, int from_tty)
   int sigfirst, siglast;
   enum gdb_signal oursig;
   int allsigs;
-  int nsigs;
-  unsigned char *sigs;
 
   if (args == NULL)
     {
@@ -8317,9 +8281,8 @@ handle_command (const char *args, int from_tty)
 
   /* Allocate and zero an array of flags for which signals to handle.  */
 
-  nsigs = (int) GDB_SIGNAL_LAST;
-  sigs = (unsigned char *) alloca (nsigs);
-  memset (sigs, 0, nsigs);
+  const size_t nsigs = GDB_SIGNAL_LAST;
+  unsigned char sigs[nsigs] {};
 
   /* Break the command line up into args.  */
 
@@ -8434,10 +8397,7 @@ Are you sure you want to change it? "),
                      sigs[signum] = 1;
                    }
                  else
-                   {
-                     printf_unfiltered (_("Not confirmed, unchanged.\n"));
-                     gdb_flush (gdb_stdout);
-                   }
+                   printf_unfiltered (_("Not confirmed, unchanged.\n"));
                }
              break;
            case GDB_SIGNAL_0:
@@ -8456,8 +8416,8 @@ Are you sure you want to change it? "),
     if (sigs[signum])
       {
        signal_cache_update (-1);
-       target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
-       target_program_signals ((int) GDB_SIGNAL_LAST, signal_program);
+       target_pass_signals (signal_pass);
+       target_program_signals (signal_program);
 
        if (from_tty)
          {
@@ -8983,8 +8943,6 @@ infrun_async_inferior_event_handler (gdb_client_data data)
 void
 _initialize_infrun (void)
 {
-  int i;
-  int numsigs;
   struct cmd_list_element *c;
 
   /* Register extra event sources in the event loop.  */
@@ -9066,13 +9024,7 @@ leave it stopped or free to run as needed."),
                           &setlist,
                           &showlist);
 
-  numsigs = (int) GDB_SIGNAL_LAST;
-  signal_stop = XNEWVEC (unsigned char, numsigs);
-  signal_print = XNEWVEC (unsigned char, numsigs);
-  signal_program = XNEWVEC (unsigned char, numsigs);
-  signal_catch = XNEWVEC (unsigned char, numsigs);
-  signal_pass = XNEWVEC (unsigned char, numsigs);
-  for (i = 0; i < numsigs; i++)
+  for (size_t i = 0; i < GDB_SIGNAL_LAST; i++)
     {
       signal_stop[i] = 1;
       signal_print[i] = 1;
This page took 0.035509 seconds and 4 git commands to generate.