1. 程式人生 > >android ndk 崩潰捕獲(cocos2d-x 之android崩潰捕獲)

android ndk 崩潰捕獲(cocos2d-x 之android崩潰捕獲)

ndk 崩潰捕獲 ,我們可以採用

breakpad是一個跨平臺的c++崩潰處理系統。
包括:dmp生成模組、 上傳模組、 伺服器儲存模組、解析dmp模組 等。

這裡我只大概說一下dmp生成模組。

1、編譯靜態庫
解壓並拷貝breakpad原始碼目錄到專案中,編譯:

指令碼如下:

LOCAL_PATH := $(call my-dir)

# Defube the client library module, as a simple static library that
# exports the right include path / linker flags to its users.

include $(CLEAR_VARS)

LOCAL_MODULE := breakpad_client_static
LOCAL_MODULE_FILENAME := breakpad_client

LOCAL_CPP_EXTENSION := .cc

# Breakpad uses inline ARM assembly that requires the library
# to be built in ARM mode. Otherwise, the build will fail with
# cryptic assembler messages like:
#   Compile++ thumb  : google_breakpad_client <= crash_generation_client.cc
#   /tmp/cc8aMSoD.s: Assembler messages:
#   /tmp/cc8aMSoD.s:132: Error: invalid immediate: 288 is out of range
#   /tmp/cc8aMSoD.s:244: Error: invalid immediate: 296 is out of range
LOCAL_ARM_MODE := arm

# List of client source files, directly taken from Makefile.am
LOCAL_SRC_FILES := \
    src/client/linux/crash_generation/crash_generation_client.cc \
    src/client/linux/handler/exception_handler.cc \
    src/client/linux/handler/minidump_descriptor.cc \
    src/client/linux/log/log.cc \
    src/client/linux/minidump_writer/linux_dumper.cc \
    src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
    src/client/linux/minidump_writer/minidump_writer.cc \
    src/client/minidump_file_writer.cc \
    src/common/android/breakpad_getcontext.S \
    src/common/convert_UTF.c \
    src/common/md5.cc src/common/string_conversion.cc \
    src/common/linux/elfutils.cc \
    src/common/linux/file_id.cc \
    src/common/linux/guid_creator.cc \
    src/common/linux/linux_libc_support.cc \
    src/common/linux/memory_mapped_file.cc \
    src/common/linux/safe_readlink.cc

LOCAL_C_INCLUDES        := $(LOCAL_PATH)/src/common/android/include \
                           $(LOCAL_PATH)/src

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_EXPORT_LDLIBS     := -llog

include $(BUILD_STATIC_LIBRARY)

2、這編譯生成的breakpad_client.a檔案就可以直接匯入我們工程直接使用了

3、在我們工程專案中新增這個庫的初始化程式碼

包含標頭檔案

#include "client/linux/handler/exception_handler.h"
#include "client/linux/handler/minidump_descriptor.h"
#include "client/linux/log/log.h"

void InitCrash()
{
#ifdef ANDROID

    std::string s_strOutPath_Debug = FORMAT("%s/%s") << GetDocumentPath() << "Debug";
    DebugMsg("InitCrashReport: %s\n ", s_strOutPath_Debug.c_str());
   //設定生成dmp的路徑
    static google_breakpad::MinidumpDescriptor descriptor(s_strOutPath_Debug);
    static google_breakpad::ExceptionHandler eh(descriptor, NULL, DumpCallback,
        NULL, true, -1);

#endif
}

//dmp回撥

bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
    void* context,
    bool succeeded)
{
        DebugMsg("Dump path: %s\n succeeded:%d", descriptor.path(), succeeded==true?1:0);

        if(!succeeded)
        {
            std::remove(descriptor.path());
        }
        return succeeded;
}

4、生成了dmp我們就要開始怎麼去解析呢?

在解析這個4f46eb83-d5e8-91dc-3ba0eec4-20a1eabe.dmp 這樣一個dump檔案之前,我們要準備dump_syms、minidump_stackwalk這兩個檔案

這個兩個檔案怎麼生成的,可以下載google_breakpad這個開原始碼,到linux環境下進行編譯既可以出來,後面我們在解析4f46eb83-d5e8-91dc-3ba0eec4-20a1eabe.dmp這個檔案,我們還要儲存我們的符號檔案例如: 這個裡面libzerg.so就是我們要儲存的符號檔案,後面就是把這些檔案準備到一個資料夾下如圖:

然後就是按下面的步驟:

adb push E:/android/android-sdk-windows/android-sdk-windows/platform-tools/10000 /data/local/tmp/10000
adb shell
cd /data/local/tmp/10000

chmod 777 libzerg.so
chmod 777 dump_syms
chmod 777 minidump_stackwalk

./dump_syms ./libzerg.so>libzerg.so.sym
busybox head -n1 libzerg.so.sym

注意:E21A4C5B4525F184923BC20F0D8557170這個是通過busybox head -n1 libzerg.so.sym這個命令生成

mkdir symbols
cd symbols
mkdir libzerg.so
cd libzerg.so
mkdir E21A4C5B4525F184923BC20F0D8557170
cd /data/local/tmp/10000
cat libzerg.so.sym> ./symbols/libzerg.so/E21A4C5B4525F184923BC20F0D8557170/libzerg.so.sym

cd /data/local/tmp/10000
mkdir res
./minidump_stackwalk 4f46eb83-d5e8-91dc-3ba0eec4-20a1eabe.dmp ./symbols

執行到這裡就會生成:

這樣整個崩潰解析就算完成了