GDB 中的 C99 可变长度数组

C99 Variable length arrays in GDB

在这个简单的 C99 代码中:

int main(void){
  int a[3][3] = {1};
  int m = 3;
  int x;
  int b[m][m];
  x = sizeof(b);
  b[0][0] = -1;
  return 0;
}

对于 GDB,我们在 return 行和 运行 处设置了一个断点。现在让我们看看以下内容:

(gdb) p a
 = {{1, 0, 0}, {0, 0, 0}, {0, 0, 0}}
(gdb) p b
 = 0x7fffffffe3a0
(gdb) p sizeof(a)
 = 36
(gdb) p sizeof(b)
 = 0
(gdb) p x
 = 36
(gdb) whatis a
type = int [3][3]
(gdb) whatis b
type = int [][]
(gdb) 

我想知道这是怎么发生的。 C运行time环境假设b的类型是int [3][3](因为sizeof(b)是36),但是GDB不是

最明显的解释是您已经进入 main,但显然还没有达到 VLA 声明。

为了解决这个问题,C11 (N1570) §6.2.4/7 对象的存储持续时间 指出(强调我的):

For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.35)

补救措施是进入 VLA 的声明(使用 gcc 4.4.7 和 gdb 7.2 测试):

Breakpoint 1, main () at so.c:1
1   int main(void){
(gdb) s
2     int a[3][3] = {1};
(gdb) s
3     int m = 3;
(gdb) s
5     int b[m][m];
(gdb) s
6     x = sizeof(b);
(gdb) p b
 = {{-1207961984, 0, 1114472}, {6381016, 6319652, -1073745804}, {6416216, 14, 129100401}}
gdb) whatis b
type = int [variable][variable]

这也可能是 gdb 版本之间的差异或某种错误,尽管后者始终是最后要考虑的事情。

编辑:

我已经从 source 构建了 gdb 7.7(CentOS 6.8 32 位),它显示 b 的地址而不是数组内容,所以我确认问题出在这个特定版本上,并且认为它有潜在的错误或功能不当。

另一方面,最新版本 7.11 运行正常。

GDB 7.7

[grzegorz@centos workspace]$ gdb-7.7/gdb/gdb -q a.out 
Reading symbols from a.out...done.
(gdb) b main
Breakpoint 1 at 0x80483ab: file so.c, line 1.
(gdb) r
Starting program: /home/grzegorz/workspace/a.out 

Breakpoint 1, main () at so.c:1
1   int main(void){
(gdb) s
2     int a[3][3] = {1};
(gdb) s
3     int m = 3;
(gdb) 
5     int b[m][m];
(gdb) 
6     x = sizeof(b);
(gdb) p b
 = 0xbffff0c0

GDB 7.11

[grzegorz@centos workspace]$ gdb-7.11/gdb/gdb -q a.out 
Reading symbols from a.out...done.
(gdb) b main
Breakpoint 1 at 0x80483ab: file so.c, line 1.
(gdb) r
Starting program: /home/grzegorz/workspace/a.out 

Breakpoint 1, main () at so.c:1
1   int main(void){
(gdb) s
2     int a[3][3] = {1};
(gdb) 
3     int m = 3;
(gdb) 
5     int b[m][m];
(gdb) 
6     x = sizeof(b);
(gdb) p b
 = {{-1207961984, 0, 1114472}, {6381016, 6319652, -1073745676}, {6416216, 14, 129100401}}

道德故事:升级或降级 gdb 版本以获得正确的行为