[英]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,我们在返回行上设置一个断点并运行。 现在让我们看以下内容:
(gdb) p a
$1 = {{1, 0, 0}, {0, 0, 0}, {0, 0, 0}}
(gdb) p b
$2 = 0x7fffffffe3a0
(gdb) p sizeof(a)
$3 = 36
(gdb) p sizeof(b)
$4 = 0
(gdb) p x
$5 = 36
(gdb) whatis a
type = int [3][3]
(gdb) whatis b
type = int [][]
(gdb)
我不知道这是怎么发生的。 C运行时环境假定b的类型为int [3][3]
(因为sizeof(b)
为36),但GDB则不然。
最明显的解释是您已进入main
,但显然尚未达到VLA声明。
为了解决这个问题,C11(N1570)§6.2.4/ 7 对象的存储持续时间规定(强调我的):
对于确实具有可变长度数组类型的对象,其生存期从对象的声明开始 ,直到程序执行离开声明的范围为止(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
$5 = {{-1207961984, 0, 1114472}, {6381016, 6319652, -1073745804}, {6416216, 14, 129100401}}
gdb) whatis b
type = int [variable][variable]
这可能也是gdb
版本之间的差异或某种错误,尽管后者始终是最后要考虑的问题。
编辑:
我已经从源代码构建了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
$1 = 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
$1 = {{-1207961984, 0, 1114472}, {6381016, 6319652, -1073745676}, {6416216, 14, 129100401}}
道德故事:升级或降级gdb
版本以获得正确的行为
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.