├── README.md ├── lightTrace ├── asm-all-6.0_BETA.jar ├── trace-0.0.1-SNAPSHOT-agent.jar ├── trace-0.0.1-SNAPSHOT-common.jar ├── trace-0.0.1-SNAPSHOT-agentcore.jar ├── trace-0.0.1-SNAPSHOT-loadagent.jar └── Run.bat ├── src ├── test │ └── java │ │ └── Test.java └── main │ └── java │ └── com │ └── xp │ ├── agent │ ├── core │ │ └── ThreadInfo.java │ └── main │ │ ├── CommonTransform.java │ │ ├── SystemTransform.java │ │ ├── Main.java │ │ └── CustomTransform.java │ ├── common │ └── CommonString.java │ └── console │ └── Main.java └── pom.xml /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpbob/lightTrace/HEAD/README.md -------------------------------------------------------------------------------- /lightTrace/asm-all-6.0_BETA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpbob/lightTrace/HEAD/lightTrace/asm-all-6.0_BETA.jar -------------------------------------------------------------------------------- /lightTrace/trace-0.0.1-SNAPSHOT-agent.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpbob/lightTrace/HEAD/lightTrace/trace-0.0.1-SNAPSHOT-agent.jar -------------------------------------------------------------------------------- /lightTrace/trace-0.0.1-SNAPSHOT-common.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpbob/lightTrace/HEAD/lightTrace/trace-0.0.1-SNAPSHOT-common.jar -------------------------------------------------------------------------------- /lightTrace/trace-0.0.1-SNAPSHOT-agentcore.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpbob/lightTrace/HEAD/lightTrace/trace-0.0.1-SNAPSHOT-agentcore.jar -------------------------------------------------------------------------------- /lightTrace/trace-0.0.1-SNAPSHOT-loadagent.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpbob/lightTrace/HEAD/lightTrace/trace-0.0.1-SNAPSHOT-loadagent.jar -------------------------------------------------------------------------------- /lightTrace/Run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SET curPath=%~dp0 3 | java -Xbootclasspath/a:"%JAVA_HOME%\lib\tools.jar" -jar trace-0.0.1-SNAPSHOT-loadagent.jar %curPath% %1 %2 4 | pause -------------------------------------------------------------------------------- /src/test/java/Test.java: -------------------------------------------------------------------------------- 1 | public class Test { 2 | public static void main(String[] args) throws InterruptedException { 3 | while (true){ 4 | Thread.sleep(30000); 5 | System.out.println("ggg"); 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/xp/agent/core/ThreadInfo.java: -------------------------------------------------------------------------------- 1 | package com.xp.agent.core; 2 | 3 | public class ThreadInfo { 4 | public static void getStack() { 5 | StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 6 | for (StackTraceElement element : stackTrace) { 7 | System.out.println(element); 8 | } 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/xp/common/CommonString.java: -------------------------------------------------------------------------------- 1 | package com.xp.common; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public interface CommonString { 7 | public static final Set SYSTEM = new HashSet() { 8 | { 9 | add("java.lang.System"); 10 | add("sun.management.MemoryImpl"); 11 | } 12 | }; 13 | 14 | public static final String NOCLASS = "doubidoubi"; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/xp/agent/main/CommonTransform.java: -------------------------------------------------------------------------------- 1 | package com.xp.agent.main; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | import org.objectweb.asm.tree.ClassNode; 5 | import org.objectweb.asm.tree.LabelNode; 6 | import org.objectweb.asm.tree.MethodInsnNode; 7 | import org.objectweb.asm.tree.VarInsnNode; 8 | 9 | public abstract class CommonTransform implements Opcodes{ 10 | public VarInsnNode getVarInsnNode(final int opcode, final int var) { 11 | return new VarInsnNode(opcode, var); 12 | 13 | } 14 | 15 | public LabelNode getLabelNode() { 16 | return new LabelNode(); 17 | } 18 | 19 | public MethodInsnNode currentTimeMillis() { 20 | return new MethodInsnNode(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false); 21 | } 22 | 23 | public abstract void trans(ClassNode cn); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/xp/agent/main/SystemTransform.java: -------------------------------------------------------------------------------- 1 | package com.xp.agent.main; 2 | 3 | import java.util.List; 4 | 5 | import org.objectweb.asm.tree.ClassNode; 6 | import org.objectweb.asm.tree.InsnList; 7 | import org.objectweb.asm.tree.MethodInsnNode; 8 | import org.objectweb.asm.tree.MethodNode; 9 | 10 | public class SystemTransform extends CommonTransform { 11 | public void trans(ClassNode cn) { 12 | for (MethodNode mn : (List) cn.methods) { 13 | if ("".equals(mn.name) || "".equals(mn.name)) { 14 | continue; 15 | } 16 | 17 | if (!"gc".equals(mn.name)) { 18 | continue; 19 | } 20 | 21 | InsnList insns = mn.instructions; 22 | if (insns.size() == 0) { 23 | continue; 24 | } 25 | 26 | InsnList list = new InsnList(); 27 | list.add(getLabelNode()); 28 | list.add(new MethodInsnNode(INVOKESTATIC, "com/xp/agent/core/ThreadInfo", "getStack", "()V", false)); 29 | insns.insert(list); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/xp/console/Main.java: -------------------------------------------------------------------------------- 1 | package com.xp.console; 2 | 3 | import java.io.IOException; 4 | 5 | import com.sun.tools.attach.AgentInitializationException; 6 | import com.sun.tools.attach.AgentLoadException; 7 | import com.sun.tools.attach.AttachNotSupportedException; 8 | import com.sun.tools.attach.VirtualMachine; 9 | import static com.xp.common.CommonString.*; 10 | 11 | public class Main { 12 | 13 | public static void main(String[] args) 14 | throws AttachNotSupportedException, IOException, AgentLoadException, AgentInitializationException { 15 | 16 | String agentPath = args[0]; 17 | String pid = null; 18 | String arg = null; 19 | try { 20 | pid = args[1]; 21 | if (pid == null) { 22 | System.out.println("input pid"); 23 | return; 24 | } 25 | } catch(Exception e) { 26 | System.out.println("input pid"); 27 | return; 28 | } 29 | 30 | try { 31 | arg = args[2]; 32 | if (arg == null) { 33 | System.out.println("input arg"); 34 | return; 35 | } 36 | } catch(Exception e) { 37 | arg=NOCLASS; 38 | 39 | } 40 | 41 | 42 | final String jarName = "trace-0.0.1-SNAPSHOT-agent.jar"; 43 | 44 | VirtualMachine vm; 45 | try { 46 | vm = VirtualMachine.attach(pid); 47 | vm.loadAgent(agentPath + "/" + jarName,arg); 48 | vm.detach(); 49 | } catch (Exception e) { 50 | 51 | e.printStackTrace(); 52 | } 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/xp/agent/main/Main.java: -------------------------------------------------------------------------------- 1 | package com.xp.agent.main; 2 | 3 | import org.objectweb.asm.ClassReader; 4 | import org.objectweb.asm.ClassWriter; 5 | import org.objectweb.asm.tree.ClassNode; 6 | 7 | import java.lang.instrument.ClassFileTransformer; 8 | import java.lang.instrument.IllegalClassFormatException; 9 | import java.lang.instrument.Instrumentation; 10 | import java.lang.instrument.UnmodifiableClassException; 11 | import java.security.ProtectionDomain; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import static com.xp.common.CommonString.NOCLASS; 16 | import static com.xp.common.CommonString.SYSTEM; 17 | 18 | public class Main { 19 | 20 | public static void premain(final String args, Instrumentation inst) { 21 | agentmain(args, inst); 22 | } 23 | 24 | public static void agentmain(final String args, Instrumentation inst) { 25 | 26 | inst.addTransformer(new ClassFileTransformer() { 27 | 28 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, 29 | ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { 30 | 31 | className = className.replace("/", "."); 32 | if (!className.contains("$") && (isSpecialClass(className) || isReTransformClass(className, args))) { 33 | 34 | ClassReader cr; 35 | cr = new ClassReader(classfileBuffer); 36 | ClassNode cn = new ClassNode(); 37 | cr.accept(cn, 0); 38 | if (SYSTEM.contains(className)) { 39 | SystemTransform at = new SystemTransform(); 40 | at.trans(cn); 41 | } else { 42 | CustomTransform at = new CustomTransform(); 43 | at.trans(cn); 44 | } 45 | ClassWriter cw = new ClassWriter(0); 46 | cn.accept(cw); 47 | byte[] toByte = cw.toByteArray(); 48 | return toByte; 49 | 50 | 51 | } 52 | 53 | return null; 54 | } 55 | }, true); 56 | 57 | Class[] allLoadedClasses = inst.getAllLoadedClasses(); 58 | List retransformClasses = new ArrayList(allLoadedClasses.length); 59 | for (Class clazz : allLoadedClasses) { 60 | String name = clazz.getName(); 61 | if (isSpecialClass(name) || isReTransformClass(name, args)) { 62 | if (inst.isModifiableClass(clazz) && !name.contains("$")) { 63 | retransformClasses.add(clazz); 64 | } 65 | } 66 | } 67 | try { 68 | if(retransformClasses.size()>0){ 69 | inst.retransformClasses(retransformClasses.toArray(new Class[0])); 70 | } 71 | } catch (UnmodifiableClassException e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | 76 | public static boolean isSpecialClass(String className) { 77 | return SYSTEM.contains(className); 78 | } 79 | 80 | public static boolean isReTransformClass(String className, String args) { 81 | if (NOCLASS.equals(args)) { 82 | return false; 83 | } 84 | 85 | if (className.contains(args)) { 86 | return true; 87 | } 88 | 89 | return false; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/xp/agent/main/CustomTransform.java: -------------------------------------------------------------------------------- 1 | package com.xp.agent.main; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.objectweb.asm.Opcodes; 7 | import org.objectweb.asm.tree.AbstractInsnNode; 8 | import org.objectweb.asm.tree.ClassNode; 9 | import org.objectweb.asm.tree.FieldInsnNode; 10 | import org.objectweb.asm.tree.InsnList; 11 | import org.objectweb.asm.tree.InsnNode; 12 | import org.objectweb.asm.tree.LabelNode; 13 | import org.objectweb.asm.tree.LdcInsnNode; 14 | import org.objectweb.asm.tree.MethodInsnNode; 15 | import org.objectweb.asm.tree.MethodNode; 16 | import org.objectweb.asm.tree.TypeInsnNode; 17 | import org.objectweb.asm.tree.VarInsnNode; 18 | 19 | public class CustomTransform extends CommonTransform { 20 | 21 | 22 | 23 | public void trans(ClassNode cn) { 24 | for (MethodNode mn : (List) cn.methods) { 25 | if ("".equals(mn.name) || "".equals(mn.name)) { 26 | continue; 27 | } 28 | InsnList insns = mn.instructions; 29 | if (insns.size() == 0) { 30 | continue; 31 | } 32 | 33 | FieldInsnNode out = new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 34 | MethodInsnNode println = new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", 35 | "(Ljava/lang/String;)V", false); 36 | 37 | VarInsnNode var = new VarInsnNode(LSTORE, mn.maxLocals); 38 | mn.maxLocals += 2; 39 | insns.insert(var); 40 | insns.insert(currentTimeMillis()); 41 | insns.insert(getLabelNode()); 42 | 43 | Iterator j = insns.iterator(); 44 | 45 | while (j.hasNext()) { 46 | AbstractInsnNode in = j.next(); 47 | 48 | int op = in.getOpcode(); 49 | if ((op >= Opcodes.IRETURN && op <= Opcodes.RETURN)) { 50 | 51 | AbstractInsnNode previous = in.getPrevious(); 52 | InsnList list = new InsnList(); 53 | VarInsnNode varEnd = new VarInsnNode(LSTORE, mn.maxLocals); 54 | mn.maxLocals += 2; 55 | list.add(getLabelNode()); 56 | list.add(currentTimeMillis()); 57 | list.add(varEnd); 58 | list.add(getLabelNode()); 59 | list.add(out); 60 | list.add(new TypeInsnNode(NEW, "java/lang/StringBuilder")); 61 | list.add(new InsnNode(DUP)); 62 | list.add(new VarInsnNode(ALOAD, 0)); 63 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", 64 | false)); 65 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", 66 | false)); 67 | list.add(new MethodInsnNode(INVOKESTATIC, "java/lang/String", "valueOf", 68 | "(Ljava/lang/Object;)Ljava/lang/String;", false)); 69 | list.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/StringBuilder", "", 70 | "(Ljava/lang/String;)V", false)); 71 | list.add(new LdcInsnNode(" ")); 72 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 73 | "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)); 74 | list.add(new LdcInsnNode(mn.name)); 75 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 76 | "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)); 77 | list.add(new LdcInsnNode(" ")); 78 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 79 | "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)); 80 | list.add(new LdcInsnNode("cost ")); 81 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 82 | "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)); 83 | 84 | list.add(getVarInsnNode(LLOAD, varEnd.var)); 85 | list.add(getVarInsnNode(LLOAD, var.var)); 86 | list.add(new InsnNode(LSUB)); 87 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 88 | "(J)Ljava/lang/StringBuilder;", false)); 89 | list.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", 90 | "()Ljava/lang/String;", false)); 91 | list.add(println); 92 | list.add(getLabelNode()); 93 | insns.insert(previous, list); 94 | 95 | } 96 | } 97 | mn.maxStack += 6; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | trace 5 | trace 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | UTF-8 10 | 11 | 12 | 13 | com.sun 14 | tools 15 | 1.6 16 | system 17 | ${java.home}/../lib/tools.jar 18 | 19 | 20 | org.ow2.asm 21 | asm-all 22 | 6.0_BETA 23 | 24 | 25 | 26 | src/main/java 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-compiler-plugin 31 | 32 | 6 33 | 6 34 | UTF-8 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-dependency-plugin 40 | 3.1.1 41 | 42 | 43 | copy-dependencies 44 | package 45 | 46 | copy-dependencies 47 | 48 | 49 | ./target/lib 50 | 51 | 52 | 53 | 54 | 55 | 56 | maven-jar-plugin 57 | 58 | 59 | agent 60 | 61 | jar 62 | 63 | package 64 | 65 | agent 66 | 67 | com/xp/agent/main/** 68 | 69 | 70 | 71 | true 72 | 73 | 74 | 75 | com.xp.agent.main.Main 76 | 77 | 78 | com.xp.agent.main.Main 79 | 80 | 81 | trace-0.0.1-SNAPSHOT-agentcore.jar 82 | 83 | 84 | trace-0.0.1-SNAPSHOT-common.jar 85 | 86 | 87 | true 88 | 89 | 90 | true 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | agentMain 99 | 100 | jar 101 | 102 | package 103 | 104 | loadagent 105 | 106 | com/xp/console/* 107 | 108 | 109 | 110 | true 111 | 112 | 113 | 114 | com.xp.console.Main 115 | 116 | 117 | trace-0.0.1-SNAPSHOT-common.jar 118 | 119 | 120 | 121 | 122 | 123 | 124 | agentcore 125 | 126 | jar 127 | 128 | package 129 | 130 | agentcore 131 | 132 | com/xp/agent/core/* 133 | 134 | 135 | 136 | true 137 | 138 | 139 | 140 | 141 | 142 | common 143 | 144 | jar 145 | 146 | package 147 | 148 | common 149 | 150 | com/xp/common/* 151 | 152 | 153 | 154 | true 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | --------------------------------------------------------------------------------