在运行时重新初始化全局/静态内存或全局/静态变量的静态分析

时间:2018-02-10 19:49:03

标签: c memory static initialization global

问题

我正在研究一个大型C项目(C99),它大量使用全局变量(我知道,我知道)。该程序运行良好,但最初设计为运行一次并退出。

因此,它依赖于它的全局/静态内存来初始化为0(或者声明它的任何值),并且在运行时它会修改这些变量(就像大多数程序那样)。

但是,我想要再次运行该程序,而不是在完成时退出。我想制作一个对这个大型程序具有控制和可见性的父程序。完全了解正在运行的程序非常重要。

该解决方案需要在macOS,Linux和Windows上运行。

我考虑过:

1。分叉

制作一个小包装程序,用作" shell",并根据需要执行大程序。

赞成

  • 操作系统完成了将内存重置为正确值的艰苦工作
  • 保证按预期运作

缺点

  • 失去对计划的了解
  • 在运行期间无法检查从包装器执行程序的内存,在启动之前更难调整设置,更难收集运行时信息
  • 需要实现一个系统来获取/退出程序的内部数据,可能涉及大量代码
  • 统一体验更加困难(共享GUI窗口等)

2。手动识别关键结构

仔细阅读源代码,多次运行程序,等待程序在完整性检查或内存访问不良时爆炸。

赞成

  • 易于操作
  • 易于启动
  • 高可见性,代码共享和统一

缺点

  • 没有抓住每一个案例,非常拼凑
  • 耗时

3。重构

将所有全局变量收集到memset的单个结构中,为使用值初始化的变量创建初始值设定项。根据具体情况处理静态。

赞成

  • 概念上容易,大锤的方法
  • 高可见性,代码共享和统一

缺点

  • 非常耗时,代码库很大,几乎可以触及所有内容

4。魔杖

告诉操作系统重新初始化全局/静态内存。如果我需要保存一个值,我会在本地存储它,然后在完成后重写它。

赞成

  • 非常完美:))

缺点

  • 不存在(?)
  • 非常黑魔法
  • 可能不是跨平台
  • 可能会激怒第三方库

我现在在做什么

我现在正在使用选项2,只是通过代码,依靠程序崩溃并指出我正确的方向。

我说这种方法让我大约80%的方式。我已经识别并重新初始化了足够多的东西,程序或多或少可以重新运行。它没有我想象的那么广泛,它给了我很大的希望。

偶尔会发生奇怪的事情,或者它没有按预期运行,但它也不会崩溃。这使得跟踪它变得更加困难。

我只需要一些能让我获得最后20%的东西。也许某种静态分析工具,或者某些东西可以帮助我查看源代码并查看全局变量的触摸位置。

1 个答案:

答案 0 :(得分:1)

要轻松检测全局变量和静态变量,可以尝试CppDepend并执行像这样的cqlinq查询

from f in Fields where f.IsGlobal || f.IsStatic
select f

如果您想要特定函数或特定文件中使用的变量,也可以修改查询。