RenderHeads / UnityPlugin-AVProMovieCapture

AVPro Movie Capture is a Unity Plugin for advanced video capture to AVI/MP4/MOV files
https://renderheads.com/products/avpro-movie-capture/
48 stars 8 forks source link

Crash on Android when capturing audio from microphone #203

Closed artoonie closed 1 year ago

artoonie commented 1 year ago

Describe the bug Looks like the race condition fixed in #184 is still appearing occasionally

Your Setup (please complete the following information):

To Reproduce Not sure, I'm getting the following stack in the Unity Dashboard:

0   libAVProMovieCaptureNative.so      0x0000006c1aaa84ec PluginAudioInputDevice::UnprepareRecording() 
1   libAVProMovieCaptureNative.so      0x0000006c1ab1d9b8 VideoRecorderAPI28::cleanup(bool) 
2   libAVProMovieCaptureNative.so      0x0000006c1ab1d82c VideoRecorderAPI28::~VideoRecorderAPI28() 
3   libAVProMovieCaptureNative.so      0x0000006c1ab1dab4 VideoRecorderAPI28::~VideoRecorderAPI28() 
4   libAVProMovieCaptureNative.so      0x0000006c1ab179f4 std::__ndk1::__compressed_pair_elem<std::__ndk1::allocator<IVideoRecorder>, 1, true>::__compressed_pair_elem<std::__ndk1::allocator<IVideoRecorder>, void>(std::__ndk1::allocator<IVideoRecorder>&&) 
5   libAVProMovieCaptureNative.so      0x0000006c1ab17798 std::__ndk1::__shared_ptr_pointer<IVideoRecorder*, std::__ndk1::default_delete<IVideoRecorder>, std::__ndk1::allocator<IVideoRecorder> >::__on_zero_shared() 
6   libAVProMovieCaptureNative.so      0x0000006c1ab71ab8 std::__ndk1::__shared_weak_count::__add_weak() 

Unfortunately, I haven't been able to reproduce this myself, so I can't give steps to reproduce. Is there another potential race condition in UnprepareRecording?

It happens soon after StopCapture is called, and after [AVProMovieCapture] File processing complete is written to the log file.

MorrisRH commented 1 year ago

Slightly confused, the race condition was on iOS.

artoonie commented 1 year ago

Ah, you're right - not sure what the fix for #184 was, but this seems potentially related (at the very least, both happen in UnprepareRecording).

MorrisRH commented 1 year ago

Which is the odd part, UnprepareRecording is now the least exciting function you can imagine and does very little. I moved the important bits to StopRecording. This would suggest that StopRecording isn't being called.

If it's possible, can you get a full crash log? Not entirely sure where to look otherwise.

artoonie commented 1 year ago

Hm, unfortunately only four users have encountered this, and I don't currently have a way to contact them to get more information. I'm limited to what Debug.Log will tell, until I can find a way to reproduce.

Is it possible that the call stack is optimized, and the actual bug lies in a function which was compiler-inlined into UnprepareRecording?

I will keep an eye on logs and see if I can gather any more insight.

artoonie commented 1 year ago

I got slightly more verbose logs from adb logcat --buffer=crash. This happened on a Pixel 2. It looks like a shared pointer issue, maybe a double-free on a IVideoRecorder?

E AndroidRuntime: FATAL EXCEPTION: UnityMain
E AndroidRuntime: Process: com.com.app, PID: 5759
E AndroidRuntime: java.lang.Error: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
E AndroidRuntime: Version '2021.3.7f1 (24e8595d6d43)', Build type 'Release', Scripting Backend 'il2cpp', CPU 'arm64-v8a'
E AndroidRuntime: Build fingerprint: 'google/walleye/walleye:11/RP1A.201005.004.A1/6934943:user/release-keys'
E AndroidRuntime: Revision: 'MP1'
E AndroidRuntime: ABI: 'arm64'
E AndroidRuntime: Timestamp: 2022-10-07 14:29:53-0400
E AndroidRuntime: pid: 5759, tid: 5840, name: UnityMain  >>> com.com.app <<<
E AndroidRuntime: uid: 10196
E AndroidRuntime: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
E AndroidRuntime: Cause: null pointer dereference
E AndroidRuntime:     x0  00000079b14b0990  x1  0000007bd2531644  x2  00000000000a6760  x3  0000000000000000
E AndroidRuntime:     x4  00000000000170de  x5  000000794151cb00  x6  00000079c14d6e00  x7  00000079c1470020
E AndroidRuntime:     x8  0000000000000000  x9  00000079b14b0990  x10 0000000000001f44  x11 0000007bd252fe90
E AndroidRuntime:     x12 0000000000000068  x13 00000079c14da660  x14 00195abc29a9f9a7  x15 0000000009e34c66
E AndroidRuntime:     x16 00000077e09ec148  x17 00000077e08e3490  x18 0000007840c086f8  x19 0000007961589b00
E AndroidRuntime:     x20 0000007961589b10  x21 0000000000000000  x22 00000078bfd443d0  x23 0000000000000000
E AndroidRuntime:     x24 00000078bfd8b7a8  x25 00000078bfd566e8  x26 00000078bfd5c458  x27 00000078bfd44ec8
E AndroidRuntime:     x28 00000078bfd5c468  x29 00000078d211dc00
E AndroidRuntime:     sp  00000078d211dbf0  lr  00000077e09589bc  pc  00000077e08e34ec
E AndroidRuntime: 
E AndroidRuntime: backtrace:
E AndroidRuntime:       #00 pc 000000000011d4ec  /.../libAVProMovieCaptureNative.so (PluginAudioInputDevice::UnprepareRecording()+92) (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime:       #01 pc 00000000001929b8  /.../libAVProMovieCaptureNative.so (VideoRecorderAPI28::cleanup(bool)+156) (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime:       #02 pc 000000000019282c  /.../libAVProMovieCaptureNative.so (VideoRecorderAPI28::~VideoRecorderAPI28()+360) (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime:       #03 pc 0000000000192ab4  /.../libAVProMovieCaptureNative.so (VideoRecorderAPI28::~VideoRecorderAPI28()+32) (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime:       #04 pc 000000000018c9f4  /.../libAVProMovieCaptureNative.so (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime:       #05 pc 000000000018c798  /.../libAVProMovieCaptureNative.so (std::__ndk1::__shared_ptr_pointer<IVideoRecorder*, std::__ndk1::default_delete<IVideoRecorder>, std::__ndk1::allocator<IVideoRecorder> >::__on_zero_shared()+68) (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime:       #06 pc 00000000001e6ab8  /.../libAVProMovieCaptureNative.so (BuildId: ddef6a1436313d0045e02550bad874418ff8f06c)
E AndroidRuntime: 
E AndroidRuntime:        at libAVProMovieCaptureNative.PluginAudioInputDevice::UnprepareRecording()(UnprepareRecording:92)
E AndroidRuntime:        at libAVProMovieCaptureNative.VideoRecorderAPI28::cleanup(bool)(cleanup:156)
E AndroidRuntime:        at libAVProMovieCaptureNative.VideoRecorderAPI28::~VideoRecorderAPI28()(~VideoRecorderAPI28:360)
E AndroidRuntime:        at libAVProMovieCaptureNative.VideoRecorderAPI28::~VideoRecorderAPI28()(~VideoRecorderAPI28:32)
E AndroidRuntime:        at libAVProMovieCaptureNative.0x18c9f4(Native Method)
E AndroidRuntime:        at libAVProMovieCaptureNative.std::__ndk1::__shared_ptr_pointer<IVideoRecorder*, std::__ndk1::default_delete<IVideoRecorder>, std::__ndk1::allocator<IVideoRecorder> >::__on_zero_shared()(__on_zero_shared:68)
E AndroidRuntime:        at libAVProMovieCaptureNative.0x1e6ab8(Native Method)
MorrisRH commented 1 year ago

I have a possible fix for this (unfortunately I've not been able to reproduce it though in order to test). It all stems from the overlap between stopping a recording and starting a new one before the file writing handler has completed which is something we hadn't anticipated when writing this originally (although with hindsight does seem a bit obvious).

Chris-RH commented 1 year ago

The next version has been released, please let us know if this has not fixed the issue.