thread 1 | grep 'main(' // thread 1会打印线程 ID 1 的栈,通常是 main 函数的线程
jad 类名 // 反编译 Main Class
trace 类名 方法名 '#cost > 10' -n 1 // 只会展示耗时大于 10ms 的调用路径
// 观察事件点
// -b 函数调用前
// -e 函数异常后
// -s 函数返回后
// -f 函数结束后
// -x 指定输出结果的属性遍历深度,默认为 1,最大值是 4
// -n 1 指定输出次数// 查看方法参数、目标对象、返回值
watch 类名 方法名 "{params,target,returnObj}"// 查看方法第一个参数,假设 params[0] 是一个List对象
watch 类名 方法名 params[0] -n 1
// 查看数组中的元素
watch 类名 方法名 params[0][0] -n 1
// 查看Pojo的属性
watch 类名 方法名 params[0][0].age -n 1// 集合投影,相当于 java stream 中的 map 方法
watch 类名 方法名 params[0].{name} -n 1// 集合过滤,{? #this.age > 5} 相当于 java stream 中的 filter 方法
watch 类名 方法名 "params[0].{? #this.age > 5}.{name}" -n 1 // 所有age大于5的Pojo的name
watch 类名 方法名 "params[0].{^ #this.age > 5}.{name}" -n 1 // 第一个age大于5的Pojo的name
watch 类名 方法名 "params[0].{$ #this.age > 5}.{name}" -n 1 // 最后一个age大于5的Pojo的name// 多行表达式,把所有Pojo的name拿出来,再往里面新加一个新的元素,在返回新的列表
watch 类名 方法名 '(#test=params[0].{name}, #test.add("abc"), #test)' -n 1
// 调用构造函数,创建一个新的list,然后添加一个新的元素,然后返回添加后的list
watch 类名 方法名 '(#test=new java.util.ArrayList(), #test.add("abc"), #test)' -n 1// 访问静态变量
watch 类名 方法名 '@类名@静态变量名' -n 1
// 调用静态方法
watch 类名 方法名 '@类名@方法名(args)' -n 1
// 静态方法和非静态方法结合
watch 类名 方法名 '@类名@静态方法名().非静态方法名()' -n 1// 访问Map中的元素
watch 类名 方法名 '@类名@静态变量名.keys' -n 1 // 获取这个Map的所有key
// key 为 enum 类型的获取方法
// 方式一:valueOf
watch 类名 方法名 '@类名@静态变量名.get(@枚举类名@valueOf("RUN"))' -n 1
// 方式二:迭代器+过滤
watch 类名 方法名 '@类名@静态变量名.entrySet().iterator.{? #this.key.name() == "RUN"}' -n 1
反编译需要修改的文件
jad --source-only 类名 > 目标路径/类名.java
sc查找加载修改类的ClassLoader
sc -d *类名 | grep classLoaderHash
mc内存编译代码
mc -c 1be6f5c3 类名.java -d 目标路径
redefine热更新代码
redefine 类名.class
ognl -x 3 '#springContext=@com.ithuameng.admin.utils.SpringUtils@applicationContext,#springContext.getBean("userServiceImpl").getUserByUsername("ithuameng")' -c 18b4aac2
watch -x 2 -n 1 com.ithuameng.admin.service.impl.UserServiceImpl listUser '#springContext=@com.ithuameng.admin.utils.SpringUtils@applicationContext,#user=#springContext.getBean("userServiceImpl"),#redis=#springContext.getBean("redisTemplate"),{#redis.opsForValue().get("pwy::token::1"),#user.getUserByUsername("ithuameng")}'