了解 Android 原生代码崩溃报告
Understanding Android Native code crash report
好的,我的 NDK 应用程序崩溃了,并显示如下信息:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
r0 00000000 r1 0009a830 r2 698a2efc r3 2a63f4da
r4 66db37ac r5 698a2efc r6 6b843b14 r7 66d89ed4
r8 6b6e0ff5 r9 6b746000 sl 697e0680 fp 401912ec
ip 00000003 sp 6b843a90 lr 66d9d7dd pc 6b69ac36 cpsr 000d0030
d0 4c555345525f4c53 d1 4e4f434552505f54
d2 5f534e4f49544944 d3 444554414c4f4956
d4 0000000000000000 d5 000000003f800000
d6 000084c03f800000 d7 3f8000003f800000
d8 0000000000000000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 00000a3dcc4f35c1 d17 ffff000000010000
d18 3ff8099d80000000 d19 0000000000000000
d20 3ff0000000000000 d21 0000000000000000
d22 c040000000000000 d23 0000000000000000
d24 3ff8099d80000000 d25 0000000000000000
d26 3ff0000000000000 d27 0000000000000000
d28 3ff8099d80000000 d29 c040000000000000
d30 0000000000000000 d31 0000000000000000
scr 20000010
backtrace:
#00 pc 000dec36 /mnt/asec/com.myapp/lib/myapp.so (HWLayer::SoundManagerImpl::MyChannel::start(SLEngineItf_ const* const*, SLObjectItf_ const* const*, HWLayer::SndChannelData const&)+249)
#01 pc 000decb1 /mnt/asec/com.myapp/lib/myapp.so (HWLayer::SoundManagerImpl::startChannel(HWLayer::SndChannelData const&)+20)
#02 pc 000cb2f3 /mnt/asec/com.myapp/lib/myapp.so (ChannelController::start(GPSoundObjectImpl*, bool)+242)
我想如何在我的C++代码中找到此崩溃。
+249
或+20
在上面的回溯中是什么意思?我想这是从例程开始到子例程调用的一些偏移。但是用什么单位来衡量呢?
ip 00000003
如何帮助我?我想这是一个指令指针...什么?
我的C++代码看起来像
void SoundManagerImpl::startChannel( const SndChannelData& data )
{
int const nChannel = data.nChannel;
dbgAssert(nChannel >= 0 && nChannel < m_maxNumChannels);
m_channels[nChannel].start(m_engineEngine, m_outputMix, data);
}
void SoundManagerImpl::MyChannel::start(SLEngineItf engine, SLObjectItf outputMix, SndChannelData const &data)
{
stop();
dbgAssertEq(16, data.bps);
m_numPlayedPages = 0;
m_pBuffer1 = data.pBuffer1;
m_pBuffer2 = data.pBuffer2;
SLresult status;
SLDataLocator_BufferQueue bufferQueue;
SLDataFormat_PCM pcm;
SLDataSource audioSource;
audioSource.pFormat = &pcm;
audioSource.pLocator = &bufferQueue;
/* Setup the data source structure for the buffer queue */
bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
bufferQueue.numBuffers = data.nTotalPages;
/* Setup the format of the content in the buffer queue */
pcm.formatType = SL_DATAFORMAT_PCM;
pcm.numChannels = (m_pBuffer2 != 0) ? 2 : 1;
pcm.samplesPerSec = /*SL_SAMPLINGRATE_44_1*/data.sampleRate * 1000;
pcm.bitsPerSample = /*SL_PCMSAMPLEFORMAT_FIXED_16*/data.bps;
pcm.containerSize = pcm.bitsPerSample;
pcm.channelMask = 1 == pcm.numChannels ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
SLDataSink audioSink;
SLDataLocator_OutputMix locator_outputmix;
locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
locator_outputmix.outputMix = outputMix;
audioSink.pLocator = &locator_outputmix;
audioSink.pFormat = 0;
static SLboolean const s_required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
static SLInterfaceID const s_iidArray[] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
dbgCompileAssert(GP_PLAIN_ARRAY_LEN(s_required) == GP_PLAIN_ARRAY_LEN(s_iidArray));
status = (*engine)->CreateAudioPlayer(engine, &m_player, &audioSource, &audioSink,
GP_PLAIN_ARRAY_LEN(s_required), s_iidArray, s_required);
dbgAssertEq(SL_RESULT_SUCCESS, status);
// ... and so on
}
谁能帮我找到崩溃报告中的那些神奇数字和这个C++代码之间的对应关系?
您应该查看位于Android NDK目录根目录的ndk-stack
。它将此类崩溃报告转换为一些更易于人类阅读的崩溃堆栈。
只需将日志猫通过管道插入其中并指定库的位置:
adb logcat | ndk-stack -sym /path/to/myapp.so
(假设adb
和ndk-stack
都在您的路径中,否则使用完整路径)
希望这有帮助!
NDK工具链包含一个名为addr2line的工具。你可以解释
#00 pc 000dec36 /mnt/asec/com.myapp/lib/myapp.so (HWLayer::SoundManagerImpl::MyChannel::start(SLEngineItf_ const* const*, SLObjectItf_ const* const*, HWLayer::SndChannelData const&)+249)
像这样(对于 ARM GCC 工具链):
~/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-addr2line -Cf -e obj/local/armeabi/myapp.so dec36
请注意,我提供了obj
目录中的--executable
,那里有带有额外 inprmation 的 .so 文件,当安装到 libs/armeabi
中时会剥离该文件。
相关文章:
- 当回溯以零开始时,如何调试崩溃
- Android NDK传感器向事件队列报告奇怪的间隔
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 使用std::source_location报告错误的最佳实践
- 程序崩溃并显示"std::out_of_range"错误
- xmake总是报告:错误:无法获取cxx的程序,为什么
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- iOS崩溃报告象征无DSYM-二进制中看到的地址之外的符号地址
- 是否有支持C++和C#混合应用程序的崩溃报告服务
- 在 macOS 上以编程方式检索崩溃报告
- Clang-Linux:报告CFI错误而不会崩溃.ftrap功能和-O2
- 如果测试程序崩溃,Valgrind报告是否可信
- 为c++应用程序创建崩溃转储报告
- 崩溃报告中的CPU寄存器地址在分析中如何有用
- 第一次阅读崩溃报告
- 了解 Android 原生代码崩溃报告
- 跨平台崩溃报告