简体   繁体   English

当使用 SAST 工具时,为什么我们必须为编译语言(例如 C/C++)使用“构建包装器”?

[英]When using a SAST tool, why do we have to use a "build wrapper" for compiled languages (e.g. C/C++)?

I am new to SAST tools.我是 SAST 工具的新手。 It's amazing to run those tools and find out bugs that are sometimes obvious but we just didn't notice.运行这些工具并找出有时很明显但我们只是没有注意到的错误真是太神奇了。

While I know how to run the tools, I still have many questions in mind how these incredible tools work under the hood.虽然我知道如何运行这些工具,但我仍然对这些令人难以置信的工具如何在幕后工作有很多疑问。

For example, while using SonarQube or Coverity to scan C/C++ source codes, we have to use a build-wrapper so the tool can monitor the build process.例如,在使用 SonarQube 或 Coverity 扫描 C/C++ 源代码时,我们必须使用构建包装器,以便该工具可以监控构建过程。 However, for other interpreted langaues, these tools can just take a look at the codes and still function very well.但是,对于其他解释性语言,这些工具只需查看代码,仍然可以很好地发挥作用。

I could envision that the tools are building the relationship between source codes(function calls/variables/memory alloc or dealloc), what is the reason that for a compiled language the tool has to meddle into the build process?我可以想象这些工具正在构建源代码(函数调用/变量/内存分配或释放)之间的关系,对于编译语言,工具必须干预构建过程的原因是什么?

A static analysis tool needs to know what the code means.静态分析工具需要知道代码的含义。 For compiled languages, the meaning of the code often depends on how the compiler is invoked.对于编译语言,代码的含义通常取决于编译器的调用方式。 For C/C++, that includes things like -D (macro definition) and -I (include path) options, as the former often controls the behavior of #ifdef and the latter is used to find headers for third-party libraries (among other thngs).对于 C/C++,这包括-D (宏定义)和-I (包含路径)选项,因为前者通常控制#ifdef的行为,而后者用于查找第三方库的头文件(以及其他事物)。 For Java, the compilation command includes the -classpath option, which again is how third-party dependencies are found.对于 Java,编译命令包含-classpath选项,这也是查找第三方依赖项的方式。 Other compiled languages are similar.其他编译语言类似。

It is important to locate the correct dependencies both because that can affect the way the code should be parsed and what the behavior is.找到正确的依赖关系很重要,因为这会影响代码的解析方式和行为。 As an example of the former, consider that, in Java, the expression abcdef could mean many things, since the .作为前者的一个例子,考虑一下,在 Java 中,表达式abcdef可能意味着很多东西,因为. operator is used both to navigate in the package hierarchy and to dereference an object to access a field.运算符既用于在包层次结构中导航,也用于取消引用对象以访问字段。 If a comes from the classpath, the tool can't know what this means without inspecting the classes in that classpath.如果a来自类路径,则该工具不检查该类路径中的类就无法知道这意味着什么。 As an example of the latter, consider a function in a third-party library that accepts an object reference.作为后者的示例,请考虑接受对象引用的第三方库中的函数。 Does that function allow a null reference to be passed?该函数是否允许传递null引用? Unless it is a well-known function that the tool already knows about, the only way to tell is for the analyzer to inspect the bytecode of that function.除非它是工具已经知道的众所周知的函数,否则唯一的判断方法是让分析器检查该函数的字节码。

Now, a tool could just ask the user to provide the compilation information directly when invoking the analyzer.现在,一个工具可以只要求用户在调用分析器时直接提供编译信息。 That is the approach taken by clang-tidy , for example.例如,这是clang-tidy采取的方法。 This is conceptually simple, but it can be a challenge to maintain.这在概念上很简单,但维护起来可能是一个挑战。 In a large project, there may be many sets of files that are compiled with different options, making this a pain to set up.在一个大型项目中,可能会有许多文件集使用不同的选项编译,这使得设置起来很麻烦。 And possibly worse, there's no simple and general way to ensure the options passed to the analyzer and the set of files to analyze are kept in sync with the real build.可能更糟糕的是,没有简单和通用的方法来确保传递给分析器的选项和要分析的文件集与实际构建保持同步。

Consequently, some tools provide a "build monitor" that can wrap the usual build, inspecting all of the compilations it performs, and gathering both the set of source files to analyze and the options needed to compile them.因此,一些工具提供了一个“构建监视器”,它可以包装通常的构建,检查它执行的所有编译,并收集要分析的源文件集和编译它们所需的选项。 When that is finished, the main analysis can begin.完成后,可以开始主要分析。 With this approach, nothing in the normal build has to be modified or maintained over time.使用这种方法,正常构建中的任何内容都无需随着时间的推移而修改或维护。 This isn't entirely without potential issues, however.然而,这并非完全没有潜在问题。 The tool may need to be told, for example, what the name of your compiler executable is (which can vary a lot in cross-compile scenarios), and you have to ensure the normal build performs a full build from a "clean" state, otherwise some files may be missed.该工具可能需要被告知,例如,您的编译器可执行文件的名称是什么(在交叉编译场景中可能会有很大差异),并且您必须确保正常构建从“干净”状态执行完整构建,否则可能会遗漏某些文件。

Interpreted languages are usually different because they often have dependencies specified by environment variables that the analyzer can see.解释性语言通常是不同的,因为它们通常具有由分析器可以看到的环境变量指定的依赖项。 When that isn't the case, the analyzer will generally accept additional configuration options.如果不是这种情况,分析器通常会接受额外的配置选项。 For example, if the python executable on the PATH is not what will be used to run Python scripts being analyzed, the analyzer can typically be told to emulate a different one.例如,如果PATH上的python可执行文件不是用于运行正在分析的 Python 脚本的,通常可以告诉分析器模拟不同的脚本。

Tangent: At the end of your question, you jokingly refer to this process as "meddling". Tangent:在你的问题的最后,你开玩笑地把这个过程称为“干预”。 In fact, these tools try very hard not to have any observable effect on the normal build.事实上,这些工具非常努力地避免对正常构建产生任何可观察到的影响。 The paper A Few Billion Lines of Code Later (of which I am one of the authors) has some amusing anecdotes of failures to be transparent. 稍后的几十亿行代码一文(我是其中的作者之一)有一些有趣的失败轶事要透明化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我们必须使用私有? 在C ++和Java中? - why we have to use private? in c++ and java? JFileChooser-从“计算机”开始,例如C:D:E:驱动器 - JFileChooser - Starting at the 'Computer' e.g. C: D: E: drives 我们在Java中是否有像C ++那样的设计模式? - Do we have design patterns in C++ as we have in java? Java - 为什么在递归调用中不维护原始包装类(例如Integer)的值? - Java - Why value of primitive wrapper class (e.g. Integer) isn't maintained in recursive calls? 不同语言(即 Java 和 C++)中的“随机”生成器如何比较? - How do the "random" generators in different languages (i.e. Java and C++) compare? Objective-C选择器,其他语言,例如C ++,Python,ruby,java,javascript也有类似的东西吗? - objective-c selector, do other languages such as c++, python, ruby, java, javascript have similar thing? 用于在java类上生成C ++包装器的工具 - tool to generate C++ wrapper over java class 用于创建和发送HTTP消息的调试工具(例如Curl) - Debug tool for creating and sending HTTP messages (e.g. Curl) 为什么我们需要在 C++ 中检查空指针,而在 Java 中不需要? - Why do we need to check null pointer in C++, but not in Java? 使用该类是否更有效,例如Hashtable而不是接口,例如Map? - Is it more efficient to use the class, e.g. Hashtable than the interface, e.g. Map?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM