修复IDEA Agent BUG 修改Java字节码导致的原始字节码结构出错

发布于: 2020年08月18日 22:22:18 | 分类: 轮子工厂 | 浏览: 5

在调试博客新版本中发现了IDEA底层修改Java字节码是的原始字节码错误,框架在解析方法参数的时候我发现原始的程序检测的参数名向后偏移了一个名字如下:

IDEA报错:

业务代码:

原始解析:

int offset = Modifier.isStatic(method.getModifiers()) ? 0 : 1;
for (i = 0; i < parameterCount; i++) {
	paramNames[i] = localVariables.get(i + offset).name;
}

以上解析没有检测参数类型导致参数名偏移出错。

int offset = 0;
if (!Modifier.isStatic(method.getModifiers())) {
	for (LocalVariable localVariable : localVariables) {// 可有可无
		offset++;
		if ("this".equals(localVariable.name)) { // 找到this变量
			break;
		}
	}
}
// check params types
int idx = offset; // localVariable index
for (int start = 0; start < argumentTypes.length; start++) {
	final Type argument = argumentTypes[start];
	if (!argument.equals(Type.getType(localVariables.get(idx++).descriptor))) {
		idx = ++offset;
		start = 0; // 归位
	}
	else {
		paramNames[start] = localVariables.get(start + offset).name;
	}
}

我发现不用检测this关键字 优化版:

// check params types
int idx = offset; // localVariable index
for (int start = 0; start < argumentTypes.length; start++) {
	final Type argument = argumentTypes[start];
	if (!argument.equals(Type.getType(localVariables.get(idx++).descriptor))) {
		idx = ++offset;
		start = 0;
	}
	else {
		paramNames[start] = localVariables.get(start + offset).name;
	}
}

由于不是所有应用都又该问题,我又弄了个开关:


private static boolean enableParamNameTypeChecking = false;

public static void setEnableParamNameTypeChecking(final boolean enableParamNameTypeChecking) {
	ClassUtils.enableParamNameTypeChecking = enableParamNameTypeChecking;
}
static {
	enableParamNameTypeChecking = Boolean.parseBoolean(System.getProperty("ClassUtils.enableParamNameTypeChecking", "false"));
}

int offset = Modifier.isStatic(method.getModifiers()) ? 0 : 1;
if (ClassUtils.enableParamNameTypeChecking) { // enable check params types
  // check params types
  int idx = offset; // localVariable index
  for (int start = 0; start < argumentTypes.length; start++) {
	final Type argument = argumentTypes[start];
	if (!argument.equals(Type.getType(localVariables.get(idx++).descriptor))) {
	  idx = ++offset;
	  start = 0;
	}
	else {
	  paramNames[start] = localVariables.get(start + offset).name;
	}
  }
}
else {
  for (i = 0; i < parameterCount; i++) {
	paramNames[i] = localVariables.get(i + offset).name;
  }
}
标签: Java 踩坑 轮子
版权声明:本文为作者原创文章,转载时请务必声明出处并添加指向此页面的链接。
分享:
发表评论

目前您尚未登录,请 登录 后进行评论

评论信息