AddressSanitizer,这些术语是什么意思?

AddressSanitizer, What do these terms mean?

所以我正在使用 AddressSanitizer。但是它在描述问题时使用了一些密集的术语。

Shadow bytes around the buggy address:
  0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 00[fa]fa 00 00 00 fa fa fa 00 00
  0x0c067fff8010: 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7320==ABORTING

Heap left redzone是什么意思? (还有其他人,但我最感兴趣的是 fa,因为有一个 [fa] 可能表明问题所在?)

What does Heap left redzone mean?

当 AddressSanitizer 堆插入器分配堆内存以响应类似以下内容时:

char *p = malloc(5);

它分配的内存比您要求的多。假设它在地址 q 分配了 32 个字节。然后它将前 16 个字节(区域 [q, q+15])标记为不可访问的堆左侧红色区域(fa),接下来的 5 个字节标记为可寻址(0),接下来的 11 个字节标记为堆右红区(fb).

最后它将 return 的 q+16 分配给应用程序(分配给 p)。

现在,如果应用程序尝试从 p-1p-2、... p-15 读取或写入,所有此类尝试都会被检测到,因为它们都将落在左侧红色区域。这是堆下溢。

类似地,将检测到访问 p+5p+6、... p+10(堆溢出)的尝试,因为它们都将落在正确的红色区域。

为什么应用程序会出现堆下溢?考虑这段代码:

int idx = get_valid_index(...);  // return -1 on failure
...
if (p[idx] == ...) {   // BUG: forgot to check idx!=-1

这实际上比您想象的更频繁地发生,并且似乎已经发生在您身上。