]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb] Notice when stepping into different file
authorTom de Vries <tdevries@suse.de>
Mon, 5 Aug 2024 12:00:42 +0000 (14:00 +0200)
committerTom de Vries <tdevries@suse.de>
Mon, 5 Aug 2024 12:00:42 +0000 (14:00 +0200)
Consider the following test-case:
...
$ cat -n test.c
     1 int var;
     2
     3 int
     4 foo (void)
     5 {
     6   var = 1;
     7 #include "test.h"
     8 }
     9
    10 int
    11 main ()
    12 {
    13   return foo ();
    14 }
$ cat -n test.h
     1   return 1;
$ gcc test.c -g
...

When stepping through the test-case, gdb doesn't make it explicit that line 1
is not in test.c:
...
Temporary breakpoint 1, main () at test.c:13
13   return foo ();
(gdb) step
foo () at test.c:6
6   var = 1;
(gdb) n
1   return 1;
(gdb)
8 }
(gdb)
...
which makes it easy to misinterpret the output.

This is with the default "print frame-info" == auto, with documented
behaviour [1]:
...
stepi will switch between source-line and source-and-location depending on the
program counter.
...

What is actually implemented is that source-line is used unless stepping into
or out of a function.

The problem can be worked around by using
"set print frame-info source-and-location", but that's a bit verbose.

Instead, change the behaviour of "print frame-info" == auto to also use
source-and-location when stepping into another file, which gets us:
...
(gdb) n
foo () at test.h:1
1   return 1;
...

Tested on x86_64-linux.

Reviewed-By: Kevin Buettner <kevinb@redhat.com>
Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
PR gdb/32011
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32011

[1] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Print-Settings.html#index-set-print-frame_002dinfo

gdb/infrun.c
gdb/testsuite/gdb.base/step-into-other-file.c [new file with mode: 0644]
gdb/testsuite/gdb.base/step-into-other-file.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/step-into-other-file.h [new file with mode: 0644]

index 06b454bf78f7340128873f95dc7f2d868e6f30dd..05e81a08e03df55f5c3150b30e7c70c361035de4 100644 (file)
@@ -9296,12 +9296,24 @@ print_stop_location (const target_waitstatus &ws)
          && (tp->control.step_start_function
              == find_pc_function (tp->stop_pc ())))
        {
-         /* Finished step, just print source line.  */
-         source_flag = SRC_LINE;
+         symtab_and_line sal = find_frame_sal (get_selected_frame (nullptr));
+         if (sal.symtab != tp->current_symtab)
+           {
+             /* Finished step in same frame but into different file, print
+                location and source line.  */
+             source_flag = SRC_AND_LOC;
+           }
+         else
+           {
+             /* Finished step in same frame and same file, just print source
+                line.  */
+             source_flag = SRC_LINE;
+           }
        }
       else
        {
-         /* Print location and source line.  */
+         /* Finished step into different frame, print location and source
+            line.  */
          source_flag = SRC_AND_LOC;
        }
       break;
diff --git a/gdb/testsuite/gdb.base/step-into-other-file.c b/gdb/testsuite/gdb.base/step-into-other-file.c
new file mode 100644 (file)
index 0000000..5ec7c33
--- /dev/null
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 Free Software Foundation, Inc.
+
+   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/>.  */
+
+int var;
+
+int
+foo (void)
+{
+  var = 1;
+#include "step-into-other-file.h"
+}
+
+int
+main ()
+{
+  return foo ();
+}
diff --git a/gdb/testsuite/gdb.base/step-into-other-file.exp b/gdb/testsuite/gdb.base/step-into-other-file.exp
new file mode 100644 (file)
index 0000000..f0e8c3f
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# 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/>.
+
+# Check that when stepping into another file, the file is shown.
+
+standard_testfile .c .h
+
+set flags {}
+lappend flags debug
+lappend_include_file flags $srcdir/$subdir/$srcfile2
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
+         $flags] == -1 } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test step $srcfile:$decimal\r\n.*
+
+# Regression test for PR32011.
+gdb_test next $srcfile2:$decimal\r\n.*
diff --git a/gdb/testsuite/gdb.base/step-into-other-file.h b/gdb/testsuite/gdb.base/step-into-other-file.h
new file mode 100644 (file)
index 0000000..60b4816
--- /dev/null
@@ -0,0 +1,18 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 Free Software Foundation, Inc.
+
+   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/>.  */
+
+  return 1;