Skip to main content
 首页 » 编程设计

Android dump Java和C++函数调用栈

2022年07月19日24xiaohuochai

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)

这个效果是最好的,注意打印出来的还有类名和行号,可以避免类的继承关系带来的混淆。

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

可以看出效果并不怎么好。


本文参考链接:https://www.cnblogs.com/hellokitty2/p/10882632.html