从事此行业N年,遇到问题上去先是一通王八拳,能把问题打死,
就继续找下一个问题的茬,如果打不死,就再打一套王八拳,直至打死问题为止。
王八拳(不成体系的定位方法和手段)对付问题有效果,但是效率低,
我的王八拳主要是:
加log,编译,替库,运行,看log, 加log,编译,替库,运行,看log……
运用这种磨豆腐的磨劲,磨死了好多问题,但 碰到流程套路深的框架和体系,这个效率实在实在是太低了,
有时候能从java层跟到内核层,有种上穷碧落下黄泉的感觉,甚至最后还 两处茫茫皆不见。
后来升级王八拳至 王八拳V2.0,即增加调用栈的方式,编译替库一次,可以揪出一大窜流程
从java到内核的调用栈方法如下:
https://blog.csdn.net/u012188065/article/details/84667625
再后来,学会了 adb shell dumpsys, 可以dump media.audio_flinger, dump media.player 等进程
瞬间感觉到了人生的巅峰,使用之前是我给代码打工,使用之后是代码给我打工
可以参考此文 https://blog.csdn.net/u012188065/article/details/84255809 中的 部分专用调试命令 模块
再来后问题也开始迭代升级了(也有可能通用的问题很容易被这些通用的定位调试手段消灭掉,剩下来的都是特有问题),
原有手段命中率也开始下降,又逐渐回归到我给代码打工,还是996的那种。
是时候去总结一些特定的定位手段,把王八拳中有价值的招式提取处理,荟萃成少林长拳,武当剑法甚至凌波微步这些特定的招式,去打击特定的问题。
某天梳理video代码流程,发现OMXNodeIntance构造函数中有如下语句:
DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug");
机警如我的我,一看到property这几个字,就知道是一个动态开关
果不其然,文件头有大量控制log的宏,如下:
#define CLOGI_(level, fn, fmt, ...) \
ALOGI_IF(DEBUG >= (level), #fn "(%p:%s, " fmt ")", mHandle, mName, ##__VA_ARGS__)
#define CLOGD_(level, fn, fmt, ...) \
ALOGD_IF(DEBUG >= (level), #fn "(%p:%s, " fmt ")", mHandle, mName, ##__VA_ARGS__)
#define CLOG_LIFE(fn, fmt, ...) CLOGI_(ADebug::kDebugLifeCycle, fn, fmt, ##__VA_ARGS__)
#define CLOG_STATE(fn, fmt, ...) CLOGI_(ADebug::kDebugState, fn, fmt, ##__VA_ARGS__)
#define CLOG_CONFIG(fn, fmt, ...) CLOGI_(ADebug::kDebugConfig, fn, fmt, ##__VA_ARGS__)
#define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__)
代码中存在大量使用 CLOG_LIFE, CLOG_INTERNAL这些宏
通过设置的 DEBUG 与log级别中的 ADebug::kDebugLifeCycle, ADebug::kDebugState等级别比较
高于log中的级别就打印,低于就不打印。
log级别共有如下几个level, 见 ADebug.cpp
enum Level {
kDebugNone, // no debug
kDebugLifeCycle, // lifecycle events: creation/deletion
kDebugState, // commands and events
kDebugConfig, // configuration
kDebugInternalState, // internal state changes
kDebugAll, // all
kDebugMax = kDebugAll,
};
默认 property键值 “debug.stagefright.omx-debug” 未使能,为 kDebugNone,播放视频log如下:
02-03 10:49:47.266 13916 14190 I OMXNodeInstance: debug level for OMX.google.aac.decoder is 0, mName:google.aac.decoder
02-03 10:49:47.268 13916 14190 E OMXNodeInstance: setConfig(0xf2f26e40:google.aac.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001)
02-03 10:49:47.269 13916 14190 E OMXNodeInstance: setConfig(0xf2f26e40:google.aac.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001)
02-03 10:49:47.269 13916 14190 E OMXNodeInstance: getConfig(0xf2f26e40:google.aac.decoder, ConfigAndroidVendorExtension(0x6f100004)) ERROR: Undefined(0x80001001)
adb shell setprop debug.stagefright.omx-debug 1, 设置为kDebugLifeCycle后,
02-03 10:50:19.947 13916 14257 I OMXNodeInstance: debug level for OMX.google.aac.decoder is 1, mName:google.aac.decoder
02-03 10:50:19.948 13916 14257 I OMXNodeInstance: allocateNode(0x0:google.aac.decoder, handle=0xf2f262a0)
02-03 10:50:19.949 13916 14257 E OMXNodeInstance: setConfig(0