简体   繁体   中英

C99 Variable length arrays in GDB

At this simple C99-Code:

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;
}

with GDB we set a breakpoint at the return line and run. Now let's look at the following:

(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) 

I wonder how this does happen. The C runtime environment assumes that the type of b is int [3][3] (because sizeof(b) is 36), but GDB does not.

The most obvious explanation would be that you have entered into main , but apparently have not reached VLA declaration.

To cover this, the C11 (N1570) §6.2.4/7 Storage durations of objects states that (emphasis mine):

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)

The remedy is to step up into the declaration of VLA (tested with gcc 4.4.7 and 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]

It may be also a discrepancy between gdb versions or some sort of bug, though the latter is always the last thing to consider.

EDIT:

I have build gdb 7.7 (CentOS 6.8 32-bit) from source and it displays the address of b instead of array content, so I confirm that issue is with this specific version and consider it has a potential bug or misfeature.

On the other hand, the latest version 7.11 behaves correctly.

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}}

Moral story: Either upgrade or downgrade your version of gdb to get correct behaviour

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM