dump Java和C++函数调用栈
1. java代码中打印堆栈
(1) 通常的方法是使用exception的printStackTrace()方法:
try { ... } catch (RemoteException e) { e.printStackTrace(); ... }
(2) 测试Demo
class Person { public void person_dump_stack() { try { throw new Exception("my_dump"); } catch (Exception e) { e.printStackTrace(); } } } public class Test { public static void main(String[] args) { Person p = new Person(); p.person_dump_stack(); } }
执行结果:
# java Test java.lang.Exception: my_dump at Person.person_dump_stack(Test.java:5) at Test.main(Test.java:15)
(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: import android.util.Log; class Animal { public void animal_dump_java_stack() { String TAG = "java_dump: "; Log.d(TAG, Log.getStackTraceString(new Throwable())); } } class Person extends Animal { public void person_dump_java_stack() { animal_dump_java_stack(); } } public class JavaDump { public static void main(String args[]) { Person person = new Person(); person.person_dump_java_stack(); } }
执行结果:
1|shell@tiny4412:/system/mytest # dalvikvm -cp ./java_dump.jar JavaDump java.lang.UnsatisfiedLinkError: No implementation found for 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)
这个效果是最好的,注意打印出来的还有类名和行号,可以避免类的继承关系带来的混淆。
补充:感觉下面这个好用一些
new RuntimeException("stack_dump").printStackTrace(); //打印栈回溯
2. C++代码中打印堆栈
(1) C++也是支持异常处理的,异常处理库中,已经包含了获取backtrace的接口,Android也是利用这个接口来打印堆栈信息的。在Android的C++中,
已经集成了一个工具类CallStack,在libutils.so中。使用方法:
#include <utils/CallStack.h> ... 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 <utils/CallStack.h> using namespace android; class Person { public: void person_dump_cpp() { CallStack stack; stack.update(); stack.dump(STDOUT, 0, LOG_TAG); } }; int main() { Person p1; p1.person_dump_cpp(); return 0; }
执行结果:
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
可以看出效果并不怎么好。
补充:可以参考下面
//frameworks/native/libs/binder/IPCThreadState.cpp CallStack::logStack("oneway spamming", CallStack::getCurrent().get(), ANDROID_LOG_ERROR);
这样C++代码的栈和Java代码的栈都可以打印出来。
posted on 2019-05-17 17:31 Hello-World3 阅读(525) 评论(0) 编辑 收藏 举报