Remove ref_dynamic_nonweak added by accident
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 4f59a9261ea9dc655ca6ab7a0fa93ef32f3cd668..e7c20e165b36d4c1f29cd333b73b06bac190ccbd 100644 (file)
@@ -58,6 +58,7 @@
 #include "probe.h"
 #include "objfiles.h"
 #include "completer.h"
+#include "target-descriptions.h"
 
 /* Prototypes for local functions */
 
@@ -663,7 +664,18 @@ handle_vfork_child_exec_or_exit (int exec)
 
          /* follow-fork child, detach-on-fork on.  */
 
-         old_chain = make_cleanup_restore_current_thread ();
+         inf->vfork_parent->pending_detach = 0;
+
+         if (!exec)
+           {
+             /* If we're handling a child exit, then inferior_ptid
+                points at the inferior's pid, not to a thread.  */
+             old_chain = save_inferior_ptid ();
+             save_current_program_space ();
+             save_current_inferior ();
+           }
+         else
+           old_chain = save_current_space_and_thread ();
 
          /* We're letting loose of the parent.  */
          tp = any_live_thread_of_process (inf->vfork_parent->pid);
@@ -902,6 +914,16 @@ follow_exec (ptid_t pid, char *execd_pathname)
       set_current_inferior (inf);
       set_current_program_space (pspace);
     }
+  else
+    {
+      /* The old description may no longer be fit for the new image.
+        E.g, a 64-bit process exec'ed a 32-bit process.  Clear the
+        old description; we'll read a new one below.  No need to do
+        this on "follow-exec-mode new", as the old inferior stays
+        around (its description is later cleared/refetched on
+        restart).  */
+      target_clear_description ();
+    }
 
   gdb_assert (current_program_space == inf->pspace);
 
@@ -921,6 +943,14 @@ follow_exec (ptid_t pid, char *execd_pathname)
   if ((inf->symfile_flags & SYMFILE_NO_READ) == 0)
     set_initial_language ();
 
+  /* If the target can specify a description, read it.  Must do this
+     after flipping to the new executable (because the target supplied
+     description must be compatible with the executable's
+     architecture, and the old executable may e.g., be 32-bit, while
+     the new one 64-bit), and before anything involving memory or
+     registers.  */
+  target_find_description ();
+
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #else
@@ -2362,7 +2392,7 @@ enum infwait_states
 ptid_t waiton_ptid;
 
 /* Current inferior wait state.  */
-enum infwait_states infwait_state;
+static enum infwait_states infwait_state;
 
 /* Data to be passed around while handling an event.  This data is
    discarded between events.  */
@@ -3370,23 +3400,38 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
 
     case TARGET_WAITKIND_EXITED:
+    case TARGET_WAITKIND_SIGNALLED:
       if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXITED\n");
+       {
+         if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_EXITED\n");
+         else
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_SIGNALLED\n");
+       }
+
       inferior_ptid = ecs->ptid;
       set_current_inferior (find_inferior_pid (ptid_get_pid (ecs->ptid)));
       set_current_program_space (current_inferior ()->pspace);
       handle_vfork_child_exec_or_exit (0);
       target_terminal_ours (); /* Must do this before mourn anyway.  */
-      print_exited_reason (ecs->ws.value.integer);
 
-      /* Record the exit code in the convenience variable $_exitcode, so
-         that the user can inspect this again later.  */
-      set_internalvar_integer (lookup_internalvar ("_exitcode"),
-                              (LONGEST) ecs->ws.value.integer);
+      if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
+       {
+         /* Record the exit code in the convenience variable $_exitcode, so
+            that the user can inspect this again later.  */
+         set_internalvar_integer (lookup_internalvar ("_exitcode"),
+                                  (LONGEST) ecs->ws.value.integer);
 
-      /* Also record this in the inferior itself.  */
-      current_inferior ()->has_exit_code = 1;
-      current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
+         /* Also record this in the inferior itself.  */
+         current_inferior ()->has_exit_code = 1;
+         current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
+
+         print_exited_reason (ecs->ws.value.integer);
+       }
+      else
+       print_signal_exited_reason (ecs->ws.value.sig);
 
       gdb_flush (gdb_stdout);
       target_mourn_inferior ();
@@ -3396,35 +3441,17 @@ handle_inferior_event (struct execution_control_state *ecs)
       stop_stepping (ecs);
       return;
 
-    case TARGET_WAITKIND_SIGNALLED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SIGNALLED\n");
-      inferior_ptid = ecs->ptid;
-      set_current_inferior (find_inferior_pid (ptid_get_pid (ecs->ptid)));
-      set_current_program_space (current_inferior ()->pspace);
-      handle_vfork_child_exec_or_exit (0);
-      stop_print_frame = 0;
-      target_terminal_ours (); /* Must do this before mourn anyway.  */
-
-      /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't
-         reach here unless the inferior is dead.  However, for years
-         target_kill() was called here, which hints that fatal signals aren't
-         really fatal on some systems.  If that's true, then some changes
-         may be needed.  */
-      target_mourn_inferior ();
-
-      print_signal_exited_reason (ecs->ws.value.sig);
-      singlestep_breakpoints_inserted_p = 0;
-      cancel_single_step_breakpoints ();
-      stop_stepping (ecs);
-      return;
-
       /* The following are the only cases in which we keep going;
          the above cases end in a continue or goto.  */
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
       if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
+       {
+         if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
+           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
+         else
+           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_VFORKED\n");
+       }
 
       /* Check whether the inferior is displaced stepping.  */
       {
@@ -3497,11 +3524,9 @@ handle_inferior_event (struct execution_control_state *ecs)
         vfork follow are detached.  */
       if (ecs->ws.kind != TARGET_WAITKIND_VFORKED)
        {
-         int child_pid = ptid_get_pid (ecs->ws.value.related_pid);
-
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (child_pid);
+         detach_breakpoints (ecs->ws.value.related_pid);
        }
 
       if (singlestep_breakpoints_inserted_p)
@@ -3758,7 +3783,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
          context_switch (saved_singlestep_ptid);
          if (deprecated_context_hook)
-           deprecated_context_hook (pid_to_thread_id (ecs->ptid));
+           deprecated_context_hook (pid_to_thread_id (saved_singlestep_ptid));
 
          resume (1, GDB_SIGNAL_0);
          prepare_to_wait (ecs);
@@ -4904,14 +4929,22 @@ process_event_stop_test:
 
          if (execution_direction == EXEC_REVERSE)
            {
-             struct symtab_and_line sr_sal;
-
-             /* Normal function call return (static or dynamic).  */
-             init_sal (&sr_sal);
-             sr_sal.pc = ecs->stop_func_start;
-             sr_sal.pspace = get_frame_program_space (frame);
-             insert_step_resume_breakpoint_at_sal (gdbarch,
-                                                   sr_sal, null_frame_id);
+             /* If we're already at the start of the function, we've either
+                just stepped backward into a single instruction function,
+                or stepped back out of a signal handler to the first instruction
+                of the function.  Just keep going, which will single-step back
+                to the caller.  */
+             if (ecs->stop_func_start != stop_pc)
+               {
+                 struct symtab_and_line sr_sal;
+
+                 /* Normal function call return (static or dynamic).  */
+                 init_sal (&sr_sal);
+                 sr_sal.pc = ecs->stop_func_start;
+                 sr_sal.pspace = get_frame_program_space (frame);
+                 insert_step_resume_breakpoint_at_sal (gdbarch,
+                                                       sr_sal, null_frame_id);
+               }
            }
          else
            insert_step_resume_breakpoint_at_caller (frame);
@@ -4981,15 +5014,23 @@ process_event_stop_test:
 
       if (execution_direction == EXEC_REVERSE)
        {
-         /* Set a breakpoint at callee's start address.
-            From there we can step once and be back in the caller.  */
-         struct symtab_and_line sr_sal;
+         /* If we're already at the start of the function, we've either just
+            stepped backward into a single instruction function without line
+            number info, or stepped back out of a signal handler to the first
+            instruction of the function without line number info.  Just keep
+            going, which will single-step back to the caller.  */
+         if (ecs->stop_func_start != stop_pc)
+           {
+             /* Set a breakpoint at callee's start address.
+                From there we can step once and be back in the caller.  */
+             struct symtab_and_line sr_sal;
 
-         init_sal (&sr_sal);
-         sr_sal.pc = ecs->stop_func_start;
-         sr_sal.pspace = get_frame_program_space (frame);
-         insert_step_resume_breakpoint_at_sal (gdbarch,
-                                               sr_sal, null_frame_id);
+             init_sal (&sr_sal);
+             sr_sal.pc = ecs->stop_func_start;
+             sr_sal.pspace = get_frame_program_space (frame);
+             insert_step_resume_breakpoint_at_sal (gdbarch,
+                                                   sr_sal, null_frame_id);
+           }
        }
       else
        /* Set a breakpoint at callee's return address (the address
@@ -6763,11 +6804,10 @@ restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
   if (inf_state->siginfo_gdbarch == gdbarch)
     {
       struct type *type = gdbarch_get_siginfo_type (gdbarch);
-      size_t len = TYPE_LENGTH (type);
 
       /* Errors ignored.  */
       target_write (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
-                   inf_state->siginfo_data, 0, len);
+                   inf_state->siginfo_data, 0, TYPE_LENGTH (type));
     }
 
   /* The inferior can be gone if the user types "print exit(0)"
@@ -7098,21 +7138,31 @@ Specify a signal as argument to print info on that signal only."));
   add_info_alias ("handle", "signals", 0);
 
   c = add_com ("handle", class_run, handle_command, _("\
-Specify how to handle a signal.\n\
+Specify how to handle signals.\n\
+Usage: handle SIGNAL [ACTIONS]\n\
 Args are signals and actions to apply to those signals.\n\
+If no actions are specified, the current settings for the specified signals\n\
+will be displayed instead.\n\
+\n\
 Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
 from 1-15 are allowed for compatibility with old versions of GDB.\n\
 Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
 The special arg \"all\" is recognized to mean all signals except those\n\
 used by the debugger, typically SIGTRAP and SIGINT.\n\
+\n\
 Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
 \"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
 Stop means reenter debugger if this signal happens (implies print).\n\
 Print means print a message if this signal happens.\n\
 Pass means let program see this signal; otherwise program doesn't know.\n\
 Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
-Pass and Stop may be combined."));
+Pass and Stop may be combined.\n\
+\n\
+Multiple signals may be specified.  Signal numbers and signal names\n\
+may be interspersed with actions, with the actions being performed for\n\
+all signals cumulatively specified."));
   set_cmd_completer (c, handle_completer);
+
   if (xdb_commands)
     {
       add_com ("lz", class_info, signals_info, _("\
This page took 0.027206 seconds and 4 git commands to generate.