debugging 调试:跟踪原始指针传播

abithluo  于 2023-02-19  发布在  其他
关注(0)|答案(1)|浏览(130)

我正在调试一个有heap-use-after-free问题的巨大遗留代码。地址清理器让我知道分配发生在代码的哪里,在哪里被释放以及之后在哪里使用,这非常有用。
为了调试,我需要跟踪这个错误的内存地址,即指针,以及它是如何通过代码从分配传播到错误使用的。它可能会被复制到其他一些变量(自由变量或类成员变量),最终导致错误使用。是否有任何方法可以使用调试器跟踪地址传播?
PS:我知道保存从分配返回的地址的起始指针变量(使用ASAN)。

baubqpgj

baubqpgj1#

在macOS下有所谓的lldb.macosx.heap脚本,它们在整个系统范围内可用,并为lldb提供额外的诊断手段。让我们假设您有这样一个极简的代码(其中相当多的指针指向int的一个已删除示例):

#include <iostream>

void func(int* var) {
    int* newPtr = var;
    std::cout << *newPtr << std::endl;
}

int main() {
    int* ptr = new int{2};
    delete ptr;
    int* ptr2 = ptr;
    func(ptr);
}

首先,在调试会话下,您需要加载这些工具:

(lldb) command script import lldb.macosx.heap
"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.

然后,假设你已经在std::cout行停止了执行,并且可以看到newPtr指向的地址(在我的例子中是0x000060000000c000),你可以打印所有其他指向同一地址的指针:

(lldb) ptr_refs 0x000060000000c000
0x00007ff7bfeff1f0: stack in frame #0 of thread #1: tid 0x14e058 in variable at 0x7ff7bfeff1f0:
    (int *) newPtr = 0x000060000000c000
0x00007ff7bfeff1f8: stack in frame #0 of thread #1: tid 0x14e058 in variable at 0x7ff7bfeff1f8:
    (int *) var = 0x000060000000c000
0x00007ff7bfeff210: stack in frame #1 of thread #1: tid 0x14e058
0x00007ff7bfeff218: stack in frame #1 of thread #1: tid 0x14e058 in variable at 0x7ff7bfeff218:
    (int *) ptr2 = 0x000060000000c000
0x00007ff7bfeff220: stack in frame #1 of thread #1: tid 0x14e058 in variable at 0x7ff7bfeff220:
    (int *) ptr = 0x000060000000c000

最后,在lldb下,您可以使用frame命令检查frame #1实际上是什么:

(lldb) frame select 1
frame #1: 0x0000000100003115 CPPPlayground`main at main.cpp:19:5
   16       int* ptr = new int{2};
   17       delete ptr;
   18       int* ptr2 = ptr;
-> 19       func(ptr);
            ^
   20   }
(lldb) frame info
frame #1: 0x0000000100003115 CPPPlayground`main at main.cpp:19:5

相关问题