mackron / miniaudio

Audio playback and capture library written in C, in a single source file.
https://miniaud.io
Other
4.07k stars 361 forks source link

Memory leaks in OpenSl (android) mode #422

Closed JPDelprat closed 2 years ago

JPDelprat commented 2 years ago

Hello,

I use miniaudio to capture sounds in my android application. I use opensl.

For each sound, I initialize/unitialize the device (=> all calls are successful).

I got memory leaks on the following line, for each sound I've recorded.

    resultSL = MA_OPENSL_OBJ(pDevice->opensl.pAudioRecorderObj)->Realize((SLObjectItf)pDevice->opensl.pAudioRecorderObj, SL_BOOLEAN_FALSE);

Leaks are in:

1) libaudioclient.so | android::RecordingActivityTracker::RecordingActivityTracker() libaudioclient.so | android::AudioRecord::set(audio_source_t, unsigned int, audio_format_t, unsigned int, unsigned long, void ()(int, void, void), void, unsigned int, bool, audio_session_t, android::AudioRecord::transfer_type, audio_input_flags_t, unsigned int, int, audio_attributes_t const, int, audio_microphone_direction_t, float) libaudioclient.so | android::AudioRecord::AudioRecord(audio_source_t, unsigned int, audio_format_t, unsigned int, android::String16 const&, unsigned long, void ()(int, void, void), void, unsigned int, audio_session_t, android::AudioRecord::transfer_type, audio_input_flags_t, unsigned int, int, audio_attributes_t const, int, audio_microphone_direction_t, float) libwilhelm.so | 0x1e1dc libwilhelm.so | 0x32478 ma_device_init__opensl(miniaudio.h:37427:20)

2) libaudioclient.so | android::AudioSystem::get_audio_flinger() libaudioclient.so | android::AudioRecord::createRecord_l(android::Modulo const&, android::String16 const&) libaudioclient.so | android::AudioRecord::set(audio_source_t, unsigned int, audio_format_t, unsigned int, unsigned long, void ()(int, void, void), void, unsigned int, bool, audio_session_t, android::AudioRecord::transfer_type, audio_input_flags_t, unsigned int, int, audio_attributes_t const, int, audio_microphone_direction_t, float) libaudioclient.so | android::AudioRecord::AudioRecord(audio_source_t, unsigned int, audio_format_t, unsigned int, android::String16 const&, unsigned long, void ()(int, void, void), void, unsigned int, audio_session_t, android::AudioRecord::transfer_type, audio_input_flags_t, unsigned int, int, audio_attributes_t const, int, audio_microphone_direction_t, float) libwilhelm.so | 0x1e1dc libwilhelm.so | 0x32478 ma_device_init__opensl(miniaudio.h:37427:20)

3) libutils.so | android::RefBase::RefBase() libbinder.so | android::BBinder::BBinder() libaudioclient.so | android::RecordingActivityTracker::RecordingActivityTracker() libaudioclient.so | android::AudioRecord::set(audio_source_t, unsigned int, audio_format_t, unsigned int, unsigned long, void ()(int, void, void), void, unsigned int, bool, audio_session_t, android::AudioRecord::transfer_type, audio_input_flags_t, unsigned int, int, audio_attributes_t const, int, audio_microphone_direction_t, float) libaudioclient.so | android::AudioRecord::AudioRecord(audio_source_t, unsigned int, audio_format_t, unsigned int, android::String16 const&, unsigned long, void ()(int, void, void), void, unsigned int, audio_session_t, android::AudioRecord::transfer_type, audio_input_flags_t, unsigned int, int, audio_attributes_t const, int, audio_microphone_direction_t, float) libwilhelm.so | 0x1e1dc libwilhelm.so | 0x32478 ma_device_init__opensl(miniaudio.h:37427:20)

I don't know opensl at all. Do you have any idea about the reason for these memory leaks ? If you don't, feel free to close this issue . I'm afraid the leak is in android aosp libraries.

Thanks

mackron commented 2 years ago

I don't know what would be causing this. Certainly I'm destroying the audio recorder object when the device is uninitialized:

if (pDevice->opensl.pAudioRecorderObj) {
    MA_OPENSL_OBJ(pDevice->opensl.pAudioRecorderObj)->Destroy((SLObjectItf)pDevice->opensl.pAudioRecorderObj);
}

Could you maybe put a break point on the line above and confirm that it's getting hit? I didn't think there was anything else I needed to do for cleaning up with OpenSL.

JPDelprat commented 2 years ago

Thanks for your answer.

I added a breakpoint and I confirm it’s getting hit.

mackron commented 2 years ago

OK. I don't know what needs to be done to fix this. If it's an error in miniaudio I'll need more information because there's just not enough for me to go on.

Are you getting a memory leak for every device init/uninit or is it just a single memory leak for all devices?

JPDelprat commented 2 years ago

I get a memory leak for each device init/uninit. That’s why it may be a little annoying for me.

I understand that you have more important things to be done. I just wanted to know if you had a clue.

Don’t bother trying to investigate this more.

Thanks again,

mackron commented 2 years ago

Since the leak appears to be happing from inside Android itself, if miniaudio is at fault it'll be due to me not uninitializing some object. From what I can see it looks fine to me. I'll set this to "help wanted" in case the community might have some advice, but will close this issue after some time if there's no response or other reports.

What version of Android are you running on by the way? Are you getting a memory leak on all versions? Another thing you could try is initializing one ma_context object, and then pass that into each of your ma_device_init() calls. That way, if the memory leak is coming from the context it'll show only one memory leak, whereas if it's coming from the device it'll show many memory leaks. Then we can narrow it down a bit.

JPDelprat commented 2 years ago

I am running android api 29 (android 10.0). I cannot test on another version easily because my application use aosp libraries.

In my code, I didn't create a ma_context myself today, since I'm using the ma_device_init_ex function.

In order to test, I've just modified my program to create a ma_context (only once), and call ma_device_init(&context) instead :

Anyway, as I said previously, this is not a big deal. Don't worry about it. Memory leaks are small (60-100 bytes on each call). I was just hoping that these memory leaks could explain more important ones, which also occurs in android libraries, but are limited to 3 occurrences, even if I record more sounds.

Total leak size : 20952 (in 3 allocations) libaudioclient.so | android::BnAudioFlingerClient::onTransact(unsigned int, android::Parcel const&, android::Parcel, unsigned int) libbinder.so | android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel, unsigned int) libbinder.so | android::IPCThreadState::executeCommand(int) libbinder.so | android::IPCThreadState::getAndExecuteCommand() libbinder.so | android::IPCThreadState::joinThreadPool(bool) libbinder.so | 0x7eef4 libutils.so | android::Thread::_threadLoop(void*) libc.so | 0xe2390

mackron commented 2 years ago

I'm going to go ahead and close this one. If someone from the community with better knowledge of Android than myself is able to give me some advice about this I'm more than happy to reopen this one.