理解Android本机代码崩溃报告

理解Android本机代码崩溃报告,android,c++,android-ndk,Android,C++,Android Ndk,好吧,我的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 6b843a

好吧,我的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++代码中找到这个崩溃。< /P> 在上面的回溯中,
+249
+20
是什么意思?我猜这是从例程的开始到子程序调用的偏移量。但它是用什么单位来衡量的呢

ip00000003
如何帮助我?我猜这是一个指令指针。。。然后呢

<>我的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
}
void SoundManagerImpl::startChannel(const SndChannelData&data)
{
int const nChannel=data.nChannel;
dbgAssert(nChannel>=0&&nChannelCreateAudioPlayer(引擎、m_播放器、音频源和音频接收器、,
GP_普通_阵列_LEN(需要s_)、s_iidArray、s_需要);
dbgAssertEq(SL_结果_成功,状态);
//……等等
}

<> P>请问有谁能帮我找到碰撞报告中的魔法数字与C++代码之间的关系?< /P> < P>你应该看看位于你的Android NDK目录根的<代码> NDK堆栈< /C>。它将这样一个崩溃报告转换成一些更易于阅读的崩溃堆栈

只需将logcat导入其中并指定库的位置:

adb logcat | ndk-stack -sym /path/to/myapp.so
(假设
adb
ndk堆栈
都在您的路径中,否则使用完整路径)


希望这有帮助

您应该看看位于Android ndk目录根目录下的
ndk堆栈。它将这样一个崩溃报告转换成一些更易于阅读的崩溃堆栈

只需将logcat导入其中并指定库的位置:

adb logcat | ndk-stack -sym /path/to/myapp.so
(假设
adb
ndk堆栈
都在您的路径中,否则使用完整路径)


希望这有帮助

NDK工具链包括一个名为的工具。你可以翻译

#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工具链):


请注意,我从
obj
目录中提供了
--executable
,在那里我有.so文件和额外的信息,当安装到
libs/armeabi

NDK工具链中时,该文件会被剥离,包括一个名为。你可以翻译

#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工具链):

请注意,我从
obj
目录中提供了
--executable
,在那里我有.so文件和额外信息,当安装到
libs/armeabi

ip
中时,该文件被剥离为“过程内调用暂存器”。ARM程序计数器(指令指针)寄存器称为
pc
ip
是“过程内调用暂存寄存器”。ARM程序计数器(指令指针)寄存器称为
pc