简体   繁体   English

AddressSanitizer:特定输入的 heap-use-after-free 错误

[英]AddressSanitizer: heap-use-after-free error for particular input

Problem Link: https://leetcode.com/problems/partition-list问题链接: https ://leetcode.com/problems/partition-list

Solution:解决方案:

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode *dummy = new ListNode(-1, head);
        ListNode *traverse = dummy->next, *left = dummy, *prev = dummy;
        while (traverse) {
            auto cacheNext = traverse->next;
            if (traverse->val < x) {
                prev->next = prev->next->next;
                // insert in left
                traverse->next = left->next;
                left->next = traverse;
                left = left->next;
            } else prev = traverse;
            traverse = cacheNext;
        }
        return dummy->next;
    }
};

This is giving AddressSanitizer: heap-use-after-free error for this specific input.这给出了AddressSanitizer: heap-use-after-free error ,用于此特定输入。

[1,1]
2

Other inputs like below are working fine,像下面这样的其他输入工作正常,

[1,4,3,2,5,2]
3

[1,2]
2

What things to keep in mind to avoid such errors?避免此类错误需要注意哪些事项? How to debug use after free error ? use after free error

In your example, I don't see any "free" in in the code so you're probably aliasing two pointers to occupy the same memory.在您的示例中,我在代码中看不到任何“空闲”,因此您可能将两个指针混叠以占用相同的内存。 When the calling code tries to delete the list, deleting a node causes access to deleted memory since the node points to the same adress a previous pointer was pointing.当调用代码试图删除列表时,删除一个节点会导致访问已删除的内存,因为该节点指向的地址与前一个指针指向的地址相同。

You will also have a memory leak, since you allocate a dummy node and return dummy->next .您还会有内存泄漏,因为您分配了一个虚拟节点并返回dummy->next The caller has no way of successfully deleting the list they receive since the new head node is not actually the head.调用者无法成功删除他们收到的列表,因为新的head节点实际上不是头。

In a very simple example that causes use after free errors, like:在一个非常简单的示例中,它会导致在释放错误后使用,例如:

int main ()
{
    auto p = new int(3);
    delete p;
    std::cout << *p << std::endl; 
}

You'll see that the address sanitizer report, provided you compile with the -g option, gives two pieces of information:如果您使用-g选项进行编译,您将看到地址清理程序报告提供了两条信息:

  1. Where the memory was free'd ("freed by thread T0 here:" below)内存被释放的地方(“由线程 T0 释放:”下面)
  2. Where the memory was allocated ("previously allocated by thread T0 here")分配内存的位置(“此处之前由线程 T0 分配”)
=================================================================
==7162==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000010 at pc 0x000000400e77 bp 0x7ffc5d4fe560 sp 0x7ffc5d4fe558
READ of size 4 at 0x602000000010 thread T0
    #0 0x400e76 in main /tmp/1658572799.3164601/main.cpp:7
    #1 0x7f0f2b9d982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #2 0x400f48 in _start (/tmp/1658572799.3164601/a.out+0x400f48)

0x602000000010 is located 0 bytes inside of 4-byte region [0x602000000010,0x602000000014)
freed by thread T0 here:
    #0 0x7f0f2c9a8658 in operator delete(void*, unsigned long) (/usr/local/lib64/libasan.so.8+0xb7658)
    #1 0x400d2f in main /tmp/1658572799.3164601/main.cpp:6

previously allocated by thread T0 here:
    #0 0x7f0f2c9a7758 in operator new(unsigned long) (/usr/local/lib64/libasan.so.8+0xb6758)
    #1 0x400d1f in main /tmp/1658572799.3164601/main.cpp:5

SUMMARY: AddressSanitizer: heap-use-after-free /tmp/1658572799.3164601/main.cpp:7 in main
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[fd]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: 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
==7162==ABORTING

The same report starts by mentioning the "offending line" and the instruction it was executing there:同一份报告首先提到了“违规行”和它在那里执行的指令:

=================================================================
==7162==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000010 at pc 0x000000400e77 bp 0x7ffc5d4fe560 sp 0x7ffc5d4fe558
READ of size 4 at 0x602000000010 thread T0
    #0 0x400e76 in main /tmp/1658572799.3164601/main.cpp:7
    #1 0x7f0f2b9d982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #2 0x400f48 in _start (/tmp/1658572799.3164601/a.out+0x400f48)

So the process of debugging is simple:所以调试的过程很简单:

  1. Check where you use after free免费后检查您在哪里使用
  2. Make sure that the "free" command doesn't happen unless you don't use the memory any-more确保“free”命令不会发生,除非您不再使用内存

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 可变内容导致 AddressSanitizer: heap-use-after-free on address - Variadic content leads to AddressSanitizer: heap-use-after-free on address AddressSanitizer 识别 std::vector<t> ::push_back 作为 heap-use-after-free 错误的原因</t> - AddressSanitizer identifies std::vector<T>::push_back as reason for heap-use-after-free error BST释放后使用堆错误中的删除节点 - Delete Node in BST heap-use-after-free error address sanitizer 有时会错过 heap-use-after-free - address sanitizer sometimes misses heap-use-after-free C++ [heap-use-after-free error] 引用和 push_back 到 vector - C++ [heap-use-after-free error] with referencing and push_back to vector 将变量声明为引用时的堆使用后释放 - heap-use-after-free when declaring a variable as a reference 这是我为添加二进制 leet 代码而制作的程序,显示运行时错误:heap-use-after-free on adress - this is a program i made for adding binary leet code is showing an error that is runtime error:heap-use-after-free on adress ASan:在递归 function 中的 vector.emplace(push)_back 之后的堆使用后释放 - ASan: heap-use-after-free after vector.emplace(push)_back in a recursive function 在 C++ 中使用带有 2D 向量的引用时,堆使用后释放 - heap-use-after-free when using references with 2D vector in C++ ASAN:将二叉树展平到链接列表时释放后使用堆 - ASAN: heap-use-after-free when flattening a binary tree to a linked list
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM