Android Native庫的調試一直是個複雜的事,一般調試方法有輸出日誌和使用ADT等插件方法,前者較簡單,TouchVG就使用日誌輸出方式來調試定位:java
#include "mglog.h"
,在要調試的函數中調用 LOGD("your message %d", someint);
tag:dalvikvm|AndroidRuntime|vgjni|touchvg|vgstack|libc
最近遇到一些libc崩潰問題,須要在C++代碼中定位。首先須要定位JNI入口函數,而SWIG生成touchvg_java_wrap.cpp有4萬行代碼、1900多個JNI函數,不可能一個個去加日誌。python
固然寫腳本自動幹這事了,這裏是Python腳本內容。android
<!-- lang: python --> #!/usr/bin/env python # addlog.py: Add logging entry for each JNI function # author: Zhang Yungui <github.com/rhcad> # Usage: # 1. Call `python addlog.py` in jni/build.sh # 2. Then type `./build.sh -swig` to re-generate touchvg_java_wrap.cpp import os, re file = os.path.abspath('touchvg_java_wrap.cpp') text = open(file).read() blks = [] prog = re.compile(r'SWIGEXPORT (void|j).*{') funp = re.compile(r'Java_.*\(') funcstr = '''#include <android/log.h> struct TmpLogFunc { const char* name; TmpLogFunc(const char* name) : name(name) { __android_log_print(ANDROID_LOG_VERBOSE,"vgstack","%s enter",name); } ~TmpLogFunc() { __android_log_print(ANDROID_LOG_VERBOSE,"vgstack","%s exit",name); } };''' text = text.replace('struct TmpJOBJ {', funcstr + '\nstruct TmpJOBJ {') while True: match = prog.search(text) if match: pos = match.end() + 1 mfn = funp.search(text) name = text[mfn.start():mfn.end()-1] blks.append(text[:pos]) blks.append(r' TmpLogFunc logf("' + name + '\");\n') text = text[pos:] else: blks.append(text) break text = ''.join(blks) open(file, 'w').write(text)
在編寫腳本的過程當中,複習了正則表達式、字符串和列表的相互轉換方法。自動添加日誌後,當即定位到崩潰的JNI函數。而後逐級添加LOGD語句找到崩潰緣由:在一個擴展模塊中,對象在一個函數內釋放後,在外部函數繼續使用--野指針!git