利用clang提供的库函数进行c语言常规错误的检测

2023-11-08

前言:

感觉很多事情不做就一直不会去做了......

在学校的“科创”活动要求下,不得不尝试发论文,

但我觉得我跟同学做的东西还是比较适合做Demo,为其他刚开始接触这个工具的童鞋提供参考......


正文:

继续在ubuntu中进行操作,一共进行三项检测:

(1)除零检验:

使用libclang的库函数

先提一下如何使用该库函数:

具体操作可以参见我在前面发的文章中的文档链接:Ubuntu下clang开发工具简易入门知识(一)

CXChildVisitResult visitor(CXCursor cursor,CXCursor parent,CXClientData clientData){} 所有的检测都在这个函数中,后面的工作几乎都是在这个函数中完成

这是访问CXCursor的函数,在主函数中经过

clang_visitChildren(cxc,visitor,cxda);调用后,

会按顺序访问输入的代码文件中的每一个CXCursor(在上面的文档链接中提到了,是一个高层抽象过的语法单元,包含多个token,可以递归包含),

通过return CXChildVisit_Continue 和 CXChildVisit_Recurse 来决定下一步的访问内容。


由于是类型上触发,所以关键在于匹配的位置。


匹配位置:

clang_getCursorKind(cursor)== CXCursor_BinaryOperator    

clang_getCursorKind(cursor)== CXCursor_CompoundAssignOperator

一个是出现在形如a=c/b中的,

另一个是出现在形如a/=b的,

在匹配到上面的表达式后,找到/号最后面的变量(1个token),将其与0比较的判断语句插装到该语句前面

“if(b == 0){......}”

rewrite.InsertText(linesloc,judgeStr.c_str(),true,true); 

不过要注意b++,++b,--b,b--这种特殊情况的处理


(2)负数开根号:

匹配位置:

clang_getCursorKind(cursor) == CXCursor_CallExpr

匹配函数名为sqrt,sqrtf,sqrtl,将函数的参数处理出来,注意也处理++,--的问题


----------注意:以上两个函数在插装时都可能遇到位置不对的情况,比如源代码中if()后面没有花括号,会造成改变源码运行结果的问题,所以还要对if,else语句做单独处理,如果没有需要增加花括号

clang_getCursorKind(cursor) == CXCursor_IfStmt

---------

(3)数组越界:

以下开始使用ASTMatcher做检测,同样
具体操作可以参见我在前面发的文章中的文档链接: Ubuntu下clang开发工具简易入门知识(一)
使用clang的语法构造一个匹配表达式,在结点处触发(可以参见clang -Xclang -ast-dump xxx.c生成的语法树)


匹配语句:

StatementMatcher ArraySubMatcher = arraySubscriptExpr().bind("arraySub");
StatementMatcher ArraySubRefMatcher = declRefExpr(hasParent(implicitCastExpr(hasParent(arraySubscriptExpr())))).bind("arraySubRef");

一次是为了得到当前使用的数组的每一维大小,另一次是为了得到正确的插装位置。

由于我是先做的前两个检测,所以if括号的问题已经在之前解决了,否则这边同样需要处理


(4)内存开辟与释放

对于c来说主要是malloc和free的匹配问题,需要在malloc后将该指针的信息存入一个结构体中,再在malloc和free的时候记下指针,再匹配,并在整个程序运行结束后看看是否有未释放的空间或者是否了不合法的指针


匹配语句:

//匹配到malloc()里的变量
StatementMatcher MallocVarMatcher = declRefExpr(hasParent(binaryOperator(
               hasOperatorName("="),
                hasRHS(cStyleCastExpr(has(callExpr(has(declRefExpr(to(functionDecl(hasName("malloc")))))))))))).bind("mallocVar");


//匹配到malloc()那个二元表达式
StatementMatcher MallocMatcher = binaryOperator(
               hasOperatorName("="),
               //hasLHS(anything()),
                hasRHS(cStyleCastExpr(has(callExpr(has(declRefExpr(to(functionDecl(hasName("malloc")))))))))).bind("malloc");


//匹配到直接初始化的malloc()
DeclarationMatcher Malloc2Matcher = varDecl(has(cStyleCastExpr(has(callExpr(has(declRefExpr(to(functionDecl(hasName("malloc")))))))))).bind("malloc2");
//has(cStyleCastExpr(has(callExpr(declRefExpr(to(functionDecl(hasName("malloc"))))))))).bind("malloc2");


//匹配到free()的表达式                                                
StatementMatcher FreeMatcher = callExpr(has(declRefExpr(to(functionDecl(hasName("free")))))).bind("free");
//匹配到free()里的变量
StatementMatcher FreeVarMatcher = declRefExpr(hasParent(implicitCastExpr(hasParent(implicitCastExpr(hasParent(callExpr(has(declRefExpr(to(functionDecl(hasName("free")))))))))))).bind("freeVar");  


同样是一个用于匹配,一个用于找到插装位置。

先写这么多,代码之后会放出。


已经上传github:

https://github.com/farseer002/clangCheckingTool

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用clang提供的库函数进行c语言常规错误的检测 的相关文章

  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • 用户泄漏、libc++ 泄漏或误报

    我正在使用 clang 编译器和 libc 标准库在 C 11 中的 mac 上构建动态库 当我在链接到动态库的测试代码上运行 valgrind 时 我得到一块肯定丢失的内存 这是 valgrind 报告 45659 36 bytes in
  • 在 Ubuntu 中使用 Gstreamer 通过 RTP 协议流式传输 Mp4 视频

    我正在尝试从本地目录获取视频文件 启用来自服务器的流并从客户端捕获这些帧 我使用了以下管道 服务器端 gst launch v filesrc location home gokul Videos Econ TestVideo radioa
  • 让 Rails 生产在端口 80 上运行

    我正在尝试让我的 Rails 应用程序在生产模式下运行 但遇到了一些困难 我正在使用 Passenger 和 apache 并运行 Ubuntu 12 04 我已经配置和创建了生产数据库 并设置了乘客 状态如下 rvmsudo passen
  • Pyaudio 安装错误 - “命令‘gcc’失败,退出状态 1”

    我正在运行 Ubuntu 11 04 Python 2 7 1 并想安装 Pyaudio 于是我跑了 sudo easy install pyaudio 在终端中 进程退出并显示以下错误消息 Searching for pyaudio Re
  • PHP 从命令行启动 gui 程序,但 apache 不启动

    首先 我阅读了有类似问题的人的一些帖子 但所有答案都没有超出导出 DISPLAY 0 0 和 xauth cookies 这是我的问题 提前感谢您的宝贵时间 我开发了一个小库 它使用 OpenGL 和 GLSL 渲染货架 过去几天我将它包装
  • Android 存储库初始化失败

    我想我非常仔细地遵循该网站的说明 http source android com source downloading html http source android com source downloading html 但是当我尝试这
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • Linux:在文件保存时触发 Shell 命令

    我想在修改文件时自动触发 shell 命令 我认为这可以通过注册 inotify 挂钩并调用来在代码中完成system 但是是否有更高级别的 bash 命令可以完成此任务 尝试 inotify 工具 我在复制链接时遇到问题 抱歉 但 Git
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的
  • Linux 中什么处理 ping?

    我想覆盖 更改 linux 处理 ping icmp echo 请求数据包的方式 这意味着我想运行自己的服务器来回复传入的 icmp 回显请求或其他 数据包 但为了使其正常工作 我想我需要禁用 Linux 的默认 ping icmp 数据包
  • C语言中如何通过内存地址映射函数名和行号?

    如何用 GCC 中的内存地址映射回函数名称和行号 即假设一个 C 语言原型 void func Get the address of caller maybe this could be avoided MemoryAddress get
  • 如何授予 apache 使用 NTFS 分区上的目录的权限?

    我在一台带有 20GB 硬盘的旧机器上运行 Linux Lubutu 12 10 我有一个 1 TB 外部硬盘 上面有一个 NTFS 分区 在该分区上 有一个 www 目录 用于保存我的网页内容 它在启动时自动安装为 media t515
  • 没有名为“PIL”的模块

    当我尝试时遇到错误 from PIL import Image ImageFilter 在 Python 文件中我收到一条错误消息ModuleNotFoundError No module named PIL 到目前为止 我已经尝试卸载 重
  • SSE:跨页边界的未对齐加载和存储

    我在页面边界旁边执行未对齐加载或存储之前读过某处 例如使用 mm loadu si128 mm storeu si128内在函数 代码应首先检查整个向量 在本例中为 16 个字节 是否属于同一页 如果不属于同一页 则切换到非向量指令 我知道
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 查找哪个程序运行另一个程序

    我有一个 NAS 运行在 Redhat Linux 的有限版本上 我按照指示破解了它 这样我就可以访问 shell 这很有帮助 我还做了一些修改 其他人也做过修改 除了一个问题之外 它们似乎都工作得很好 不知何故 每隔 22 天 系统就会关
  • 在脚本内使用不带密码的 sudo

    由于某种原因 我需要作为用户在没有 sudo 的情况下运行脚本 script sh 该脚本需要 root 权限才能工作 我认为将 sudo 放入 script sh 中是唯一的解决方案 让我们举个例子 script sh bin sh su
  • 如何确保应用程序在 Linux 上持续运行

    我试图确保脚本在开发服务器上保持运行 它会整理统计数据并提供网络服务 因此它应该会持续存在 但一天中有几次 它会因未知原因而消失 当我们注意到时 我们只需再次启动它 但这很麻烦 并且某些用户没有权限 或专有技术 来启动它 作为一名程序员 我

随机推荐

  • Java集合之LinedList

    LinedList类实现了List接口 他提供了 双向的 链表数据结构 在该链表中的每一个元素除了存储本身的内容之外还存储指向前一个元素的指针和指向后一个元素的指针 下图展示了一个包含三个元素的双向链表 每个链表都有一个头部 头部指向第一个
  • Jdk8 foreach语法需要break怎么办?

    forEach里的return只相当于continue 没有break语法 在这里我总结了3种解决方案供你选择 exception filter anyMatch forEach里的return只相当于continue 没有break语法
  • 【Unity】让动画系统支持相对坐标

    假如你有一个很简单的动画 并且需要应用到许多物体上 但如果你挂载同一个动画到两个物体上 就会这样 解决方案 仅测试过 legacy 动画 挂载此脚本到物体上 using System Collections using System Col
  • 新手小白学影视剪辑50天日入500,她的方法秘籍全在这里了!【覃小龙课堂】

    hi 我是您的老朋友 覃小龙 您可以称呼我为覃总 今天给您带来的主题干货是一位女学员的总结 新手小白学影视剪辑50天日入500 她的方法秘籍全在这里了 做视频剪辑无论新手老手 无非就是这几点 1 怎么样才能不侵权 过审核发布 2 怎么样才能
  • upload-labs靶场学习笔记1-21关

    目录 Pass 01 前端验证 Pass 02 MIME验证 Pass 03 黑名单验证 特殊后缀 Pass 04 黑名单验证 htaccess重写解析绕过上传 Pass 05 黑名单验证 user ini 点空格点 Pass 06 黑名单
  • TD联合Modelsim进行功能仿真

    TD联合Modelsim进行功能仿真 1 引言 2 基本配置流程 2 1 TD软件设置操作 2 2 Modelsim软件方面设置 1 引言 最近在接触使用国产安路科技公司的FPGA进行相关的开发 TD Tang Dynasty 作为一款安路
  • 项目研发心得总结

    前言 近期因学校实验室项目需求 组建6人小团队研发一个网站 框架采用 NET MVC EF 数据库为SQL Server 简单总结一二 一 数据库设计方面 网站的根基 数据库 最开始源自于和甲方进行需求沟通 由于甲方节奏较缓慢 在未完全确定
  • 用certutil 注册根证书到nss/firefox

    环境 Centos 6 5 certutil 参数 所有命令可参见系统自带帮助 通俗易懂 certutil 选项 参数 root localhost lftshell certutil H A Add a certificate to th
  • e5服务器系列天梯图,至强e5系列cpu天梯图_2020年5月至强e5天梯图排行

    CPU的种类多种多样 性能也不尽相同 有很多朋友都非常关注cpu市场的情况 因为一款CPU性能的好坏 决定了我们电脑的运算能力高低 今天我们主要关注的是英特尔e5系列cpu 为了直观对比e5系列cpu的性能情况 我们可以参考至强e5系列cp
  • int *p = NULL 和*p = NULL 有什么区别

    int p NULL 和p NULL 有什么区别 int p NULL 这时候我们可以通过编译器查看p 的值为0x00000000 这句代码的意思是 定义一个指针变量p 其指向的内存里面保存的是int 类型的数据 在定义变量p 的同时把p
  • springboot整合mybatis-plus,代码自动生成

    Mybatis Plus 简称MP 是一个 Mybatis 的增强工具 在 Mybatis 的基础上只做增强不做改变 为简化开发 提高效率而生 特性 无侵入 Mybatis Plus 在 Mybatis 的基础上进行扩展 只做增强不做改变
  • win11绕过硬件限制的方法

    升级win11有硬件配置要求 所以这让很多硬件设施不合格 又懒的换硬件 还想体验win11新系统的用户很头疼 其中就有Windows11当前不支持该处理器的问题 但这不能说明配置低的电脑就完全失去机会了 绕开微软限制的要求 安装上win11
  • [转]信息安全相关理论题(四)

    26 表示邮件服务器返回代码为临时性失败 xx代表任意数 A 2xx B 3xx C 4xx D 5xx 您的答案 标准答案 C 27 买家称购买商品异常后的正确操作是立即咨询官方客服 A 正确 B 错误 您的答案 标准答案 A 28 网上
  • i.mx287学习笔记10-带参内核模块、程序

    上面是我的微信和QQ群 欢迎新朋友的加入 1 带参程序 这里传递的是字符串 argc表示有几个参数要被传递 其中可执行文件本身也会当做一个参数 include stdio h int main int argc char argv int
  • 数据结构(线性表预习)

    1 基本概念 线性表 List 由零个或多个数据元素组成的有限序列 2 注意 1 线性表是一个序列 2 0个元素构成的线性表是空表 3 线性表中的第一个元素无前驱 最后一个元素无后继 其他元素有且只有一个前驱和后继 4 线性表是有长度的 其
  • 四则表达式的编译过程及生成汇编代码

    1 前序 这是编译原理的实验 自认为是上大学以来做过的最难的一个实验 所以写篇博客记录一下 实验用到的基础知识 C语言 数据结构 汇编 只需简单的了解 开发工具 VC 2 问题描述 编译整数四则运算表达式 将整数四则运算表达式翻译为汇编语言
  • GetDC

    目前win10下程序如果是每监视器dpi感知类型 GetDC获取某一个窗口的上下文时 获取的时96dpi值的像素坐标 逻辑英寸 这个API应该还没有dpi感知上下文 建议获取整个屏幕的DC
  • frp内网穿透详细教程

    前言 frp内网穿透是一个比较方便 快捷的配置 使用也是比较人性化 下面简单介绍下实现过程 配置分服务端和本地端 一 阿里服务端配置 1 1 获取frp的安装包 获取安装包 提取链接 下载frp 0 44 0 linux amd64 tar
  • Android Studio总是依赖最新版本的库文件的方式

    依赖最新版本的方式 例如 implementation com google ar core latest release 关键是冒号后边的latest release PS 不太推荐这种方式来依赖第三方库 第一是提交CI编译时徒增编译时间
  • 利用clang提供的库函数进行c语言常规错误的检测

    前言 感觉很多事情不做就一直不会去做了 在学校的 科创 活动要求下 不得不尝试发论文 但我觉得我跟同学做的东西还是比较适合做Demo 为其他刚开始接触这个工具的童鞋提供参考 正文 继续在ubuntu中进行操作 一共进行三项检测 1 除零检验