【问题标题】:How to resolve this segmentation fault in my program with the following Address Sanitizer output?如何使用以下 Address Sanitizer 输出解决我的程序中的分段错误?
【发布时间】:2016-04-06 10:53:36
【问题描述】:

这个问题是我上一个问题的续集,目前的状态是我已经获得了地址消毒剂的输出——由@Employed Russian 建议——如下所示。这是我第一次使用地址消毒剂,请原谅我的幼稚。

==2596== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff89d67fd0 at pc 0x401f21 bp 0x7fff89d67d00 sp 0x7fff89d67cf8
READ of size 4 at 0x7fff89d67fd0 thread T0
    #0 0x401f20 (/home/ubuntu/tp+0x401f20)
    #1 0x405bac (/home/ubuntu/tp+0x405bac)
    #2 0x406d40 (/home/ubuntu/tp+0x406d40)
    #3 0x7fb5a7d6fec4 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21ec4)
    #4 0x401278 (/home/ubuntu/tp+0x401278)
Address 0x7fff89d67fd0 is located at offset 320 in frame <TMV_multiplication> of T0's stack:
This frame has 13 object(s):
   [32, 60) 'A11_Upper_matrix'
   [96, 124) 'A_Upper_matrix'
   [160, 192) 'A11_Lower_matrix'
   [224, 256) 'A_Lower_matrix'
   [288, 320) 'VecA'
   [352, 384) 'VecB'
   [416, 448) 'VecC'
   [480, 536) 'result_A_Upper'
   [576, 632) 'result_C_Upper'
   [672, 732) 'matrix_A21'
   [768, 832) 'result_A_Lower'
   [864, 928) 'result_B'
   [960, 1024) 'result_C_Lower'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
  (longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
0x1000713a4fa0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x1000713a4fb0: 00 00 f4 f4 f2 f2 f2 f2 00 00 00 04 f2 f2 f2 f2
0x1000713a4fc0: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
0x1000713a4fd0: 00 00 f1 f1 f1 f1 00 00 00 04 f2 f2 f2 f2 00 00
0x1000713a4fe0: 00 04 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00
=>0x1000713a4ff0: 00 00 f2 f2 f2 f2 00 00 00 00[f2]f2 f2 f2 00 00
0x1000713a5000: 00 00 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00
0x1000713a5010: 00 00 00 00 00 f4 f2 f2 f2 f2 00 00 00 00 00 00
0x1000713a5020: 00 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 04 f2 f2
0x1000713a5030: f2 f2 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00
0x1000713a5040: 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 00 00 00
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
   Heap righ redzone:     fb
   Freed Heap region:     fd
   Stack left redzone:    f1
   Stack mid redzone:     f2
   Stack right redzone:   f3
   Stack partial redzone: f4
   Stack after return:    f5
   Stack use after scope: f8
   Global redzone:        f9
   Global init order:     f6
   Poisoned by user:      f7
   ASan internal:         fe
==2596== ABORTING

正如@Employed Russian 之前指出的,问题很可能出在堆栈上。现在,如何解决这个堆栈问题?因为这些都超出了我的想象。

【问题讨论】:

  • 作为一个一直讨厌 GDB 的人,你能给我们看看代码吗?
  • 你能指出哪一行导致了段错误吗?你在哪里找到 X[16] = Y[0] 等等?
  • 如果问题(超出数组限制的访问?)在程序的另一个点(UT()?LT()? )。您应该向我们展示一个完整的(带有main()UT()LT())和分段错误示例。
  • @user110219 对于调试问题,您需要创建一个Minimal, Complete, Verifiable Example 第一步是确定故障发生的位置。毫无疑问,GDB 很难使用,IDE 或许可以帮助您,但要让stackoverflow.com 对您有所帮助,您需要将其放入 MCVE。
  • 需要查看TW的代码。很有可能它(或它调用的东西)正在写入超出m_A21 数组的末尾,这将破坏func 的堆栈帧。

标签: gcc segmentation-fault gdb g++ sanitizer


【解决方案1】:

我在main 中有三个无符号整数数组X[16], Y[16], Z[16]...
X[32]=Z[0]

你可以在这里停下

访问X 的有效索引为0 到15。当您访问X[16](及以上)时,您正在调用未定义的行为(任何事情都可能发生)。

认为您实际上并不是指您分配给X[32]。您可能的意思是&amp;X[32]&amp;Z[0] 相同。如果是这样的话,就没有什么特别有趣的了:数组在内存中一个接一个地布局。

0x000000008304ed6a in ?? ()

这通常意味着堆栈损坏(某些东西覆盖了返回地址,并且您返回到了不知名的地方)。假设X 是一个本地 数组,越界写入它极有可能导致这种损坏。

查找此类堆栈损坏的一种简单方法是使用 Address Sanitizer(适用于 Clang 和 GCC)。

更新:

Address Sanitizer 错误告诉您

  • TMV_multiplication() 中,您有一个32 字节的本地数组VecA(可能是int VecA[8];)和
  • 您越界访问(读取)该数组(试图访问偏移量 320,该偏移量刚好超过该数组的末尾)。

此错误不是导致您崩溃的原因。您应该修复它,然后重新运行。在这个之后还有更多的错误。全部修复后,您的程序将停止崩溃。

【讨论】:

  • 是的,你是对的,我对编译器如何管理内存中的数组不感兴趣。我已经为我的程序获得了 Address Sanitizer 的输出,根据我天真的解释,它显示堆栈错误是堆栈左红区、堆栈右红区、堆栈中间红区和堆栈部分红区。堆栈中间红区的数量最多。那么接下来该怎么做呢?
  • “接下来要做什么?” -- 编辑您的问题并显示 Address Sanitizer 输出。
  • 抱歉迟到了,问题已修改。
【解决方案2】:

感谢地址清理器的输出,但为什么你删除了源?

无论如何,如果我没记错的话,输出会告诉你VecA[8] 中有一个访问权限,超出范围。

【讨论】:

  • 我已经删除了源代码,因为它使帖子很长。那么,您是如何从地址清理器中发现 VecA[8] 中存在超出范围的访问权限的?
  • 我确信我没有在我的源代码中进行超出范围的访问。那么哪里出了问题呢?
  • 我认为这是对VecA[8] 的访问,因为我读过READ of size 4 at 0x7fff89d67fd0,然后是Address 0x7fff89d67fd0 is located at offset 320 in frame [...][288, 320) 'VecA'。所以VecA[0] 在帧位置 288,VecA[1] 在位置 292,[...],VecA[8] 在位置 320。我不知道你的代码有什么问题,如果你应该提供你的完整代码您希望我们尝试回答您的问题。
猜你喜欢
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 2019-05-30
  • 2020-03-13
  • 2021-06-26
相关资源
最近更新 更多