Bug 30315 - GDB not showing variable that is supposed to be there
Summary: GDB not showing variable that is supposed to be there
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 13.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-04-05 13:39 UTC by LU Hongyi
Modified: 2024-01-20 16:34 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2023-04-05 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description LU Hongyi 2023-04-05 13:39:26 UTC
Given the following code:

#include "stdint.h"
#include "string.h"
#include <stdio.h>
int a, b;
char* c;
static int func_1() {
  int i = 0;
  for (; i < 4; i++)
    ;
  for (; a <= 4;) {
    uint16_t d;
    b = 0;
    return b;
    { int i; }
  }
  return b;
}
int main() {
  func_1();
  printf(c);
}

Compiled with gcc 12.2.0 and -O1 -g

The DWARF says that i persists until func_1 exits

Breakpoint 1, func_1 () at r.c:10
10        for (; a <= 4;) {
(gdb) info addr i
Symbol "i" is multi-location:
  Range 0x40112a-0x40112a: the constant 0
  Range 0x40112a-0x40112a: the constant 1
  Range 0x40112a-0x40112a: the constant 2
  Range 0x40112a-0x40112a: the constant 3
  Range 0x40112a-0x40113d: the constant 4
.
(gdb) p i
$1 = 4

But GDB says i is <optimized out> prematurely at line 12 with $pc = 0x401133 still in the range of func_1

(gdb) p i
$2 = <optimized out>
(gdb) p $pc
$3 = (void (*)()) 0x401133 <main+13>
(gdb)
Comment 1 Tom Tromey 2023-04-05 14:36:33 UTC
It's picking up that second 'i' somehow here.
It isn't obvious why, though, as that variable and
its block don't seem to be referenced at all.
Comment 2 Hannes Domani 2024-01-20 16:19:39 UTC
I've debugged it to this location of read_lexical_block_scope in dwarf2/read.c:
```
    case PC_BOUNDS_NOT_PRESENT:
      /* DW_TAG_lexical_block has no attributes, process its children as if
	 there was no wrapping by that DW_TAG_lexical_block.
	 GCC does no longer produces such DWARF since GCC r224161.  */
```
The inner { int i; } block is optimized away, and apparently gcc produces
this kind of block here in this case.
Which means gdb moves up the i variable to the for{} block, and that's why
it's found by print.
As a test I've just put a return in this case block, then gdb found the
correct i also in this location:
```
(gdb) n
12          b = 0;
(gdb) p i
$2 = 4
(gdb) info addr i
Symbol "i" is multi-location:
  Base address 0x140001609  Range 0x13f2e1609-0x13f2e1609: the constant 0
  Range 0x13f2e1609-0x13f2e1609: the constant 1
  Range 0x13f2e1609-0x13f2e1609: the constant 2
  Range 0x13f2e1609-0x13f2e1609: the constant 3
  Range 0x13f2e1609-0x13f2e161c: the constant 4
```

I'm not sure what the correct solution here is.
Comment 3 Hannes Domani 2024-01-20 16:34:53 UTC
(In reply to Hannes Domani from comment #2)
> I've debugged it to this location of read_lexical_block_scope in
> dwarf2/read.c:
> ```
>     case PC_BOUNDS_NOT_PRESENT:
>       /* DW_TAG_lexical_block has no attributes, process its children as if
> 	 there was no wrapping by that DW_TAG_lexical_block.
> 	 GCC does no longer produces such DWARF since GCC r224161.  */
> ```

This was added for PR15231.