如何静态识别动态堆分配? [英] How to statically identify dynamic heap allocation?

查看:169
本文介绍了如何静态识别动态堆分配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将在应用程序中删除尽可能多的动态堆分配,我想知道如何确保自己不会错过任何内容。

I'm about to remove "as many as possible" dynamic heap allocation in my application and I wonder how I can make sure I didn't miss anything.

当前,我正在寻找一种方法来轻松甚至自动判断代码的任何部分(或哪些部分)可能调用 new / <$ c的标准实现$ c>删除或 malloc / 免费,而无需动态跟踪分配(即通过静态代码分析或来自编译器/链接器的反馈)。

Currently I'm looking for a way to easily or even automatically tell, if any (or which) parts of the code might invoke the standard implementations of new/delete or malloc/free without having to dynamically trace allocations (i.e. via static code analysis or feedback from compiler/linker).

很容易发现(或搜索)直接调用 new malloc 当然:

It's easy to spot (or search for) code which directly calls new or malloc of course:

int main() {
  auto s = new std::string();
  delete s;
}

仅当分配隐藏在第3方库的深处或不太明显(例如 throw ),我仍然可以在二进制文件中搜索新的/删除的错误符号:

Just in case the allocations are hidden deep in a 3rd party library or in cases which are less obvious (like throw) I can still search for the mangled symbols for new/delete in my binary:

g++ main.cpp
nm a.out | grep -E "_Znwm|_Znam|_Znwj|_Znaj|_ZdlPv|_ZdaPv|malloc|free"
                 U _ZdlPvm@@CXXABI_1.3.9
                 U _Znwm@@GLIBCXX_3.4

但是这种方法只能找到<$> direct 对 new / delete / malloc / free的使用。如果我的代码(或第三方的东西)使用了标准库,则仅通过调用 nm 不会检测到它:

But this approach will only find direct uses of new/delete/malloc/free. In case my code (or 3rd party stuff) makes use of the standard library you won't detect it by just calling nm:

int main() {
    std::string a;
    for(int i = 0; i < 100; ++i) {
        a += "data ";
    }
}

我目前的方法是链接到静态标准库( -static-libgcc / -static-libstdc ++ ),看看是否有对 new的引用 / 删除 全部在整个二进制文件中:

My current approach is to link against static standard libraries (-static-libgcc / -static-libstdc++) and look if there's a reference to new/delete at all in the whole binary:

g++ -static-libgcc -static-libstdc++ main.cpp
nm a.out | grep -E "_Znwm|_Znam|_Znwj|_Znaj|_ZdlPv|_ZdaPv|malloc|free"
0000000000471fd0 T __cxa_free_dependent_exception
0000000000471f30 T __cxa_free_exception
                 U free@@GLIBC_2.2.5
                 U __freelocale@@GLIBC_2.2.5
                 U malloc@@GLIBC_2.2.5
0000000000471b20 T _ZdlPv
0000000000491bf0 T _ZdlPvm
0000000000471bc0 t _ZN12_GLOBAL__N_14pool4freeEPv.constprop.2
0000000000402a20 t _ZN12_GLOBAL__N_14pool4freeEPv.constprop.2.cold.5
0000000000471e80 T _ZN9__gnu_cxx9__freeresEv
0000000000472240 T _Znwm
0000000000491c00 T _ZnwmRKSt9nothrow_t
0000000000403f37 t _ZnwmRKSt9nothrow_t.cold.0

这种方法适用于小型二进制文件,在这些小型二进制文件中,您可以设法使堆分配,但是只要您允许一些分配(例如,在仅执行一次的代码中,或者在错误情况下,因此很难分离可能会执行的代码) 分配堆内存和不会分配的内存。

This approach works for small binaries where you can manage to have zero heap allocations but as soon as you want to allow some allocations (e.g. in code which gets executed only once or in error cases it becomes very difficult to consequently separate code which might allocate heap memory and the stuff which won't.

在最佳情况下,我目前可以想象编译器或静态代码分析器为我提供了一个列表我的源代码中的位置可能会导致动态堆分配。我可以定期检查/过滤此列表,以了解设置是否正常(例如引导程序代码或错误处理)以及需要重构的情况(例如通过提供特殊的分配器)。

In the best scenario I can currently imagine the compiler or a static code analyzer provides me with a list of locations in my source code which could result in dynamic heap allocations. This list I could regularly check/filter for cases which are OK in my setup (e.g. bootstrap code or error handling) and those where I have to refactor (e.g. by providing a special allocator).

您的方法,工具和经验是什么?

What are your approaches, tools, experiences?

推荐答案

一种策略可能是包装对malloc / calloc的调用,该函数将确定是否允许调用,如果没有则断言(或记录)。可以通过检查在初始化,错误处理程序等过程中设置/清除的全局标志来做出决定。

One strategy might be to wrap the calls to malloc/calloc with your own function which decides if they are allowed and asserts (or logs) if not. The decision can be made by checking a global flag which you set/clear during initialization, error handlers, etc.

这当然不是静态的,但是它可能是静态的可以作为清理代码的良好起点。

This is, of course, not static, but it might serve as a good starting point for sanitizing your code.

这篇关于如何静态识别动态堆分配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆