Realizing an outputMixObject in the Android NDK with OpenSL ES causes crash of application
I am trying to implement OpenSL ES into a project of mine, but while doing so, I get a crash of my application. The error occurs when I try to realize an outputMixObject by calling it's realize method:
// Create OutputMixer.
result = (*engineInstance)->CreateOutputMix(engineInstance, &outputMixObject, 1, NULL, NULL);
assert(result == SL_RESULT_SUCCESS);
// Realize the OutputMixer.
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
When I run the application to test, I get the following log entries:
05-11 13:20:19.736: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-11 13:20:19.736: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/generic:2.3.1/GSI11/93351:eng/test-keys'
05-11 13:20:19.736: INFO/DEBUG(31): pid: 631, tid: 631 >>> org.test.opensl <<<
05-11 13:20:19.746: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
05-11 13:20:19.746: INFO/DEBUG(31): r0 00000000 r1 00000000 r2 00000000 r3 00000000
05-11 13:20:19.746: INFO/DEBUG(31): r4 82f01bdc r5 8380af69 r6 00000000 r7 418fccc4
05-11 13:20:19.746: INFO/DEBUG(31): r8 bee5f428 r9 418fccbc 10 418fcca4 fp 42596f38
05-1开发者_JAVA技巧1 13:20:19.746: INFO/DEBUG(31): ip 00000000 sp bee5f410 lr 8380af95 pc 82f009ae cpsr 40000030
05-11 13:20:19.986: INFO/DEBUG(31): #00 pc 000009ae /data/data/org.test.opensl/lib/libSLAudio.so
05-11 13:20:19.986: INFO/DEBUG(31): #01 pc 00017d34 /system/lib/libdvm.so
05-11 13:20:19.996: INFO/DEBUG(31): #02 pc 00048ec0 /system/lib/libdvm.so
05-11 13:20:20.007: INFO/DEBUG(31): #03 pc 00041a6a /system/lib/libdvm.so
05-11 13:20:20.007: INFO/DEBUG(31): #04 pc 0004e5dc /system/lib/libdvm.so
05-11 13:20:20.016: INFO/DEBUG(31): #05 pc 0001cf94 /system/lib/libdvm.so
05-11 13:20:20.016: INFO/DEBUG(31): #06 pc 0002209c /system/lib/libdvm.so
05-11 13:20:20.016: INFO/DEBUG(31): #07 pc 00020f90 /system/lib/libdvm.so
05-11 13:20:20.016: INFO/DEBUG(31): #08 pc 0005f50e /system/lib/libdvm.so
05-11 13:20:20.026: INFO/DEBUG(31): #09 pc 00066ed6 /system/lib/libdvm.so
05-11 13:20:20.026: INFO/DEBUG(31): #10 pc 0001cf94 /system/lib/libdvm.so
05-11 13:20:20.057: INFO/DEBUG(31): #11 pc 0002209c /system/lib/libdvm.so
05-11 13:20:20.057: INFO/DEBUG(31): #12 pc 00020f90 /system/lib/libdvm.so
05-11 13:20:20.057: INFO/DEBUG(31): #13 pc 0005f360 /system/lib/libdvm.so
05-11 13:20:20.066: INFO/DEBUG(31): #14 pc 0004b960 /system/lib/libdvm.so
05-11 13:20:20.066: INFO/DEBUG(31): #15 pc 0003eb64 /system/lib/libdvm.so
05-11 13:20:20.066: INFO/DEBUG(31): #16 pc 0003c15c /system/lib/libandroid_runtime.so
05-11 13:20:20.086: INFO/DEBUG(31): #17 pc 0003cf76 /system/lib/libandroid_runtime.so
05-11 13:20:20.086: INFO/DEBUG(31): #18 pc 00008ca2 /system/bin/app_process
05-11 13:20:20.086: INFO/DEBUG(31): #19 pc 00014db8 /system/lib/libc.so
05-11 13:20:20.097: INFO/DEBUG(31): code around pc:
05-11 13:20:20.106: INFO/DEBUG(31): 82f0098c 68116803 32201c22 479868db 1c216a20
05-11 13:20:20.106: INFO/DEBUG(31): 82f0099c 68032201 31189600 230069dd 69a047a8
05-11 13:20:20.106: INFO/DEBUG(31): 82f009ac 68032100 4798681b bd70b002 00001274
05-11 13:20:20.116: INFO/DEBUG(31): 82f009bc 00001228 0000002c 00000002 00000001
05-11 13:20:20.126: INFO/DEBUG(31): 82f009cc 007a1200 00000010 00000010 00000004
05-11 13:20:20.126: INFO/DEBUG(31): code around lr:
05-11 13:20:20.136: INFO/DEBUG(31): 8380af74 29002602 2000d01e 48106008 fcf8f7fd
05-11 13:20:20.136: INFO/DEBUG(31): 8380af84 9300ab05 9a031c39 1c049b0c fa9af7fe
05-11 13:20:20.136: INFO/DEBUG(31): 8380af94 d10f1e06 99051c20 f7fd9a02 1e04fec3
05-11 13:20:20.136: INFO/DEBUG(31): 8380afa4 2603d101 1c20e006 fa30f7fb f0011c20
05-11 13:20:20.136: INFO/DEBUG(31): 8380afb4 602cf8a3 1c30b007 46c0bdf0 00001009
05-11 13:20:20.136: INFO/DEBUG(31): stack:
05-11 13:20:20.136: INFO/DEBUG(31): bee5f3d0 82f01bf4 /data/data/org.test.opensl/lib/libSLAudio.so
05-11 13:20:20.136: INFO/DEBUG(31): bee5f3d4 00000002
05-11 13:20:20.146: INFO/DEBUG(31): bee5f3d8 00000001
05-11 13:20:20.146: INFO/DEBUG(31): bee5f3dc 8380af95 /system/lib/libOpenSLES.so
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3e0 bee5f3f4
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3e4 838089b9 /system/lib/libOpenSLES.so
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3e8 0029cea4 [heap]
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3ec 00000000
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3f0 00000000
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3f4 82f01bfc /data/data/org.test.opensl/lib/libSLAudio.so
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3f8 000001b4
05-11 13:20:20.156: INFO/DEBUG(31): bee5f3fc 82f01bdc /data/data/org.test.opensl/lib/libSLAudio.so
05-11 13:20:20.167: INFO/DEBUG(31): bee5f400 8380af69 /system/lib/libOpenSLES.so
05-11 13:20:20.167: INFO/DEBUG(31): bee5f404 00000000
05-11 13:20:20.167: INFO/DEBUG(31): bee5f408 df002777
05-11 13:20:20.176: INFO/DEBUG(31): bee5f40c e3a070ad
05-11 13:20:20.176: INFO/DEBUG(31): #00 bee5f410 00000000
05-11 13:20:20.176: INFO/DEBUG(31): bee5f414 00000000
05-11 13:20:20.176: INFO/DEBUG(31): bee5f418 bee5f448
05-11 13:20:20.186: INFO/DEBUG(31): bee5f41c 00000000
05-11 13:20:20.186: INFO/DEBUG(31): bee5f420 43d6e7c3 /data/dalvik-cache/data@app@org.test.opensl-2.apk@classes.dex
05-11 13:20:20.186: INFO/DEBUG(31): bee5f424 81d17d38 /system/lib/libdvm.so
05-11 13:20:20.186: INFO/DEBUG(31): #01 bee5f428 41adab28 /dev/ashmem/dalvik-LinearAlloc (deleted)
05-11 13:20:20.186: INFO/DEBUG(31): bee5f42c 0000ce48 [heap]
05-11 13:20:20.186: INFO/DEBUG(31): bee5f430 43d6e7c3 /data/dalvik-cache/data@app@org.test.opensl-2.apk@classes.dex
05-11 13:20:20.186: INFO/DEBUG(31): bee5f434 bee5f508
05-11 13:20:20.186: INFO/DEBUG(31): bee5f438 81d17f00 /system/lib/libdvm.so
05-11 13:20:20.186: INFO/DEBUG(31): bee5f43c 0000ce48 [heap]
05-11 13:20:20.186: INFO/DEBUG(31): bee5f440 bee5f448
05-11 13:20:20.186: INFO/DEBUG(31): bee5f444 81d48ec3 /system/lib/libdvm.so
Checking the program counter at #00, it shows that the method at address 000009ae caused the crash. Converting the address to the line at which it occurred in my source file, gives me the line of code where the Realize(outputMixObject, SL_BOOLEAN_FALSE
method is.
Note, I converted the address via the solution posted at this question: How to use addr2line in Android
However, I can't seem to make sense of it, which might be due to my inexperience with the NDK or C/OpenSL ES in general...
I test this on an Android 2.3.1 emulator. The code specified earlier is in an initialization method which initializes the engine for my application:
JNIEXPORT void JNICALL Java_org_test_opensl_AudioProcessor_createEngine(JNIEnv *env, jobject thiz){
SLresult result;
// Create engine.
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(result == SL_RESULT_SUCCESS);
// Realize the engine.
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
// Get the engine interface, required for the creation of all the other objects.
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineInstance);
assert(result == SL_RESULT_SUCCESS);
// Create OutputMixer.
result = (*engineInstance)->CreateOutputMix(engineInstance, &outputMixObject, 1, NULL, NULL);
assert(result == SL_RESULT_SUCCESS);
// Realize the OutputMixer.
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
}
If anybody could shed some light on this, it would be greatly appreciated...
result = (*engineInstance)->CreateOutputMix(engineInstance, &outputMixObject, 1, NULL, NULL);
You're supplying 1 as the numInterfaces parameter, and sending a NULL pointer for the pInterfaceIds param, which will result in a segfault at 0x00000000 somewhere inside opensl.
I'm not sure what would be causing the issue but the issue is that one of the pointers used on that line is invalid. Check that outputMixObject and *outputMixObject and (*outputMixObject)->Realize are not null.
Add something like
assert(outputMixObject);
assert(*outputMixObject);
assert((*outputMixObject)->Realize);
before that line to catch the error before it segfaults.
The issue I ran into here was that assert didn't work the way I wanted it to work... After some searching and a meaningful glance of a co-worker, I managed to find out that it was much better to do my own error checking instead of relying on assert.
So the bit of code where it was going wrong with the asserts now looks like this:
// Create OutputMixer.
result = (*engineInstance)->CreateOutputMix(engineInstance, &outputMixObject, 1, ids, req);
if(result != SL_RESULT_SUCCESS){
decodeResult(result);
LOG_ERROR("Unable to create output mix object");
return;
}
// Realize the OutputMixer.
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
if(result != SL_RESULT_SUCCESS){
decodeResult(result);
LOG_ERROR("Unable to realize output mix object");
}
Where decodeResult(result)
is a method that checks for any possible error states.
I know that this adds lines to the code, but now I know it works the way it should...
Maybe I should've done this from the beginning, as I've done this kind of error checking before. I don't know.... Anyway, this works...
精彩评论