• 让你的checker出现在clang的checker list中


    生成LLVM文件之后,做下面两件事,我们差不多就终于可以开始我们正式的编写checker之旅了。

    1. clang,can-build,scan-view,ccc-analyzer全部添加正确的系统路径

    2. 安装windows下的Perl64解释器并添加系统路径

    到这里差不多就可使用了,我们来测试一下:

    clang --help
    clang -cc1 -analyzer-checker-help    (列出所有可用的checker)

    下面我们给出一段测试程序

    char * test_fixed_address_checker()
    {
        char *p;
        p = 0x1000;
        return p;
    }

    将它保存为test.c,并放在桌面上,方便我们测试(强迫症者除外),然后我们打开cmd,复制粘贴下面三行:

    cd desktop
    type test.c
    clang --analyze -Xclang -analyzer-checker=alpha.core.FixedAddr test.c

    结果为:

    下面我们来试下scan-build

    scan-build --use-analyzer=D:LLVMuildDebuginclang.exe clang -cc1 test.c

     

    --use-analyzer=D:LLVMuildDebuginclang.exe --use-analyzer 就是要告诉系统一个可用的clang的位置,也就是我们配置的clang 的环境变量path的值。

    实践测试了代码之后,我们来DIY吧!下面来写自己的checkers。我就按照自己放置的路径分享了,大家可以对照自己的做调整:

    1. 打开D:LLVMllvm oolsclanglibStaticAnalyzerCheckers

    2. 添加自定义的.cpp checker文件,比如:MyDefinedChecker.cpp

    并在该文件中添加注册函数:

    void ento::registerMyDefinedChecker(CheckerManager &mgr) {
      mgr.registerChecker<MyDefinedChecker>();
    }

    千万别像我一样傻,除了上面的代码什么都不往里面放,就想要皆大欢喜,实际是要放下下面这一段试试的,因为第一步你要在VS中没有便宜错误,之后还不能有链接错误,所以虽然没有实际内容,请放下面的内容:

    #include "ClangSACheckers.h"
    #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
    #include "clang/StaticAnalyzer/Core/Checker.h"
    #include "clang/StaticAnalyzer/Core/CheckerManager.h"
    #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
    
    using namespace clang;
    using namespace ento;
    
    namespace {
        class MyDefinedChecker
            : public Checker< check::PreStmt<BinaryOperator> > {
            mutable std::unique_ptr<BuiltinBug> BT;
    
        public:
            void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
        };
    }
    
    void MyDefinedChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const 
    {
    }
    void ento::registerMyDefinedChecker(CheckerManager &mgr) {
      mgr.registerChecker<MyDefinedChecker>();
    }

    3. D:LLVMllvm oolsclangincludeclangStaticAnalyzerCheckers中找到Checkers.td文件,在Checkers.td文件中为自己的checker添加分组信息,也就是说你要让自己的checker继承自哪一类,差不多在159行左右,大家把自己的checker放在下图的这个package里面:CoreAlpha

    代码为:

    def MyDefinedChecker : Checker<"MyDefined">,
    HelpText
    <"Check for a self-defined error">, DescFile<"MyDefinedChecker.cpp">;

    4. 最后在D:LLVMllvm oolsclanglibStaticAnalyzerCheckersCMakeLists.txt中添加类名.cpp,比如:MyDefinedChecker.cpp放在59行,因为貌似是按照字母顺序表来的。

    现在打开LLVM.sln, 在解决方案中搜索刚写的checker名,找到自己的源文件,检查是否有错误,如果没有,注意点击该源文件所属的项目,只生成这个项目即可,否则会很费时间,特别慢,特别卡,要崩溃的感觉。

    现在来测试一下:

    还不错的感觉哦,哈哈!

    如果效果不是上图所示,可以右击clang这个项目,点击生成,就会把变化的内容重新编译,如果存在连接问题,如果是LINK2019,可能是只写了函数声明,没有定义。

    今天就啰嗦这么多吧,下一节,我们会简单介绍如何真正开始写一些自己经过设计的checker

     补充说明:

    1.如果是打开LLVM.sln,然后点开clang libraries里面的clangStaticAnalyzerCheckers,然后右击Source Files直接添加的,其他文件也是在项目里打开直接修改的,就直接生成clang项目就可以,不需要像2中再Cmake生成一次。

    2.如果是根据目录从文件夹打开添加了各个对应文件,就要用Cmake重新生成一下这个VS项目: cmake -G "Visual Studio 14" ..    然后,打开LLVM.sln,生成clang这个项目。

    参考文章:

    http://blog.csdn.net/tuqinag/article/details/46940633

    https://sec.xiaomi.com/article/21

  • 相关阅读:
    数据库连接池的原理。为什么要使用连接池。
    如果你也用过 struts2.简单介绍下 springMVC 和 struts2 的区别有哪些?
    MyBatis 与 Hibernate 有哪些不同?
    Class.forName的作用?为什么要用?
    一个Redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多能存放多少元素?
    MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?
    如果有大量的key需要设置同一时间过期,一般需要注意什么?
    使用过Redis做异步队列么,你是怎么用的?
    我们如何在Struts2应用程序中集成log4j?
    我们怎样才能在动作类中获得Servlet API请求,响应,HttpSession等对象?
  • 原文地址:https://www.cnblogs.com/wangyuxia/p/6568917.html
Copyright © 2020-2023  润新知