* readelf.c (dynamic_info): Correct size of array.
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index a8ab1f0faf5511deed07c5e675287bc1d923adb1..53fb3b406971d691ccd2e993e42eeb36d59c72e2 100644 (file)
@@ -20,6 +20,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include <signal.h>
 #include "gdb_string.h"
 #include "symtab.h"
@@ -52,6 +53,7 @@
 #include "cli/cli-decode.h"
 #include "gdbthread.h"
 #include "valprint.h"
+#include "inline-frame.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -758,6 +760,17 @@ Can't resume all threads and specify proceed count simultaneously."));
   continue_1 (all_threads);
 }
 \f
+/* Record the starting point of a "step" or "next" command.  */
+
+static void
+set_step_frame (void)
+{
+  struct symtab_and_line sal;
+
+  find_frame_sal (get_current_frame (), &sal);
+  set_step_info (get_current_frame (), sal);
+}
+
 /* Step until outside of current statement.  */
 
 static void
@@ -831,7 +844,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
       if (in_thread_list (inferior_ptid))
        thread = pid_to_thread_id (inferior_ptid);
 
-      set_longjmp_breakpoint ();
+      set_longjmp_breakpoint (thread);
 
       make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
     }
@@ -926,7 +939,7 @@ step_1_continuation (void *args)
 static void
 step_once (int skip_subroutines, int single_inst, int count, int thread)
 {
-  struct frame_info *frame;
+  struct frame_info *frame = get_current_frame ();
 
   if (count > 0)
     {
@@ -936,23 +949,32 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
         THREAD is set.  */
       struct thread_info *tp = inferior_thread ();
       clear_proceed_status ();
-
-      frame = get_current_frame ();
-      tp->step_frame_id = get_frame_id (frame);
+      set_step_frame ();
 
       if (!single_inst)
        {
          CORE_ADDR pc;
 
+         /* Step at an inlined function behaves like "down".  */
+         if (!skip_subroutines && !single_inst
+             && inline_skipped_frames (inferior_ptid))
+           {
+             step_into_inline_frame (inferior_ptid);
+             if (count > 1)
+               step_once (skip_subroutines, single_inst, count - 1, thread);
+             else
+               /* Pretend that we've stopped.  */
+               normal_stop ();
+             return;
+           }
+
          pc = get_frame_pc (frame);
          find_pc_line_pc_range (pc,
                                 &tp->step_range_start, &tp->step_range_end);
 
          /* If we have no line info, switch to stepi mode.  */
          if (tp->step_range_end == 0 && step_stop_if_no_debug)
-           {
-             tp->step_range_start = tp->step_range_end = 1;
-           }
+           tp->step_range_start = tp->step_range_end = 1;
          else if (tp->step_range_end == 0)
            {
              char *name;
@@ -1008,6 +1030,7 @@ which has no line number information.\n"), name);
 static void
 jump_command (char *arg, int from_tty)
 {
+  struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR addr;
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
@@ -1077,7 +1100,7 @@ jump_command (char *arg, int from_tty)
   if (from_tty)
     {
       printf_filtered (_("Continuing at "));
-      fputs_filtered (paddress (addr), gdb_stdout);
+      fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
       printf_filtered (".\n");
     }
 
@@ -1188,6 +1211,7 @@ until_next_command (int from_tty)
   struct thread_info *tp = inferior_thread ();
 
   clear_proceed_status ();
+  set_step_frame ();
 
   frame = get_current_frame ();
 
@@ -1217,7 +1241,6 @@ until_next_command (int from_tty)
     }
 
   tp->step_over_calls = STEP_OVER_ALL;
-  tp->step_frame_id = get_frame_id (frame);
 
   tp->step_multi = 0;          /* Only one call to proceed */
 
@@ -1440,10 +1463,13 @@ finish_backward (struct symbol *function)
 
   if (sal.pc != pc)
     {
+      struct frame_info *frame = get_selected_frame (NULL);
+      struct gdbarch *gdbarch = get_frame_arch (frame);
+
       /* Set breakpoint and continue.  */
       breakpoint =
-       set_momentary_breakpoint (sal,
-                                 get_frame_id (get_selected_frame (NULL)),
+       set_momentary_breakpoint (gdbarch, sal,
+                                 get_stack_frame_id (frame),
                                  bp_breakpoint);
       /* Tell the breakpoint to keep quiet.  We won't be done
          until we've done another reverse single-step.  */
@@ -1472,6 +1498,7 @@ finish_backward (struct symbol *function)
 static void
 finish_forward (struct symbol *function, struct frame_info *frame)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   struct symtab_and_line sal;
   struct thread_info *tp = inferior_thread ();
   struct breakpoint *breakpoint;
@@ -1481,20 +1508,20 @@ finish_forward (struct symbol *function, struct frame_info *frame)
   sal = find_pc_line (get_frame_pc (frame), 0);
   sal.pc = get_frame_pc (frame);
 
-  breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame),
+  breakpoint = set_momentary_breakpoint (gdbarch, sal,
+                                        get_stack_frame_id (frame),
                                          bp_finish);
 
   old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
   tp->proceed_to_finish = 1;    /* We want stop_registers, please...  */
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
-
   cargs = xmalloc (sizeof (*cargs));
 
   cargs->breakpoint = breakpoint;
   cargs->function = function;
   add_continuation (tp, finish_command_continuation, cargs,
                     finish_command_continuation_free_arg);
+  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
 
   discard_cleanups (old_chain);
   if (!target_can_async_p ())
@@ -1544,6 +1571,36 @@ finish_command (char *arg, int from_tty)
 
   clear_proceed_status ();
 
+  /* Finishing from an inline frame is completely different.  We don't
+     try to show the "return value" - no way to locate it.  So we do
+     not need a completion.  */
+  if (get_frame_type (get_selected_frame (_("No selected frame.")))
+      == INLINE_FRAME)
+    {
+      /* Claim we are stepping in the calling frame.  An empty step
+        range means that we will stop once we aren't in a function
+        called by that frame.  We don't use the magic "1" value for
+        step_range_end, because then infrun will think this is nexti,
+        and not step over the rest of this inlined function call.  */
+      struct thread_info *tp = inferior_thread ();
+      struct symtab_and_line empty_sal;
+      init_sal (&empty_sal);
+      set_step_info (frame, empty_sal);
+      tp->step_range_start = tp->step_range_end = get_frame_pc (frame);
+      tp->step_over_calls = STEP_OVER_ALL;
+
+      /* Print info on the selected frame, including level number but not
+        source.  */
+      if (from_tty)
+       {
+         printf_filtered (_("Run till exit from "));
+         print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
+       }
+
+      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+      return;
+    }
+
   /* Find the function we will return from.  */
 
   function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
@@ -1599,7 +1656,8 @@ program_info (char *args, int from_tty)
   stat = bpstat_num (&bs, &num);
 
   target_files_info ();
-  printf_filtered (_("Program stopped at %s.\n"), paddress (stop_pc));
+  printf_filtered (_("Program stopped at %s.\n"),
+                  paddress (target_gdbarch, stop_pc));
   if (tp->stop_step)
     printf_filtered (_("It stopped after being stepped.\n"));
   else if (stat != 0)
@@ -2639,8 +2697,9 @@ fully linked executable files and separately compiled object files as needed."),
               &showlist);
   set_cmd_completer (c, noop_completer);
 
-  add_com ("kill", class_run, kill_command,
-          _("Kill execution of program being debugged."));
+  add_prefix_cmd ("kill", class_run, kill_command,
+                 _("Kill execution of program being debugged."),
+                 &killlist, "kill ", 0, &cmdlist);
 
   add_com ("attach", class_run, attach_command, _("\
 Attach to a process or file outside of GDB.\n\
This page took 0.027756 seconds and 4 git commands to generate.