1. java代码中打印堆栈
(1) 通常的方法是使用exception的printStackTrace()方法:
try{
...
}catch(RemoteException e) {
e.printStackTrace();
...
}
(2) 测试Demo
classPerson {public voidperson_dump_stack() {try{throw new Exception("my_dump");
}catch(Exception e) {
e.printStackTrace();
}
}
}public classTest {public static voidmain(String[] args) {
Person p= newPerson();
p.person_dump_stack();
}
}
View Code
执行结果:
# java Test
java.lang.Exception: my_dump
at Person.person_dump_stack(Test.java:5)
at Test.main(Test.java:15)
View Code
(3) 当然也可以只打印堆栈不退出,Java代码中插入堆栈打印的方法如下:
Log.d(TAG, Log.getStackTraceString(new Throwable()));
(4) 测试Demo
Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES :=JavaDump.java
LOCAL_MODULE :=java_dump
include $(BUILD_JAVA_LIBRARY)
JavaDump.java:importandroid.util.Log;classAnimal {public voidanimal_dump_java_stack() {
String TAG= "java_dump: ";
Log.d(TAG, Log.getStackTraceString(newThrowable()));
}
}class Person extendsAnimal {public voidperson_dump_java_stack() {
animal_dump_java_stack();
}
}public classJavaDump {public static voidmain(String args[]) {
Person person= newPerson();
person.person_dump_java_stack();
}
}
View Code
执行结果:
1|shell@tiny4412:/system/mytest # dalvikvm -cp ./java_dump.jar JavaDump
java.lang.UnsatisfiedLinkError: No implementation foundfor int android.util.Log.println_native(int, int, java.lang.String, java.lang.String) (tried Java_android_util_Log_println_1native and Java_android_util_Log_println_1native__IILjava_lang_String_2Ljava_lang_String_2)
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:139)
at Animal.animal_dump_java_stack(JavaDump.java:7)
at Person.person_dump_java_stack(JavaDump.java:13)
at JavaDump.main(JavaDump.java:22)
View Code
这个效果是最好的,注意打印出来的还有类名和行号,可以避免类的继承关系带来的混淆。
2. C++代码中打印堆栈
(1) C++也是支持异常处理的,异常处理库中,已经包含了获取backtrace的接口,Android也是利用这个接口来打印堆栈信息的。在Android的C++中,
已经集成了一个工具类CallStack,在libutils.so中。使用方法:
#include ...
CallStack stack;/*void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_CURRENT_THREAD);*/stack.update();/*void dump(int fd, int indent = 0, const char* prefix = 0) const;*/stack.dump();
(2) 测试Demo
Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=CppDump.cpp
LOCAL_SHARED_LIBRARIES :=\
libcutils \
libutils \
liblog
LOCAL_MODULE:=cpp_dump
include $(BUILD_EXECUTABLE)
CppDump.cpp:#define LOG_TAG "dump_cpp: "
#define STDOUT 1#include
using namespaceandroid;classPerson {public:voidperson_dump_cpp() {
CallStack stack;
stack.update();
stack.dump(STDOUT,0, LOG_TAG);
}
};intmain() {
Person p1;
p1.person_dump_cpp();return 0;
}
View Code
执行结果:
shell@tiny4412:/system/mytest # ./cpp_dump
dump_cpp: #00 pc 00003035 /system/lib/libbacktrace.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
dump_cpp: #01 pc 0000d061 /system/lib/libutils.so (android::CallStack::update(int, int)+52)
dump_cpp: #02 pc 000003f9 /system/mytest/cpp_dump
dump_cpp: #03 pc 000128f1 /system/lib/libc.so (__libc_init+44)
dump_cpp: #04 pc 0000047c /system/mytest/cpp_dump
View Code
可以看出效果并不怎么好。