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
版本以获得正确的行为
在这个简单的 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
版本以获得正确的行为