深入源码:解析SpotBugs (3) Detector

文章目录

  • OpcodeStackDetector
    • 常用套路
    • 调用栈
    • visit code
    • 类检测
    • 方法检测
    • 代码行检测

前面的博客也提到过,Spotbugs 里面 Detector2 与 Detector,FindBugs2 与 FindBugs,GUI2与GUI,可以视为 Spotbugs 与 FindBugs 新老技术的碰撞,那么本篇着重浏览一下 Detector 是如何进行代码扫描生成报告的。

前面也提到过,Spotbugs 很多地方应用了设计模式,在 Detector 中 visitor 模式更为普遍。而且 Spotbugs 是针对于字节码的检测器。看一下代码结构中的细节:

  • apache commons-bcel 字节码工程库(Apache Commons BCEL™)旨在为用户提供一种方便的方法来分析、创建和操作(二进制)Java类文件(以.class结尾的文件)。类由包含给定类的所有符号信息的对象表示:特别是方法、字段和字节码指令。
  • BetterVisitor 对 BCEL 库的 visitor做了更为细致的扩展。
  • PreorderVisitor 使使用访问者模式编程风格成为可能。也就是说,实现此接口的类只需调用所有类都具有的“accept”方法,就可以遍历Java类的内容。
  • AnnotationVisitor 可以访问 类、字段、方法和方法参数上的注解。
  • DismantleBytecode 关键类,拆解字节码的类。这个类实现了visit(Code)方法,并为每一个操作码调用sawOpcode(int)方法。
  • BytecodeScanningDetector 继承 DismantleBytecode 的基类,
  • OpcodeStackDetector 要扫描方法字节码或者使用操作码栈 Detector 基类。 重要
    在这里插入图片描述

OpcodeStackDetector

使用Stack-based来实现findbugs的检测器都要继承OpcodeStackDetector这个类,并且实现sawOpcode(int)方法。这个方法传入的操作码的值,根据这个值我们可以得到操作数的信息,如操作码是函数调用,则能获取到函数的名称、描述符等信息。另外我们还能获取到方法栈数据,程序计数器等数据,使用这些数据便能实现想要检测的代码模式。
在这里插入图片描述

常用套路

  • 继承 Base 类
  • 创建 BugReporter 的构造方法
  • visit 需要的信息,可见 BetterVisit,或者重写 sawOpcode
  • 改写逻辑
    在这里插入图片描述

调用栈

从调用栈上看,ClassContent -> JavaClass -> Method -> Code -> Opcode
在这里插入图片描述

visit code

字节码遍历过程中,一些变量会重置与重新赋值,如 classConstantOperand
在这里插入图片描述

sawOpcode 方法可以看作每行字节码做了什么操作,参数 seen 可以理解为哪一行。

Constants.INVOKEVIRTUAL 表示该行调用类的实例方法,
Constants.INVOKESTATIC 表示调用类的静态方法。

getNameConstantOperand 方法表示获取被调用方法的名称,
getClassConstantOperand 方法表示获取调用类的名称,
getSigConstantOperand 方法表示获取方法的所有参数。

类检测

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6c1818b6d2e546e4814e97b21e77f743.png

方法检测

对于方法的检测,
在这里插入图片描述
在这里插入图片描述

代码行检测

sawOpcode 可以看做每行字节码的操作
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python将多个可迭代对象(如列表、元组、集合等)连接成一个单一的迭代器

Python将多个可迭代对象(如列表、元组、集合等)连接成一个单一的迭代器 itertools.chain 是 Python 标准库中 itertools 模块提供的一个函数,用于将多个可迭代对象(如列表、元组、集合等)连接成一个单一的迭代器。它允许你在循环中一次性遍历多个序列,而不需要先将它们合…

STM32单片机C语言:继电器控制220v灯泡亮灭

本文旨在详细阐述如何利用STM32单片机结合继电器模块,实现对220V灯泡亮灭的远程控制。我们将深入探讨继电器的工作原理,构建相应的硬件电路,并提供具体的程序实现步骤,在智能家居与自动化控制领域的应用的比较多。 一、继电器原理…

接口测试支持IDEA插件一键同步API、新增思维导图快速评审测试用例,MeterSphere开源持续测试工具v3.1.0版本发布

2024年7月29日,MeterSphere开源持续测试工具正式发布v3.1.0版本。 在这一版本中,接口测试方面,支持通过IDEA插件一键同步API至MeterSphere;测试管理方面,“测试用例”模块新增通过思维导图模式快捷评审测试用例。在“…

扫码登录方案

以哔哩哔哩扫码登录为例 二维码解码后内容为:https://passport.bilibili.com/h5-app/passport/login/scan?navhide1&qrcode_keye60869ce7f5235c7123175a7effc6f90&frommain-fe-header 扫码登陆,利用已登录设备授权未登录设备登录的方式 扫码…

使用JavaFx Fxml笔记

使用JavaFx Fxml实现账号密码登录 HelloApplication.java:package com.example.dr295cmonth7;import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.geometry.Insets; import javafx.scene.Parent; import javafx.scene.Scene; i…

【论文精读】 | 基于图表示的视频抑郁症识别的两阶段时间建模框架

文章目录 0、Description1、Introduction2、Related work2.1 Relationship between depression and facial behaviours2.2 Video-based automatic depression analysis2.3 Facial graph representation 3、The proposed two-stage approach3.1 Short-term depressive behaviour…

请你谈谈:vue的渲染机制(render)- 2举例说明问题

如何在 Vue 的 render 函数中使用 createElement 方法来创建虚拟节点(VNode)。这里是一个稍微整理后的示例,它直接对应于你提供的注释和代码片段,但作为一个完整的 render 函数的一部分,可能位于一个 Vue 组件的 scrip…

智能教室监控系统:使用YOLO和深度学习进行人员检测

基于深度学习的教室人员检测系统(UI界面YOLOv8/v7/v6/v5代码训练数据集) 1. 引言 在学校管理中,教室内的人员检测和管理是保证教学质量和安全的重要环节。传统的人工检测方法效率低下且容易出错。随着深度学习技术的发展,基于计…

javascript(一)

一、基本语法 1.位置 (1)JavaScript脚本必须位于<script>与</script>之间 (2)<script>标签可以位于<body>或者<head>部分中 2.输出语句 (1)window.alter() 弹出警告框 (2)document.write() 可以将内容在网页中打印出来&#xff0c;同时也…

二维01背包 背包滚动数组 分割等和子集 DAY22

11.背包理论基础 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 背包问题有多种背包方式&#xff0c;常见的有&#xff1a;01背包、完全…

进程间通信方式--管道

每个进程的用户地址空间都是独立的&#xff0c;一般而言是不能互相访问的&#xff0c;但内核空间是每个进程都共享的&#xff0c;所以进程之间要通信必须通过内核。 管道 管道的linux命令&#xff1a;ps auxf | grep mysql 上面命令行里面的竖线就是一个管道&#xff0c;它的功…

Laravel模型工厂:高效构建测试数据的秘诀

Laravel模型工厂&#xff1a;高效构建测试数据的秘诀 引言 在软件开发过程中&#xff0c;测试是确保代码质量和功能正确性的关键环节。Laravel框架提供了一套强大的工具来支持测试&#xff0c;其中模型工厂&#xff08;Model Factories&#xff09;是构建测试数据的利器。模型…

新手vue学习问题汇总(自用)(长期更新)

1.export default export default 是 ES6 模块语法&#xff0c;用于导出模块的默认成员。在 Vue.js 中&#xff0c;通常用来导出一个组件对象&#xff0c;使其可以在其他文件中被导入并使用。 2.props props 是组件接收外部数据的方式。父组件可以通过向子组件传递 props 来…

紫杉醇生物合成机制研究进展-文献精读35

紫杉醇生物合成机制研究进展 摘要 紫杉醇是目前已发现的最具抗癌活性的天然广谱抗癌药物之一&#xff0c;其生产方式主要依赖于从珍稀植物红豆杉中进行分离提取以及化学半合成&#xff0c;因其含量稀少&#xff0c;生产能力受到严重的限制。随着红豆杉基因组的全解析和合成生…

如何在 Windows 上安装并配置 VNC 远程连接树莓派,并结合Cpolar实现公网远程访问

目录 ⛳️推荐 前言 1. 使用 Raspberry Pi Imager 安装 Raspberry Pi OS 2. Windows安装VNC远程树莓派 3. 使用VNC Viewer公网远程访问树莓派 3.1 安装Cpolar步骤 3.2 配置固定的公网地址 3.3 VNC远程连接测试 4. 固定远程连接公网地址 4.1 固定TCP地址测试 ⛳️推荐…

内网隧道学习笔记

1.基础&#xff1a; 一、端口转发和端口映射 1.端口转发是把一个端口的流量转发到另一个端口 2.端口映射是把一个端口映射到另一个端口上 二、http代理和socks代理 1.http带那里用http协议、主要工作在应用层&#xff0c;主要用来代理浏览网页。 2.socks代理用的是socks协议、…

编码器如何在stm32上使用?

编码器如何在stm32上使用 文章目录 编码器如何在stm32上使用1. 编码器是什么&#xff1f;2. 如何在stm32上使用编码器1. 编码器的基本原理2. STM32上的实现3. 代码实现 1. 编码器是什么&#xff1f; 编码器是一种传感器或设备&#xff0c;用于测量位置、角度或速度&#xff0c…

一天搞定Recat(5)——ReactRouter(上)【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…

程序员纯粹八股文的危害有哪些,应该如何来解决?

“八股文”这个词在程序员面试的上下文中通常指的是那些被广泛讨论、反复练习的问题和答案&#xff0c;它们往往围绕着一些经典的技术知识点&#xff0c;例如算法、数据结构、设计模式等。这些知识在面试中被频繁提及&#xff0c;以至于应聘者经常会提前准备并背诵这些答案&…

坐标系转换公式

坐标系转换2种情况&#xff1a; 一、XOY坐标系不动&#xff0c;点P(x, y) 沿顺时针方向旋转 θ \thetaθ&#xff0c;得在XOY坐标系的坐标为P(x′, y′) 设某点与原点连线和X轴夹角为b度&#xff0c;以原点为圆心&#xff0c;逆时针转过a度 , 原点与该点连线长度为R, [x,y]为…