问题
我正在开发一个大量使用全局变量的大型 C 项目 (C99)(我知道,我知道)。该程序运行良好,但最初设计为运行一次并退出。
因此,它依赖于用 0(或它声明的任何值)初始化它的全局/静态内存,并且在运行时它会修改这些变量(就像大多数程序所做的那样)。
但是,我不想在完成时退出,而是想再次运行该程序。我想制作一个对这个大型程序具有控制权和可见性的父程序。全面了解正在运行的程序非常重要。
该解决方案需要在 macOS、Linux 和 Windows 上运行。
我考虑过:
1。 fork 它
制作一个作为“外壳”的小包装程序,并根据需要执行大程序。
优点
- 操作系统会努力将内存重置为正确的值
- 保证按预期运行
缺点
- 失去对计划的了解
- 无法在运行时检查包装器执行程序的内存,启动前更难调整设置,更难收集运行时信息
- 需要实现一个系统来获取程序的内部数据,可能会涉及很多代码
- 更难统一体验(共享 GUI 窗口等)
2。手动识别关键结构
仔细阅读源代码,多次运行程序,等待程序在健全性检查或内存访问错误时崩溃。
优点
- 简单易行
- 容易上手
- 高可见性、代码共享和统一
缺点
- 没有捕获每一个案例,非常拼凑
- 耗时
3。重构
将所有全局变量收集到memset
的单个结构中,为使用值初始化的变量创建初始值设定项。根据具体情况处理静态问题。
优点
- 概念上简单的大锤式方法
- 高可见性、代码共享和统一
缺点
- 非常耗时,代码库庞大,几乎涉及所有内容
4。魔杖
告诉操作系统重新初始化全局/静态内存。如果我需要保存一个值,我会将其存储在本地,然后在完成后重写。
优点
- 基本完美:)
缺点
- 不存在(?)
- 非常黑魔法
- 可能不会跨平台
- 可能会激怒第 3 方库
我现在在做什么
我现在选择选项 2,只是通过代码,依靠程序崩溃并为我指明正确的方向。
我想说这种方法已经让我完成了大约 80% 的过程。我已经确定并重新初始化了足够多的东西,程序或多或少可以重新运行。它并没有我想象的那么普遍,它给了我很大的希望。
偶尔会发生奇怪的事情,或者它没有按预期运行,但它也不会崩溃。这使得追踪它变得更加困难。
我只需要一些东西来让我剩下最后的 20%。也许是某种静态分析工具,或者可以帮助我浏览源代码并查看全局变量的位置的工具。
最佳答案
要轻松检测全局变量和静态变量,您可以尝试 CppDepend并像这样执行一个 cqlinq 查询
from f in Fields where f.IsGlobal || f.IsStatic
select f
如果您想要特定函数或特定文件中使用的变量,您还可以修改查询。
关于c - 在运行时重新初始化全局/静态内存或对全局/静态变量进行静态分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48724903/