mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
fix trace command output negative cost problem. #1246
This commit is contained in:
@@ -30,13 +30,7 @@ import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodNode;
|
||||
import com.alibaba.arthas.deps.org.slf4j.Logger;
|
||||
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
|
||||
import com.taobao.arthas.bytekit.asm.MethodProcessor;
|
||||
import com.taobao.arthas.bytekit.asm.binding.Binding;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.InterceptorProcessor;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtEnter;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtExceptionExit;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtExit;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtInvoke;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtInvokeException;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.parser.DefaultInterceptorClassParser;
|
||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
||||
import com.taobao.arthas.bytekit.asm.location.LocationType;
|
||||
@@ -48,6 +42,15 @@ import com.taobao.arthas.bytekit.asm.location.filter.LocationFilter;
|
||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
||||
import com.taobao.arthas.bytekit.utils.AsmUtils;
|
||||
import com.taobao.arthas.core.GlobalOptions;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyInterceptor1;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyInterceptor2;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyInterceptor3;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyTraceExcludeJDKInterceptor1;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyTraceExcludeJDKInterceptor2;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyTraceExcludeJDKInterceptor3;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyTraceInterceptor1;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyTraceInterceptor2;
|
||||
import com.taobao.arthas.core.advisor.SpyInterceptors.SpyTraceInterceptor3;
|
||||
import com.taobao.arthas.core.server.ArthasBootstrap;
|
||||
import com.taobao.arthas.core.util.ArthasCheckUtils;
|
||||
import com.taobao.arthas.core.util.FileUtils;
|
||||
@@ -98,89 +101,6 @@ public class Enhancer implements ClassFileTransformer {
|
||||
affect.setListenerId(listener.id());
|
||||
}
|
||||
|
||||
public static class SpyInterceptor {
|
||||
|
||||
@AtEnter(inline = true)
|
||||
public static void atEnter(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.MethodInfo String methodInfo, @Binding.Args Object[] args) {
|
||||
SpyAPI.atEnter(clazz, methodInfo, target, args);
|
||||
}
|
||||
|
||||
@AtExit(inline = true)
|
||||
public static void atExit(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.MethodInfo String methodInfo, @Binding.Args Object[] args, @Binding.Return Object returnObj) {
|
||||
SpyAPI.atExit(clazz, methodInfo, target, args, returnObj);
|
||||
}
|
||||
|
||||
@AtExceptionExit(inline = true)
|
||||
public static void atExceptionExit(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.MethodInfo String methodInfo, @Binding.Args Object[] args,
|
||||
@Binding.Throwable Throwable throwable) {
|
||||
SpyAPI.atExceptionExit(clazz, methodInfo, target, args, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceExcludeJDKInterceptor {
|
||||
@AtInvoke(name = "", inline = true, whenComplete = false, excludes = "java.**")
|
||||
public static void onInvoke(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atBeforeInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
|
||||
@AtInvoke(name = "", inline = true, whenComplete = true, excludes = "java.**")
|
||||
public static void onInvokeAfter(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atAfterInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
|
||||
@AtInvokeException(name = "", inline = true, excludes = "java.**")
|
||||
public static void onInvokeException(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo, @Binding.Throwable Throwable throwable) {
|
||||
SpyAPI.atInvokeException(clazz, invokeInfo, target, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceInterceptor {
|
||||
@AtInvoke(name = "", inline = true, whenComplete = false, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
|
||||
, "java.lang.Boolean"
|
||||
, "java.lang.Short"
|
||||
, "java.lang.Character"
|
||||
, "java.lang.Integer"
|
||||
, "java.lang.Float"
|
||||
, "java.lang.Long"
|
||||
, "java.lang.Double"})
|
||||
public static void onInvoke(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atBeforeInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
|
||||
@AtInvoke(name = "", inline = true, whenComplete = true, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
|
||||
, "java.lang.Boolean"
|
||||
, "java.lang.Short"
|
||||
, "java.lang.Character"
|
||||
, "java.lang.Integer"
|
||||
, "java.lang.Float"
|
||||
, "java.lang.Long"
|
||||
, "java.lang.Double"})
|
||||
public static void onInvokeAfter(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atAfterInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
|
||||
@AtInvokeException(name = "", inline = true, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
|
||||
, "java.lang.Boolean"
|
||||
, "java.lang.Short"
|
||||
, "java.lang.Character"
|
||||
, "java.lang.Integer"
|
||||
, "java.lang.Float"
|
||||
, "java.lang.Long"
|
||||
, "java.lang.Double"})
|
||||
public static void onInvokeException(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo, @Binding.Throwable Throwable throwable) {
|
||||
SpyAPI.atInvokeException(clazz, invokeInfo, target, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final ClassLoader inClassLoader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
|
||||
@@ -209,17 +129,20 @@ public class Enhancer implements ClassFileTransformer {
|
||||
|
||||
final List<InterceptorProcessor> interceptorProcessors = new ArrayList<InterceptorProcessor>();
|
||||
|
||||
List<InterceptorProcessor> traceProcessors = defaultInterceptorClassParser.parse(SpyInterceptor.class);
|
||||
interceptorProcessors.addAll(traceProcessors);
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyInterceptor1.class));
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyInterceptor2.class));
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyInterceptor3.class));
|
||||
|
||||
if (this.isTracing) {
|
||||
Class<?> spyTraceInterceptorClass = SpyTraceExcludeJDKInterceptor.class;
|
||||
if (this.skipJDKTrace == false) {
|
||||
spyTraceInterceptorClass = SpyTraceInterceptor.class;
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyTraceInterceptor1.class));
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyTraceInterceptor2.class));
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyTraceInterceptor3.class));
|
||||
} else {
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyTraceExcludeJDKInterceptor1.class));
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyTraceExcludeJDKInterceptor2.class));
|
||||
interceptorProcessors.addAll(defaultInterceptorClassParser.parse(SpyTraceExcludeJDKInterceptor3.class));
|
||||
}
|
||||
List<InterceptorProcessor> traceInvokeProcessors = defaultInterceptorClassParser
|
||||
.parse(spyTraceInterceptorClass);
|
||||
interceptorProcessors.addAll(traceInvokeProcessors);
|
||||
}
|
||||
|
||||
List<MethodNode> matchedMethods = new ArrayList<MethodNode>();
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.taobao.arthas.core.advisor;
|
||||
|
||||
import java.arthas.SpyAPI;
|
||||
|
||||
import com.taobao.arthas.bytekit.asm.binding.Binding;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtEnter;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtExceptionExit;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtExit;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtInvoke;
|
||||
import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtInvokeException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengyunabc 2020-06-05
|
||||
*
|
||||
*/
|
||||
public class SpyInterceptors {
|
||||
|
||||
public static class SpyInterceptor1 {
|
||||
|
||||
@AtEnter(inline = true)
|
||||
public static void atEnter(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.MethodInfo String methodInfo, @Binding.Args Object[] args) {
|
||||
SpyAPI.atEnter(clazz, methodInfo, target, args);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyInterceptor2 {
|
||||
@AtExit(inline = true)
|
||||
public static void atExit(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.MethodInfo String methodInfo, @Binding.Args Object[] args, @Binding.Return Object returnObj) {
|
||||
SpyAPI.atExit(clazz, methodInfo, target, args, returnObj);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyInterceptor3 {
|
||||
@AtExceptionExit(inline = true)
|
||||
public static void atExceptionExit(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.MethodInfo String methodInfo, @Binding.Args Object[] args,
|
||||
@Binding.Throwable Throwable throwable) {
|
||||
SpyAPI.atExceptionExit(clazz, methodInfo, target, args, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceInterceptor1 {
|
||||
@AtInvoke(name = "", inline = true, whenComplete = false, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
|
||||
, "java.lang.Boolean"
|
||||
, "java.lang.Short"
|
||||
, "java.lang.Character"
|
||||
, "java.lang.Integer"
|
||||
, "java.lang.Float"
|
||||
, "java.lang.Long"
|
||||
, "java.lang.Double"})
|
||||
public static void onInvoke(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atBeforeInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceInterceptor2 {
|
||||
@AtInvoke(name = "", inline = true, whenComplete = true, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
|
||||
, "java.lang.Boolean"
|
||||
, "java.lang.Short"
|
||||
, "java.lang.Character"
|
||||
, "java.lang.Integer"
|
||||
, "java.lang.Float"
|
||||
, "java.lang.Long"
|
||||
, "java.lang.Double"})
|
||||
public static void onInvokeAfter(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atAfterInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceInterceptor3 {
|
||||
@AtInvokeException(name = "", inline = true, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
|
||||
, "java.lang.Boolean"
|
||||
, "java.lang.Short"
|
||||
, "java.lang.Character"
|
||||
, "java.lang.Integer"
|
||||
, "java.lang.Float"
|
||||
, "java.lang.Long"
|
||||
, "java.lang.Double"})
|
||||
public static void onInvokeException(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo, @Binding.Throwable Throwable throwable) {
|
||||
SpyAPI.atInvokeException(clazz, invokeInfo, target, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceExcludeJDKInterceptor1 {
|
||||
@AtInvoke(name = "", inline = true, whenComplete = false, excludes = "java.**")
|
||||
public static void onInvoke(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atBeforeInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceExcludeJDKInterceptor2 {
|
||||
@AtInvoke(name = "", inline = true, whenComplete = true, excludes = "java.**")
|
||||
public static void onInvokeAfter(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo) {
|
||||
SpyAPI.atAfterInvoke(clazz, invokeInfo, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpyTraceExcludeJDKInterceptor3 {
|
||||
@AtInvokeException(name = "", inline = true, excludes = "java.**")
|
||||
public static void onInvokeException(@Binding.This Object target, @Binding.Class Class<?> clazz,
|
||||
@Binding.InvokeInfo String invokeInfo, @Binding.Throwable Throwable throwable) {
|
||||
SpyAPI.atInvokeException(clazz, invokeInfo, target, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user