我有一个庞大的遗留系统来维护.代码库使用遍布各处的线程,这些线程共享大量可变数据.我知道,听起来很糟糕.无论如何,不回答"从头开始重写整个应用程序"或者我会投票给你:-)我试图在代码库上运行一些静态分析工具,但这些似乎都没有抓住这种情况发生了很多在我们的源代码中:多个线程正在读取和写入未标记为volatile或同步的变量.通常这发生在"runFlag"类型的变量上.这方面的一个例子是在Effective Java第2版第260页上:
public class StopThread
{
private static boolean stopRequested;
public static void main(String[] args) throws InterruptedException
{
Thread backgroundThread = new Thread(new Runnable()
{
public void run()
{
int i = 0;
while (!stopRequested)
{
i++;
}
}
});
backgroundThread.start();
Thread.sleep(1000);
stopRequested = true;
}
}
Run Code Online (Sandbox Code Playgroud)
此示例永远不会在Windows/Linux上完成,并为Sun JVM提供"-server"启动参数.那么,是否有任何(半)自动方式来查找这些问题,或者我是否必须完全依赖代码审查?
我刚刚介绍了"程序切片"这个术语.人们想要这样的功能是完全合理的,但是它存在于任何地方吗?
这个词现在已经20岁了,我看到有很多出版物,研究论文等等.但实际的工具在哪里?人们是否真的将这个概念付诸实践,或者只是在学术上研究它?
什么在那里,以及什么语言?
编辑:我想我正在寻找什么,我作为一个接受的答案奖励,是一些出版物/组织/等的参考,特别是面向程序切片和维护工具/技术等的列表.
code-analysis static-analysis dynamic-analysis analysis utility
我最近读了EJ Schwartz博士的一篇题为"所有你想要了解动态污点分析和前进符号执行(但可能不得不提出来)"的论文.在本文中,他主要讨论了它们在二进制级安全上下文中的应用.
我很好奇动态污点分析和前向符号执行之间的确切差异.
从我所看到的,每当存储在x中的信息被传送到对象y时,污点分析就跟踪从对象x(源)到对象y(接收器)的信息流.因此,主要关注的是对象可以受到源的传递影响.符号执行将某些输入视为符号值,并尝试用符号表示其他变量; 因此它回答了什么条件的符号输入影响后续的程序.
我可以看到,在二进制级别,通常会提到污点分析,其中包含由覆盖返回地址引起的漏洞; 而符号执行可以处理更多类型的易受攻击的问题,如整数溢出,运行时断言错误,资源泄漏(例如,内存泄漏,文件打开/关闭),缓冲区溢出.
然而,现代污点分析似乎不仅涉及数据流分析,而且大多数都将跟踪控制流条件; 在一些漏洞检测场景中,受污染的输入也表示为符号值,并像符号执行一样传播.另一方面,由于底层约束求解器和执行/解释运行时的限制,符号执行引擎不能完全使用由不同路径条件分隔的符号值; 因此,它们无法达到预期的高分支或路径覆盖.
所以在一般情况下,我们可以说污点分析是一种粗略的符号执行,还是符号执行是一种精确的污点分析?
security static-analysis dynamic-analysis runtime symbolic-computation
我可以使用什么工具.Net/C#项目来捕获类之间的运行时依赖关系?我发现这个问题非常有用,但建议的工具捕获静态依赖图.我只是想看看类的实例化图.
我正在使用VS 2008(但如果需要可以安装其他版本).
UPD:我的目标是这样的.我有很大的旧代码库.它有(例如)500个类但由于DB驱动的工作流程多年来发生了变化(例如)现在使用了100个类.这就是静态依赖性分析太难以消化的原因.
我希望能够检测我的函数(或它调用的任何其他函数)是否最终会在我的单元测试中调用某些特定函数(例如,malloc和free):我的软件的一小部分具有硬实时要求,并且我想确保没有人添加会在这些函数中偶然触发分配的东西(并让我的CI管道自动检查它).
我知道我可以在gdb上设置一个断点,但理想情况下我想做的事情如下:
void my_unit_test() {
my_object obj; // perform some initialization that will allocate
START_CHECKING_FUNCTION(malloc); // also, operator new or std::allocate would be nice
obj.perform_realtime_stuff();
STOP_CHECKING_FUNCTION(malloc);
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,std::abort如果在两个检查之间调用malloc ,那么测试将以不太脏的方式(例如不是)失败.
理想情况下,这可以在任何系统上运行,但我现在可以使用只在Linux上运行的东西.这有可能吗?也许通过LD_PRELOAD hack来取代malloc,但我不想为我感兴趣的所有函数做这个.
我发现了关于这个主题的几个问题,并且所有这些问题都有很多参考,但我仍然没有清楚的想法,因为大多数参考文献都是关于具体工具而不是关于分析的一般概念.因此我有一些问题:
关于静态分析:1.我想有一个参考,或者总结哪些技术是成功的,现在更具相关性.2.他们真正可以做些什么来发现错误,我们可以做一个总结,还是取决于工具?
关于符号执行:1.哪里可以包含符号执行?我想根据方法,我想知道它们是动态分析,还是静态和动态分析的组合,如果可以确定的话.
我找到了区分工具中两种不同技术的问题,即使我认为我知道理论上的差异.
我实际上是在提前与C合作
我试图理解静态分析和动态分析之间的差异,以便程序流程执行,检测安全漏洞.
很明显,动态分析的主要缺点是它无法探索程序可以进入的所有可能状态,因为它依赖于实际运行具有特定输入集的程序.
但是,静态分析似乎是所有可能的程序状态的原因,所以我无法想象静态分析可能会失败的情况,即使我确信这样的情况确实存在.我所看到的大多数参考文献似乎都模糊地说"抽象状态分析"并不像动态分析所能提供的那样精确,但这对我来说太过蓬松.
任何人都可以用静态分析失败的地方和需要动态分析的具体例子提供简单的解释吗?
我正在寻找一些有趣的动态分析仪来使用和报告大学任务.工具应该是:
这包括但不限于性能分析器.他们可以执行任何类型的分析,只要它是动态的,例如代码覆盖,多线程正确性.
产生的结果应该在某种程度上有用,但它们不一定是工业强度.
类似的问题:
那么什么是一些有趣的,免费的,开源的Java动态分析工具?
以下问题的答案描述的推荐用法static_cast,dynamic_cast以及reinterpret_cast在C++:
什么时候应该使用static_cast,dynamic_cast,const_cast和reinterpret_cast?
你知道有哪些工具可以用来检测这类演员的滥用吗?像PC-Lint或Coverity Static Analysis这样的静态分析工具会这样做吗?
提示这个问题的特殊情况是不适当地使用static_cast向下转换指针,编译器没有警告.我想用工具检测这种情况,而不是假设开发人员永远不会犯这个错误.
如何以编程方式确定哪些Vars可能会影响Clojure中定义的函数的结果?
考虑一下Clojure函数的这个定义:
(def ^:dynamic *increment* 3)
(defn f [x]
(+ x *increment*))
Run Code Online (Sandbox Code Playgroud)
这是(也是(1)的一个功能x,但也是(1) ;但我不太关心它.在为此函数编写测试时,我想确保控制所有相关输入,因此我执行以下操作:*increment*clojure.core/+
(assert (= (binding [*increment* 3] (f 1)) 4))
(assert (= (binding [*increment* -1] (f 1)) 0))
Run Code Online (Sandbox Code Playgroud)
(想象一下,这*increment*是某人可能合理改变的配置值;我不希望此功能的测试需要在发生这种情况时进行更改.)
我的问题是:我如何写一个断言,它的值(f 1)可以依赖*increment*但不取决于任何其他Var?因为我希望有一天有人会重构一些代码并导致函数成为现实
(defn f [x]
(+ x *increment* *additional-increment*))
Run Code Online (Sandbox Code Playgroud)
并忽略更新测试,我想测试失败,即使*additional-increment*是零.
这当然是一个简化的例子 - 在一个大型系统中,可以有很多动态Vars,它们可以通过一长串函数调用来引用.该解决方案需要工作,即使f调用g它调用h它引用一个VAR.如果它没有声称(with-out-str (prn "foo"))取决于它会很好*out*,但这不太重要.如果被分析的代码调用eval或使用Java互操作,当然所有的赌注都是关闭的.
我可以想到三类解决方案:
从编译器获取信息
我想编译器会扫描函数定义以获取必要的信息,因为如果我尝试引用一个不存在的Var,它会抛出:
user=> (defn g [x] …Run Code Online (Sandbox Code Playgroud)假设我有这三个谓词:
Predicate<int> pred1 = x => x > 0;
Predicate<int> pred2 = x => x > 0 && true;
Predicate<int> pred3 = x => false;
Run Code Online (Sandbox Code Playgroud)
从一个人的角度,是微不足道的说,pred1并且pred2是等同的,而pred3不是.通过等价的,我的意思是,对于所有可能的输入值,该值由两个输出pred1和pred2将是相同的.
我想为给定的谓词计算一个唯一的哈希值; 两个谓词是等价的,应该有相同的哈希(比如pred1和pred2),两个不等同的谓词不应该(比如pred1和pred3).
之前是否已经完成(再次使用.NET语言)?我知道副作用基本上是这种分析的祸根; 但如果我们"禁止"副作用,可以在.NET(快速)中完成吗?
这个要求的最佳方法是什么?