如何静态识别动态堆分配?

2024-03-23

我即将在我的应用程序中删除“尽可能多的”动态堆分配,我想知道如何确保我没有错过任何内容。

目前,我正在寻找一种方法来轻松甚至自动判断代码的任何(或哪些)部分可能会调用以下标准实现new/delete or malloc/free无需动态跟踪分配(即通过静态代码分析或来自编译器/链接器的反馈)。

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

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

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

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。如果我的代码(或第 3 方的东西)使用标准库,您将无法通过调用来检测它nm:

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

我当前的方法是链接到静态标准库(-static-libgcc / -static-libstdc++)并查看是否有引用new/delete at all在整个二进制文件中:

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

这种方法适用于小型二进制文件,您可以在其中设法拥有zero堆分配,但只要您允许some分配(例如,在仅执行一次的代码中或在错误情况下,因此很难将其分离的代码might分配堆内存和不会分配的东西。

在最好的情况下,我目前可以想象编译器或静态代码分析器为我提供源代码中的位置列表,这可能会导致动态堆分配。我可以定期检查/过滤此列表,以找出在我的设置中正常的情况(例如引导代码或错误处理)以及我必须重构的情况(例如通过提供特殊的分配器)。

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


一种策略可能是wrap https://stackoverflow.com/a/617606/10396使用您自己的函数调用 malloc/calloc,该函数决定是否允许它们,如果不允许则断言(或记录)。可以通过检查在初始化、错误处理程序等期间设置/清除的全局标志来做出决定。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何静态识别动态堆分配? 的相关文章

随机推荐

  • 节点模块是针对不同的节点模块编译的 67

    我有一个在节点模块版本 67 下编译的节点项目 但现在我收到一个错误 它需要节点模块版本 69 usb bindings node was compiled against a different Node js version using
  • 属性“use”在类型“typeof...”上不存在,属性“extend”在类型“typeof”上不存在

    我第一次使用 TypeScript 构建我的 vue 应用程序 但我一直坚持这个Property xxx does not exist on type typeof问题 我研究过类似的问题 但似乎没有一个有效 我在 vue 3 0 0 0
  • 无法编译 WordCount.java

    mark maestro1 usr lib hadoop wordcount classes javac classpath usr lib hadoop hadoop common 2 0 0 cdh4 0 1 jar usr lib h
  • Powershell:返回具有最大编号的文件名

    假设我有一个像这样的文件名列表 Get ChildItem Antarctica Data xls Antarctica Data 03625516 xls Antarctica Data 84327262 xls Antarctica D
  • AspectJ 编织 Maven 模块

    我有一个项目 有多个 Maven 模块 其中之一包含我的方面 我如何获取各个方面并编织多个 Maven 模块 AspectJ Maven 插件的文档有点稀疏 无法找到很多示例 我尝试将aspectj 插件放入父pom 中 但它似乎没有应用其
  • 如何将 Excel 工作簿写入 .NET 中的 MemoryStream?

    如何将 Excel 工作簿写入MemoryStream而不先将其保存到文件系统 内的所有选项Microsoft Office Interop Excel WorkBook保存选项采用文件名 我对 PIA 以及将 Excel 文件存储在文档存
  • “OneHotEncoder”对象没有属性“get_feature_names”

    我正在尝试使用 scikit learn 的 OneHotEncoder 对象的 get feature names 函数提取特征 但它向我抛出一个错误 OneHotEncoder 对象没有属性 get feature names 下面是代
  • 带/不带类的回调函数指针 C++

    我被困 我正在尝试形成一个函数 它将吃掉无类函数指针和对象中的函数指针 这是我当前的代码 希望能解释更多 它应该在 Arduino 上运行 所以我不能使用大型库 首先 我在 Arduino 上使用这个库 SimpleTimer A time
  • Flyway 仅在我的 jar 文件中找不到迁移

    我有类似的问题this https stackoverflow com questions 11226070 flyway not finding the migrations in a jar file但我已经迁移到版本 2 1 1 问题
  • 在应用程序和 Web 之间共享数据库

    我参与了一个必须从现有数据库检索查询的应用程序 该数据库必须在远程服务器中的 php 中实现 并且将是管理员必须将内容插入共享数据库的地方 但我不知道如何正确实现或什么是最佳解决方案 我正在考虑使用 php 创建一个 sqlite 数据库并
  • ld:找不到 -lIOKit.A clang xcode 的库

    我使用项目的 Target 部分将 libIOKit A dylib 库包含到我的 Xcode 项目中 如下图所示 该项目已构建并运行良好 我在编译状态中遇到一些有线错误 ld 找不到 lIOKit 的库 A clang 错误 链接器命令
  • 将 Entity Framework Data First 与 ODBC 和 MySQL 结合使用

    我怎样才能创建一个ADO NET 实体数据模型使用 ODBC 连接 MySQL 我在本地主机上安装了 MySQL 3 51 ODBC 驱动程序 并创建了一个测试 MySQL 数据库 然后使用 VS2013 我使用 ODBC 数据源创建到我的
  • 如何从函数中实时捕获打印内容?

    我想捕捉所有prints 并执行诸如返回它们之类的操作 但继续运行该函数 我找到了这个方法 但它只返回print代码完成后 f io StringIO with redirect stdout f my code return f getv
  • Lua:setfenv() 与 _ENV

    Lua 切换有什么大不了的setfenv to ENV 在各种 新增内容 资料中 这一举措被认为是 Lua 5 1 和 5 2 版本之间最重要的变化之一 但是 PIL 和其他地方给出的示例可以修剪为以下内容 Lua 5 1 Lua 5 2
  • 提交了我的 php 表单,但没有发送任何值

    由于某种原因 这些选项没有显示在我的电子邮件中 我可以很好地发送电子邮件 我可以看到正文及其所有评论 但看不到用户所做的任何条目 我知道我做错了什么 但我无法确定它是什么 另外 如果它看起来很糟糕 请随意嘲笑我 ToEmail email
  • 可以使用存储过程中的动态 SQL 创建 MySQL 触发器吗?

    是否可以使用从存储过程中动态生成的 SQL 在 MySQL 中创建触发器 我通过准备语句在过程中执行其他动态构造的查询 但是当我尝试使用相同的方法创建触发器时 出现以下错误 错误代码 1295 准备好的语句协议尚不支持此命令 From Bu
  • Grepping 查找重叠的模式匹配

    这就是我正在运行的 grep o tcb lt lt lt r t c q c b b 输出是 t b 但我想得到 t c b 我不希望匹配没有前面的 b 或没有后面的 c 因为 tcb 应该在 r t c q b b r t c q b
  • 连接的 Delphi 字符串是否保存在保留对该字符串的引用的隐藏临时变量中?

    我试图了解 Delphi 服务器应用程序中的内存问题 最初我怀疑存在彻底的泄漏 但现在相信我们看到内存挂起的时间比应有的时间长 因为编译器在用 动态连接字符串时使用了隐藏的临时值 导致痛苦的自由空间内存碎片 背景 这是 Windows 上的
  • git:为什么 git diff 没有显示任何差异?

    如果我在我的存储库上运行 git status 它会给出 On branch master Changes to be committed use git reset HEAD
  • 如何静态识别动态堆分配?

    我即将在我的应用程序中删除 尽可能多的 动态堆分配 我想知道如何确保我没有错过任何内容 目前 我正在寻找一种方法来轻松甚至自动判断代码的任何 或哪些 部分可能会调用以下标准实现new delete or malloc free无需动态跟踪分