`
regular
  • 浏览: 75953 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

运行期代码问题检查技术的研究

    博客分类:
  • Java
阅读更多
以下用我之前代码中的一个bug作为说明,解释如何实现代码在运行期的问题检查。

首先,我们先定义一下待检查的问题。故障代码如下:
	// Invocator...
		try {
			channel = new TcpChannel(SocketChannel.open(), new InetSocketAddress("127.0.0.1", 5656));
		} catch (Exception ex) {
			if (channel != null) {// **
				channel.cleanup(); // Error prone?
			}
			throw ex;
		}

	// TcpChannel.java
	public TcpChannel(SelectableChannel channel, SocketAddress addr) throws IOException
	{
		boolean done = false;
		Selector selector = null;
		try {
			selector = Selector.open();
			key = channel.register(selector, op);
			// ...
			done = true;
		} finally {
			if (!done) {
				cleanup(); // Close all resources
			}
		}
		connect(addr); // * IOException ?
	}

	void cleanup()
	{
		try {
			key.selector().close();
			key.channel().close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	private void connect(SocketAddress addr) throws IOException
	// ...

这个问题是在使用SocketChannel的时候,没有正确地关闭,导致系统资源(文件句柄)泄漏。具体是由于connect(addr);*操作可能产生IOException错误,所以channel可能会构造失败,从而不能执行Exception子句**中的资源回收,造成的句柄外泄。但由于代码里明确写明了SocketChannel的打开和关闭,所以仅从静态的代码审查角度来看,很难发现这个错误。所以我们可以在这里采用对运行中的代码调用指定检查逻辑的方法以发现这种问题。
首先,还是要建立我们的判断逻辑。
public final class SelectorOp
{
	private SelectorOp() {}

	public static Selector open() throws IOException
	{
		Selector selector = Selector.open();
		System.out.println(selector + "\topened!");
		return selector;
	}

	public static void close(Selector selector) throws IOException
	{
		System.out.println(selector + "\tclosed!");
		selector.close();
	}
}

这里,如果要新建一个Selector,则调用SelectorOp.open()代理方法,完成对原有Selector.open()方法的调用,并记录被创建的Selector;如果要关闭Selector,也需要调用SelectorOp.close(selector)代理方法,完成对selector对象自身close()方法的调用,并记录。
这个例子只是一个问题检查的简化说明,只具有实验意义。对于真正的应用来说,可以考虑把这些事件记录在类似于Map这样的容器中,并收集事件发生的时间和代码行,以便做进一步的对比和分析。
接下来,我们要实现自己的ClassLoader。具体的代码见附件,这里仅拣要点说明。
public FileClassLoader(String[] classPaths) {
	for (String path : classPaths) {
		File file = new File(path);
		if (file.exists() && file.canRead()) {
			if (file.isFile() && file.getName().endsWith(".jar")) {
				loadJar(file);
			} else if (file.isDirectory()) {
				loadPath(file, "");
			}
		}
	}
}

FileClassLoader可以处理单个文件,也可以处理jar包。不论对于哪种方式,都是添加类名->实际存放位置的映射关系。之后,在需要的时候获取类的二进制字节数组,转换为Class。
最后,我们要实现类结构的访问和修改工具,见下:
public void visitMethodInsn(int opcode, String owner, String name, String desc)
{
	final String OWNER = "java/nio/channels/Selector";
	final String MOCK = "mock/SelectorOp";
	final String DESC1 = "()Ljava/nio/channels/Selector;";
	final String DESC2 = "(Ljava/nio/channels/Selector;)V";
	if (opcode == INVOKESTATIC && OWNER.equals(owner) && "open".equals(name) && DESC1.equals(desc)) {
		super.visitMethodInsn(opcode, MOCK, name, desc);
	} else
	if (opcode == INVOKEVIRTUAL && OWNER.equals(owner) && "close".equals(name) && "()V".equals(desc)) {
		super.visitMethodInsn(Opcodes.INVOKESTATIC, MOCK, name, DESC2);
	} else {
		super.visitMethodInsn(opcode, owner, name, desc);
	}
}

如果发现了对Selector的open静态方法调用,则转为调用SelectorOp的open静态方法;如果发现了对Selector对象的close调用,则转为调用SelectorOp的close静态方法,入参为Selector对象。
执行结果如下:


图中可以很容易发现,Selector只有开放,没有关闭。
但修改过代码之后,再次执行则结果如下:


每个Selector对象都正确地开放和关闭了。
  • 大小: 15.8 KB
  • 大小: 14.7 KB
0
0
分享到:
评论

相关推荐

    最全的中国标准目录收集

    GB 1000.1-1988 高压线路针式瓷绝缘子 技术条件 GB 10001-1994 公共信息标志用图形符号 GB 10010-1988 医用软聚氯乙烯管材 GB 1001-1986 盘形悬式绝缘子技术条件 GB 1002-1996 家用和类似用途单相插头插座型式、基本...

    part01_软件加解密技术-软件加密》配套光盘 Delphi 7.0

    对于希望自己软件加密的,绝对值得你研究,我自己就从书中代码获益颇多,给自己的商业软件加密了。共分为五个文件,希望对你有帮助。本人缺分,也希望多些人下载,(*^__^*) 嘻嘻…… 光盘目录说明 {第1章 基础知识...

    asp.net知识库

    技术基础 New Folder 多样式星期名字转换 [Design, C#] .NET关于string转换的一个小Bug Regular Expressions 完整的在.net后台执行javascript脚本集合 ASP.NET 中的正则表达式 常用的匹配正则表达式和实例 经典正则...

    part03_软件加解密技术-软件加密》配套光盘 Delphi 7.0

    对于希望自己软件加密的,绝对值得你研究,我自己就从书中代码获益颇多,给自己的商业软件加密了。共分为五个文件,希望对你有帮助。本人缺分,也希望多些人下载,(*^__^*) 嘻嘻…… 光盘目录说明 {第1章 基础知识...

    part04_软件加解密技术-软件加密》配套光盘 Delphi 7.0

    对于希望自己软件加密的,绝对值得你研究,我自己就从书中代码获益颇多,给自己的商业软件加密了。共分为五个文件,希望对你有帮助。本人缺分,也希望多些人下载,(*^__^*) 嘻嘻…… 光盘目录说明 {第1章 基础...

    ASP3《高级编程》(第一部分)

    7.1.2 语义或“运行期”错误 215 7.2 各种运行期错误 218 7.2.1 逻辑错误 219 7.2.2 脚本运行期错误 220 7.2.3 ASP和SSI的运行期错误 221 7.2.4 客户端脚本错误 222 7.3 防止错误 224 7.4 处理错误 229 ...

    ASP3《高级编程》(第二部分)

    7.1.2 语义或“运行期”错误 215 7.2 各种运行期错误 218 7.2.1 逻辑错误 219 7.2.2 脚本运行期错误 220 7.2.3 ASP和SSI的运行期错误 221 7.2.4 客户端脚本错误 222 7.3 防止错误 224 7.4 处理错误 229 ...

    part05_软件加解密技术-软件加密》配套光盘 Delphi 7.0

    对于希望自己软件加密的,绝对值得你研究,我自己就从书中代码获益颇多 ,给自己的商业软件加密了。共分为五个文件,希望对你有帮助。本人缺分 ,也希望多些人下载,(*^__^*) 嘻嘻…… 光盘目录说明 {第1章 基础...

    part02_软件加解密技术-软件加密》配套光盘 Delphi 7.0

    对于希望自己软件加密的,绝对值得你研究,我自己就从书中代码获益颇多,给自己的商业软件加密了。共分为五个文件,希望对你有帮助。本人缺分,也希望多些人下载,(*^__^*) 嘻嘻…… 光盘目录说明 {第1章 基础知识...

    操作系统(内存管理)

    文将对 Linux™ 程序员可以使用的内存管理技术进行概述,虽然关注的重点是 C 语言,但同样也适用于其他语言。文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半...

    c语言编写单片机技巧

    PATTERN)灌入IC,检查其结果是否与当时SIMULATION时状态一样。  STANDBY电流测试:测量IC处于HALT模式时即每一个接点(PAD)在1态0态或Z态保持不变时的漏电流是否符合最低之规格。  耗电...

    计算机二级公共基础知识

    算法基本设计方法:列举法、归纳法、递推、递归、减半递推技术、回溯法。 (5)指令系统 所谓指令系统指的是一个计算机系统能执行的所有指令的集合。 (2)数据结构研究的3个方面 ① 数据集合中各数据元素之间所固有...

    内存管理内存管理内存管理

    要试着运行这些示例,需要先复制本代码清单,并将其粘贴到一个名为 malloc.c 的文件中。接下来,我将一次一个部分地对该清单进行解释。 在大部分操作系统中,内存分配由以下两个简单的函数来处理: void *...

    软件工程知识点

    它包含:软件定义、软件开发、软件运行维护三个时期,并可以细分为可行性研究、项目计划、需求分析、概要设计、详细设计、编码实现与单元测试、系统集成测试、系统确认验证、系统运行与维护等几个阶段。 软件定义...

    Url重写篇视频------本讲将通过实例比较ASP.NET下的三种典型URL重写方案

    在正式研究 URL 如何实现重写之前,应首先了解 Microsoft® Internet Information Services (IIS) 如何处理传入请求,这一点非常重要。当请求到达 IIS Web 服务器时,IIS 检查被请求文件的扩展名以确定如何处理该...

    CLR.via.C#.(中文第3版)(自制详细书签)

    14.2.6 检查字符串中的字符和文本元素 14.2.7 其他字符串操作 14.3 高效率构造字符串 14.3.1 构造StringBuilder对象 14.3.2 StringBuilder的成员 14.4 获取对象的字符串表示:ToString 14.4.1 指定具体的格式...

    软件工程上机实验要求(12-13-2)-王军.doc

    有系统设计代码(其中代码注释不少于代码的30%),系统运行说明。  5.软件工程设计题目示例:    题目一 “教务管理系统之子系统——系内课程安排”  1.系统简介  每学期的期中,学院教务处分别向各个系发出...

Global site tag (gtag.js) - Google Analytics