用jvmti调试java application: hello world 实现

1. 用C写一个动态链接库, 代码如下:

ubuntu@ubuntu-VirtualBox:~$ cat agent.cpp
#include

#include

#include

#include

#include

#include

#include

#include

#include
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void
*reserved)
{
return Agent_OnAttach(vm, options, reserved);
}
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options,

void *reserved) {

jvmtiEnv *jvmti;

jint result = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);

if (result != JNI_OK) {
printf("ERROR: Unable to access JVMTI!\n");

}

jvmtiError err = (jvmtiError) 0;

jclass *classes;

jint count;

err = jvmti->GetLoadedClasses(&count, &classes);

if (err) {

printf("ERROR: JVMTI GetLoadedClasses failed!\n");

}

for (int i = 0; i < count; i++) {

char *sig;

jvmti->GetClassSignature(classes[i], &sig, NULL);

printf("cls sig=%s\n", sig);

}

return err;

}

JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) {

// nothing to do

}

编成.so文件:
gcc agent.cpp -I/usr/java/jdk1.6.0_27/include -I/usr/java/jdk1.6.0_27/include/linux -shared -fPIC -o ./libtestagent.so

2. load动态链接库到java application.
两种方法:
1) 启动时加载: java -agentpath:./libtestagent.so Test
2) 启动后加载:java -cp .:$JAVA_HOME/lib/tools.jar VMAttacher 2413 ./libtestagent.so a

3. 测试代码:
//Test.java
public class Test {

public static void main(String[] args) {
new Thread() {
@Override
public void run() {
Test test = new Test();
while (true) {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.printHello();
}
}
}.start();
}

protected void printHello() {
System.out.println("hello");

}
}

4. 动态加载代码:
//VMAttacher.java
import java.io.IOException;

import com.sun.tools.attach.VirtualMachine;

public class VMAttacher {

public static void main(String[] args) throws Exception {

// args[0]为java进程id

VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(args[0]);

// args[1]为共享库路径,args[2]为传递给agent的参数

virtualMachine.loadAgentPath(args[1], args[2]);

virtualMachine.detach();

}

}


启动后加载的结果:
cls sig=Ljava/io/ExpiringCache$1;
cls sig=Ljava/lang/Math;
cls sig=Ljava/util/LinkedHashMap;
cls sig=Ljava/util/HashMap$EntryIterator;
cls sig=Ljava/util/LinkedHashMap$Entry;
cls sig=Ljava/util/concurrent/ConcurrentHashMap$Segment;
cls sig=[Ljava/util/concurrent/ConcurrentHashMap$Segment;
cls sig=Ljava/util/concurrent/locks/ReentrantLock;
cls sig=[Ljava/util/concurrent/locks/ReentrantLock;
cls sig=Ljava/util/concurrent/locks/Lock;
cls sig=[Ljava/util/concurrent/locks/Lock;
cls sig=Ljava/lang/NullPointerException;
cls sig=Ljava/lang/StringBuilder;
cls sig=Ljava/lang/ArithmeticException;
cls sig=Ljava/io/ObjectStreamField;
cls sig=[Ljava/io/ObjectStreamField;
cls sig=Ljava/util/jar/JarFile;
cls sig=Ljava/util/zip/ZipFile;
cls sig=Ljava/util/zip/ZipConstants;
cls sig=Ljava/lang/ThreadGroup;
cls sig=[Ljava/lang/ThreadGroup;
cls sig=Lsun/nio/cs/HistoricallyNamedCharset;
cls sig=Ljava/lang/Thread$UncaughtExceptionHandler;
cls sig=[Ljava/lang/Thread$UncaughtExceptionHandler;
cls sig=Lsun/misc/VM;
cls sig=Lsun/misc/JavaSecurityAccess;
cls sig=LTest;
cls sig=Ljava/lang/String$CaseInsensitiveComparator;
cls sig=Ljava/util/Comparator;
cls sig=Ljava/lang/RuntimePermission;
cls sig=Ljava/security/BasicPermission;
cls sig=Ljava/security/Permission;
cls sig=Ljava/security/Guard;
cls sig=Ljava/lang/StringCoding;
cls sig=Lsun/misc/SoftCache;
cls sig=Ljava/util/AbstractMap;
cls sig=Ljava/util/concurrent/locks/ReentrantLock$NonfairSync;
cls sig=Ljava/util/concurrent/locks/ReentrantLock$Sync;
cls sig=Ljava/util/concurrent/locks/AbstractQueuedSynchronizer;
cls sig=Ljava/util/concurrent/locks/AbstractOwnableSynchronizer;
cls sig=Ljava/lang/ThreadLocal$ThreadLocalMap;
cls sig=Ljava/util/Properties;
cls sig=Ljava/util/Hashtable;
cls sig=Ljava/util/Dictionary;
cls sig=Ljava/util/Map;
cls sig=Ljava/util/zip/InflaterInputStream;
cls sig=Ljava/io/File$1;
cls sig=Ljava/util/jar/JavaUtilJarAccessImpl;
cls sig=Lsun/misc/JavaUtilJarAccess;
cls sig=Lsun/misc/JavaIODeleteOnExitAccess;
cls sig=Lsun/misc/SharedSecrets;
cls sig=Lsun/misc/JarIndex;
cls sig=Ljava/lang/ref/ReferenceQueue;
cls sig=Ljava/util/zip/Inflater;
cls sig=Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
cls sig=[Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
cls sig=Ljava/lang/StringCoding$StringDecoder;
cls sig=Ljava/lang/ref/ReferenceQueue$Null;
cls sig=Ljava/util/HashMap$EntrySet;
cls sig=Ljava/lang/ClassLoader$3;
cls sig=Ljava/lang/ref/ReferenceQueue$Lock;
cls sig=Ljava/lang/StringCoding$StringEncoder;
cls sig=Ljava/util/HashMap;
cls sig=Ljava/util/zip/ZipEntry;
cls sig=Ljava/nio/charset/CharsetDecoder;
cls sig=Ljava/io/ExpiringCache$Entry;
cls sig=Ljava/lang/ClassLoader$NativeLibrary;
cls sig=Ljava/lang/Terminator;
cls sig=Ljava/lang/Terminator$1;
cls sig=Lsun/misc/SignalHandler;
cls sig=Ljava/util/jar/JarFile$JarFileEntry;
cls sig=Ljava/util/jar/JarEntry;
cls sig=Lsun/misc/Signal;
cls sig=Lsun/misc/URLClassPath$JarLoader$1;
cls sig=Lsun/misc/FileURLMapper;
cls sig=Lsun/misc/NativeSignalHandler;
cls sig=Ljava/util/concurrent/locks/AbstractQueuedSynchronizer$Node;
cls sig=Ljava/io/Console;
cls sig=Ljava/nio/charset/CodingErrorAction;
cls sig=Ljava/nio/ByteBuffer;
cls sig=Ljava/util/concurrent/ConcurrentHashMap$HashEntry;
cls sig=[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;
cls sig=Ljava/lang/annotation/Annotation;
cls sig=[Ljava/lang/annotation/Annotation;
cls sig=Ljava/lang/CharacterDataLatin1;
cls sig=Ljava/lang/CharacterData;
cls sig=Ljava/util/HashMap$Entry;
cls sig=[Ljava/util/HashMap$Entry;
cls sig=Ljava/util/Map$Entry;
cls sig=[Ljava/util/Map$Entry;
cls sig=Ljava/security/AccessController;
cls sig=Ljava/io/Console$1;
cls sig=Lsun/misc/JavaIOAccess;
cls sig=Ljava/io/Console$1$1;
cls sig=Ljava/lang/reflect/AccessibleObject;
cls sig=[Ljava/lang/reflect/AccessibleObject;
cls sig=Ljava/lang/Shutdown;
cls sig=Ljava/lang/reflect/ReflectPermission;
cls sig=Lsun/reflect/ReflectionFactory$GetReflectionFactoryAction;
cls sig=Ljava/security/PrivilegedAction;
cls sig=Ljava/util/Stack;
cls sig=Ljava/net/Parts;
cls sig=Ljava/lang/reflect/Field;
cls sig=[Ljava/lang/reflect/Field;
cls sig=Ljava/lang/reflect/Member;
cls sig=[Ljava/lang/reflect/Member;
cls sig=Lsun/net/www/protocol/file/Handler;
cls sig=Ljava/net/URLStreamHandler;
cls sig=Lsun/reflect/ReflectionFactory;
cls sig=Ljava/util/ArrayList;
cls sig=Ljava/nio/HeapByteBuffer;
cls sig=Lsun/misc/JavaSecurityProtectionDomainAccess;
cls sig=Lsun/misc/ExtensionDependency;
cls sig=Ljava/lang/ref/Reference$Lock;
cls sig=Ljava/lang/ref/Reference$ReferenceHandler;
cls sig=Ljava/lang/ref/Finalizer$FinalizerThread;
cls sig=Ljava/util/Enumeration;
cls sig=Ljava/util/Iterator;
cls sig=Ljava/util/Hashtable$Entry;
cls sig=[Ljava/util/Hashtable$Entry;
cls sig=Ljava/lang/Class$1;
cls sig=Ljava/lang/reflect/Method;
cls sig=Ljava/nio/Bits;
cls sig=Lsun/reflect/ReflectionFactory$1;
cls sig=Ljava/lang/Shutdown$Lock;
cls sig=Ljava/lang/ApplicationShutdownHooks;
cls sig=Lsun/reflect/NativeConstructorAccessorImpl;
cls sig=Ljava/nio/charset/Charset;
cls sig=Ljava/util/zip/ZipFile$ZipFileInputStream;
cls sig=Lsun/reflect/DelegatingConstructorAccessorImpl;
cls sig=Ljava/util/IdentityHashMap;
cls sig=Ljava/util/HashSet;
cls sig=Lsun/misc/URLClassPath;
cls sig=Ljava/lang/reflect/Constructor;
cls sig=[Ljava/lang/reflect/Constructor;
cls sig=Lsun/nio/cs/StandardCharsets;
cls sig=Lsun/nio/cs/FastCharsetProvider;
cls sig=Ljava/nio/charset/spi/CharsetProvider;
cls sig=Lsun/net/www/protocol/jar/Handler;
cls sig=Lsun/misc/OSEnvironment;
cls sig=Ljava/lang/System$2;
cls sig=Lsun/misc/JavaLangAccess;
cls sig=Lsun/misc/Launcher$AppClassLoader;
cls sig=Ljava/lang/Compiler;
cls sig=Lsun/nio/cs/StandardCharsets$Aliases;
cls sig=Lsun/util/PreHashedMap;
cls sig=Lsun/misc/Launcher$AppClassLoader$1;
cls sig=Ljava/lang/Compiler$1;
cls sig=Lsun/reflect/MagicAccessorImpl;
cls sig=Ljava/lang/SystemClassLoaderAction;
cls sig=Lsun/reflect/MethodAccessorImpl;
cls sig=Lsun/misc/Launcher;
cls sig=Lsun/reflect/MethodAccessor;
cls sig=Lsun/reflect/ConstructorAccessorImpl;
cls sig=Lsun/reflect/ConstructorAccessor;
cls sig=Ljava/net/URLClassLoader$1;
cls sig=Lsun/reflect/DelegatingClassLoader;
cls sig=Lsun/misc/URLClassPath$3;
cls sig=Lsun/reflect/ConstantPool;
cls sig=Lsun/misc/URLClassPath$JarLoader;
cls sig=Lsun/misc/URLClassPath$Loader;
cls sig=Lsun/misc/Launcher$Factory;
cls sig=Ljava/net/URLStreamHandlerFactory;
cls sig=Lsun/misc/Launcher$ExtClassLoader;
cls sig=Ljava/net/URLClassLoader;
cls sig=Ljava/security/SecureClassLoader;
cls sig=Ljava/nio/ByteOrder;
cls sig=Lsun/reflect/UnsafeStaticFieldAccessorImpl;
cls sig=Lsun/reflect/UnsafeFieldAccessorImpl;
cls sig=Ljava/nio/CharBuffer;
cls sig=Lsun/reflect/FieldAccessorImpl;
cls sig=Lsun/reflect/FieldAccessor;
cls sig=Ljava/lang/Readable;
cls sig=Ljava/lang/Object;
cls sig=[Ljava/lang/Object;
cls sig=Lsun/nio/cs/StandardCharsets$Classes;
cls sig=Ljava/lang/String;
cls sig=[Ljava/lang/String;
cls sig=Ljava/lang/Comparable;
cls sig=[Ljava/lang/Comparable;
cls sig=Ljava/io/Serializable;
cls sig=[Ljava/io/Serializable;
cls sig=Ljava/lang/CharSequence;
cls sig=[Ljava/lang/CharSequence;
cls sig=Lsun/nio/cs/StandardCharsets$Cache;
cls sig=Ljava/security/PrivilegedActionException;
cls sig=Ljava/lang/ThreadLocal;
cls sig=Lsun/misc/URLClassPath$FileLoader;
cls sig=Lsun/misc/URLClassPath$FileLoader$1;
cls sig=Lsun/misc/Resource;
cls sig=Ljava/nio/HeapCharBuffer;
cls sig=Ljava/util/concurrent/atomic/AtomicInteger;
cls sig=Ljava/util/Vector;
cls sig=Ljava/util/AbstractList;
cls sig=Ljava/util/AbstractCollection;
cls sig=Ljava/util/Collection;
cls sig=Ljava/lang/Iterable;
cls sig=Lsun/security/util/Debug;
cls sig=Lsun/nio/ByteBuffered;
cls sig=Ljava/security/CodeSource;
cls sig=Lsun/misc/Unsafe;
cls sig=Ljava/nio/charset/CoderResult;
cls sig=Ljava/net/URLClassLoader$7;
cls sig=Lsun/misc/JavaNetAccess;
cls sig=Ljava/util/StringTokenizer;
cls sig=Ljava/util/List;
cls sig=Ljava/nio/charset/CoderResult$1;
cls sig=Ljava/nio/charset/CoderResult$Cache;
cls sig=Ljava/nio/charset/CoderResult$2;
cls sig=Lsun/misc/Version;
cls sig=Ljava/security/Permissions;
cls sig=Ljava/security/PermissionCollection;
cls sig=Lsun/misc/Launcher$ExtClassLoader$1;
cls sig=Ljava/security/PrivilegedExceptionAction;
cls sig=Lsun/misc/MetaIndex;
cls sig=Ljava/util/RandomAccess;
cls sig=Ljava/io/BufferedReader;
cls sig=Ljava/io/Reader;
cls sig=Ljava/io/FileInputStream;
cls sig=Ljava/io/InputStream;
cls sig=Ljava/io/Closeable;
cls sig=Lsun/net/www/protocol/file/FileURLConnection;
cls sig=Lsun/net/www/URLConnection;
cls sig=Ljava/net/URLConnection;
cls sig=Ljava/lang/NoSuchMethodError;
cls sig=Ljava/lang/IncompatibleClassChangeError;
cls sig=Lsun/reflect/Reflection;
cls sig=Ljava/io/FileDescriptor;
cls sig=Ljava/io/FileOutputStream;
cls sig=Ljava/io/OutputStream;
cls sig=Ljava/io/Flushable;
cls sig=Ljava/io/FileReader;
cls sig=Ljava/io/InputStreamReader;
cls sig=Ljava/lang/Class;
cls sig=[Ljava/lang/Class;
cls sig=Ljava/lang/reflect/GenericDeclaration;
cls sig=[Ljava/lang/reflect/GenericDeclaration;
cls sig=Ljava/lang/reflect/AnnotatedElement;
cls sig=[Ljava/lang/reflect/AnnotatedElement;
cls sig=Ljava/lang/reflect/Type;
cls sig=[Ljava/lang/reflect/Type;
cls sig=Ljava/lang/StringBuffer;
cls sig=Ljava/lang/AbstractStringBuilder;
cls sig=Ljava/lang/Appendable;
cls sig=Lsun/nio/cs/StreamDecoder;
cls sig=Ljava/io/BufferedInputStream;
cls sig=Ljava/io/FilterInputStream;
cls sig=Ljava/util/zip/ZStreamRef;
cls sig=Ljava/security/ProtectionDomain$Key;
cls sig=Ljava/security/ProtectionDomain$2;
cls sig=Ljava/security/AccessControlContext$1;
cls sig=Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;
cls sig=Ljava/lang/reflect/Array;
cls sig=Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl;
cls sig=Lsun/net/www/ParseUtil;
cls sig=Lsun/reflect/misc/ReflectUtil;
cls sig=Ljava/io/PrintStream;
cls sig=Ljava/io/FilterOutputStream;
cls sig=Ljava/net/UnknownContentHandler;
cls sig=Ljava/net/ContentHandler;
cls sig=Lsun/net/www/MessageHeader;
cls sig=Ljava/util/AbstractSet;
cls sig=Ljava/util/Set;
cls sig=Ljava/io/FilePermission;
cls sig=Ljava/util/BitSet;
cls sig=Ljava/io/IOException;
cls sig=Ljava/lang/ClassLoader;
cls sig=Ljava/lang/Cloneable;
cls sig=Ljava/io/BufferedOutputStream;
cls sig=Ljava/io/FilePermission$1;
cls sig=Ljava/io/OutputStreamWriter;
cls sig=Ljava/io/Writer;
cls sig=Lsun/security/provider/PolicyFile;
cls sig=Ljava/security/Policy;
cls sig=Ljava/lang/StackTraceElement;
cls sig=[Ljava/lang/StackTraceElement;
cls sig=Lsun/nio/cs/StreamEncoder;
cls sig=Ljava/io/ObjectStreamClass;
cls sig=Ljava/lang/Class$3;
cls sig=Ljava/nio/Buffer;
cls sig=Ljava/lang/reflect/Modifier;
cls sig=Ljava/lang/reflect/ReflectAccess;
cls sig=Lsun/reflect/LangReflectAccess;
cls sig=Ljava/lang/Boolean;
cls sig=Lsun/security/action/GetPropertyAction;
cls sig=Ljava/lang/Character;
cls sig=Ljava/nio/charset/CharsetEncoder;
cls sig=Ljava/util/Arrays;
cls sig=Ljava/lang/System;
cls sig=Lsun/nio/cs/UTF_8;
cls sig=Lsun/nio/cs/Unicode;
cls sig=Ljava/io/DataInputStream;
cls sig=Ljava/io/DataInput;
cls sig=Lsun/nio/cs/UTF_8$Encoder;
cls sig=Ljava/lang/Throwable;
cls sig=[Ljava/lang/Throwable;
cls sig=Ljava/io/BufferedWriter;
cls sig=Lsun/nio/cs/UTF_8$Decoder;
cls sig=Ljava/lang/Float;
cls sig=Ljava/lang/Number;
cls sig=Ljava/lang/Runtime;
cls sig=Ljava/lang/Error;
cls sig=[Ljava/lang/Error;
cls sig=Ljava/lang/ThreadDeath;
cls sig=Ljava/lang/Exception;
cls sig=Ljava/lang/RuntimeException;
cls sig=Ljava/security/Policy$UnsupportedEmptyCollection;
cls sig=Ljava/security/ProtectionDomain;
cls sig=[Ljava/security/ProtectionDomain;
cls sig=Ljava/io/FilePermissionCollection;
cls sig=Ljava/lang/Double;
cls sig=Ljava/io/File;
cls sig=[Ljava/io/File;
cls sig=Ljava/net/URL;
cls sig=[Ljava/net/URL;
cls sig=Ljava/security/AllPermission;
cls sig=Ljava/security/UnresolvedPermission;
cls sig=Ljava/security/AccessControlContext;
cls sig=Ljava/lang/Byte;
cls sig=Ljava/util/zip/ZipException;
cls sig=Ljava/lang/Short;
cls sig=Ljava/security/BasicPermissionCollection;
cls sig=Ljava/lang/ClassNotFoundException;
cls sig=Ljava/lang/NoClassDefFoundError;
cls sig=Ljava/lang/LinkageError;
cls sig=Ljava/lang/ClassCastException;
cls sig=Ljava/security/Principal;
cls sig=[Ljava/security/Principal;
cls sig=Ljava/io/FileDescriptor$1;
cls sig=Ljava/lang/ArrayStoreException;
cls sig=Ljava/security/cert/Certificate;
cls sig=[Ljava/security/cert/Certificate;
cls sig=Ljava/lang/Integer;
cls sig=Ljava/lang/VirtualMachineError;
cls sig=[Ljava/lang/VirtualMachineError;
cls sig=Ljava/util/Locale;
cls sig=Ljava/lang/OutOfMemoryError;
cls sig=[Ljava/lang/OutOfMemoryError;
cls sig=Ljava/util/HashMap$HashIterator;
cls sig=Ljava/lang/StackOverflowError;
cls sig=Ljava/lang/IllegalMonitorStateException;
cls sig=Ljava/lang/ref/Reference;
cls sig=[Ljava/lang/ref/Reference;
cls sig=Ljava/lang/ref/SoftReference;
cls sig=Ljava/io/FileSystem;
cls sig=Ljava/lang/ref/WeakReference;
cls sig=[Ljava/lang/ref/WeakReference;
cls sig=Lsun/misc/JavaIOFileDescriptorAccess;
cls sig=Ljava/lang/ref/FinalReference;
cls sig=Ljava/util/zip/ZipFile$1;
cls sig=Ljava/lang/ref/PhantomReference;
cls sig=Ljava/lang/ref/Finalizer;
cls sig=Ljava/io/UnixFileSystem;
cls sig=Ljava/lang/InterruptedException;
cls sig=Ljava/lang/Thread;
cls sig=[Ljava/lang/Thread;
cls sig=Ljava/lang/Runnable;
cls sig=[Ljava/lang/Runnable;
cls sig=Ljava/lang/Long;
cls sig=Ljava/util/concurrent/ConcurrentHashMap;
cls sig=Ljava/util/concurrent/ConcurrentMap;
cls sig=Ljava/io/ExpiringCache;
cls sig=LTest$1;


启动时加载的结果:乱码,待查
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=

你可能感兴趣的:(JAVA)