[Bug exp/34201] New: [gdb/exp] Namespace variable not found when stopped at inlined function call

vries at gcc dot gnu.org sourceware-bugzilla@sourceware.org
Thu Jun 4 09:20:53 GMT 2026


https://sourceware.org/bugzilla/show_bug.cgi?id=34201

            Bug ID: 34201
           Summary: [gdb/exp] Namespace variable not found when stopped at
                    inlined function call
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: exp
          Assignee: unassigned at sourceware dot org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Consider test.c:
...
$ cat -n test.c
     1  namespace mod_a
     2  {
     3    int xxx = 10;
     4  }
     5  
     6  static inline int __attribute__((always_inline))
     7  inlined (void)
     8  {
     9    return 0;
    10  }
    11  
    12  static int
    13  not_inlined (void)
    14  {
    15    return 0 ;
    16  }
    17  
    18  int
    19  main (void)
    20  {
    21    int res1, res2;
    22    using namespace mod_a;
    23    res1 = not_inlined ();
    24    res2 = inlined ();
    25    return res1 + res2 + xxx;
    26  }
...

Compiled like this:
...
$ g++ test.c -g
...

The following debug session:
...
$ gdb -q -batch -iex "set trace-commands on" a.out \
    -ex start \
    -ex "p xxx" \
    -ex next \
    -ex "p xxx" \
    -ex "next" \
    -ex "p xxx"
+start
  ...
Temporary breakpoint 1, main () at test.c:23
23        res1 = not_inlined ();
+p xxx
$1 = 10
+next
24        res2 = inlined ();
+p xxx
No symbol "xxx" in current context.
+next
25        return res1 + res2 + xxx;
+p xxx
$2 = 10
...
shows that variable xxx unexpectedly disappears at line 24.

What happens is that using_direct::valid_line returns false for line 24, while
it returns true for the other two lines.

The relevant code in the function is this:
...
      CORE_ADDR curr_pc = get_frame_pc (get_selected_frame (nullptr));
      symtab_and_line curr_sal = find_sal_for_pc (curr_pc, 0);
      return (decl_line <= curr_sal.line)
             || (decl_line >= boundary);
...

As expected, the decl_line is 22, the line containing "using namespace mod_a":
...
(gdb) p decl_line
$1 = 22
...

Also as expected, the boundary line is 26, the last line of main:
...
(gdb) p boundary
$2 = 26
...

The problem is that curr_sal.line is not 24, but 9:
...
(gdb) p curr_sal.line
$3 = 9
...

This is sort of true, the current PC maps to that line.  It's just that gdb
steps into inlined functions in two steps, each with identical PC:
- once stopping at the call site (line 24 in this case)
- once stopping at the PC line (9 in this case)

The function using_direct::valid_line doesn't apply this logic, and
consequently line 9 is used for both cases.

Seems to be fixed by:
...
diff --git a/gdb/namespace.c b/gdb/namespace.c
index 5b5749369ee..fec5e5cf67d 100644
--- a/gdb/namespace.c
+++ b/gdb/namespace.c
@@ -111,8 +111,8 @@ using_direct::valid_line (unsigned int boundary) const
 {
   try
     {
-      CORE_ADDR curr_pc = get_frame_pc (get_selected_frame (nullptr));
-      symtab_and_line curr_sal = find_sal_for_pc (curr_pc, 0);
+      frame_info_ptr frame = get_selected_frame ();
+      symtab_and_line curr_sal = find_frame_sal (frame);
       return (decl_line <= curr_sal.line)
             || (decl_line >= boundary);
     }
...

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Gdb-prs mailing list