cordova-plugin-media icon indicating copy to clipboard operation
cordova-plugin-media copied to clipboard

iOS: Crash in [CDVSound startPlayingAudio:] with version 3.0.1 and 5.0.2

Open sjkummer opened this issue 7 years ago • 7 comments

Hi there,

I am receiving crashreports from my users (via iTunesConnect) related to [CDVSound startPlayingAudio:]

It is very hard to reproduce this issue and it does not occur very often. May be releated to specific usage, devices or threading.

I wonder if this issue is already known and potentially fixed. I'll upgrade to version 5.0.1 and let you know if it still occurs.

Full logfile cdv.crash.txt

Interesting log sections:

Thread 32 Crashed:
0   AVFAudio                      	0x000000018a25880c AVAudioPlayerCpp::AQOutputCallbackCore(OpaqueAudioQueue*, AudioQueueBuffer*) + 180 (AVAudioPlayerCpp.mm:1250)
1   AVFAudio                      	0x000000018a257e84 AVAudioPlayerCpp::prepareToPlayQueue() + 224 (AVAudioPlayerCpp.mm:883)
2   AVFAudio                      	0x000000018a257e84 AVAudioPlayerCpp::prepareToPlayQueue() + 224 (AVAudioPlayerCpp.mm:883)
3   AVFAudio                      	0x000000018a257fe0 AVAudioPlayerCpp::playQueue(AudioTimeStamp const*) + 112 (AVAudioPlayerCpp.mm:956)
4   AVFAudio                      	0x000000018a256760 AVAudioPlayerCpp::play() + 80 (AVAudioPlayerCpp.mm:667)
5   AVFAudio                      	0x000000018a218414 -[AVAudioPlayer play] + 52 (AVAudioPlayer.mm:455)
6   MYAPP                 	        0x00000001041a16d4 __30-[CDVSound startPlayingAudio:]_block_invoke + 1648 (CDVSound.m:402)
7   libdispatch.dylib             	0x00000001841b4aa0 _dispatch_call_block_and_release + 24 (init.c:994)
8   libdispatch.dylib             	0x00000001841b4a60 _dispatch_client_callout + 16 (object.m:507)
9   libdispatch.dylib             	0x00000001841bbb84 _dispatch_queue_override_invoke$VARIANT$mp + 716 (inline_internal.h:2500)
10  libdispatch.dylib             	0x00000001841c1cac _dispatch_root_queue_drain + 588 (inline_internal.h:2539)
11  libdispatch.dylib             	0x00000001841c19fc _dispatch_worker_thread3 + 120 (queue.c:6092)
12  libsystem_pthread.dylib       	0x00000001844e7fac _pthread_wqthread + 1176 (pthread.c:2297)
13  libsystem_pthread.dylib       	0x00000001844e7b08 start_wqthread + 4

sjkummer avatar Aug 24 '18 10:08 sjkummer

Hi,

Unfortunately, I still got some crash reports after upgrading to version 5.0.2

I may have to add, that I am playing two files at the same time.

To me, this looks like a multi threading problem. As far as I can see this cordova plugin is not thread safe, is this correct?

Investigation:

  1. In my crash dump / stacktrace, I got multiple threads that are currently in [CDVSound prepareToPlay]
  2. [CDVSound prepareToPlay] starts with a [self.commandDelegate runInBackground:^{
  3. runInBackground is just a dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block);
  4. The dispatch_get_global_queue is a concurrent queue, so it does not help for thread safety / thread sync of the executed tasks, see: https://developer.apple.com/documentation/dispatch/1452927-dispatch_get_global_queue

Please let me know, if I am missing something 😳

Full Log: full_crash_log_5.0.1.txt

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x41534e57171614cb
VM Region Info: 0x41534e57171614cb is not in any region.  Bytes after previous region: 4707192163435680972  
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      MALLOC_NANO (reserved) 00000001d8000000-00000001e0000000 [128.0M] rw-/rwx SM=NUL  ...(unallocated)
--->  
      UNUSED SPACE AT END

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread:  14

Thread 14 name:
Thread 14 Crashed:
0   AVFAudio                      	0x000000018a9a880c AVAudioPlayerCpp::AQOutputCallbackCore(OpaqueAudioQueue*, AudioQueueBuffer*) + 180 (AVAudioPlayerCpp.mm:1250)
1   AVFAudio                      	0x000000018a9a7e84 AVAudioPlayerCpp::prepareToPlayQueue() + 224 (AVAudioPlayerCpp.mm:883)
2   AVFAudio                      	0x000000018a9a7e84 AVAudioPlayerCpp::prepareToPlayQueue() + 224 (AVAudioPlayerCpp.mm:883)
3   AVFAudio                      	0x000000018a9a7fe0 AVAudioPlayerCpp::playQueue(AudioTimeStamp const*) + 112 (AVAudioPlayerCpp.mm:956)
4   AVFAudio                      	0x000000018a9a6760 AVAudioPlayerCpp::play() + 80 (AVAudioPlayerCpp.mm:667)
5   AVFAudio                      	0x000000018a968414 -[AVAudioPlayer play] + 52 (AVAudioPlayer.mm:455)
6   MYAPP                           	0x0000000102b53484 __30-[CDVSound startPlayingAudio:]_block_invoke + 1648 (CDVSound.m:418)
7   libdispatch.dylib             	0x0000000184904aa0 _dispatch_call_block_and_release + 24 (init.c:994)
8   libdispatch.dylib             	0x0000000184904a60 _dispatch_client_callout + 16 (object.m:507)
9   libdispatch.dylib             	0x0000000184940548 _dispatch_queue_override_invoke$VARIANT$armv81 + 700 (inline_internal.h:2500)
10  libdispatch.dylib             	0x00000001849463c4 _dispatch_root_queue_drain + 592 (inline_internal.h:2539)
11  libdispatch.dylib             	0x0000000184946110 _dispatch_worker_thread3 + 112 (queue.c:6092)
12  libsystem_pthread.dylib       	0x0000000184c37fac _pthread_wqthread + 1176 (pthread.c:2297)
13  libsystem_pthread.dylib       	0x0000000184c37b08 start_wqthread + 4

sjkummer avatar Sep 10 '18 19:09 sjkummer

@janpio : Is there a change that this bug is going to be fixed? As far as I can see, there is no more active development, nor are PullRequests merged... 😕

sjkummer avatar Sep 14 '18 11:09 sjkummer

Apache Cordova is an Open Source project with a very limited set of active volunteer maintainers. Currently the focus is on a) finishing migration of issues from JIRA to GitHub and adapting all the processes and rules that go with it (e.g. by labeling new issues etc) and b) working on releasing and finishing new versions of everything but the plugins (CLI, platforms, other libraries and tooling). Several people are focusing on cleaning up the code base, to enable us to create more stable releases in the future quicker.

If you have a good understanding of your issue for this plugin and might be able to create a PR, please go ahead and do so! I personally won't be able to review it as I don't do Obj-C, but at least something is there and the day will come when we will be able to look at the plugin PRs and issues with some more effort as well. We of course can't just merge stuff without people reviewing the PRs and making sure they actually improve the situation. Unfortunately quite often one issue is fixed, while 5 others are created ;)

janpio avatar Sep 14 '18 11:09 janpio

Hi @sjkummer We are facing the same crash issue on IOS with latest plugin release (5.0.2) - seeing it only from production logs - very hard to reproduce. Did you have any solution or workaround for this issue?

AvnerAviram avatar Mar 25 '19 15:03 AvnerAviram

@Javier84 I am now caching all files on the local file system and make sure that everything is completely loaded before playing. No more crashes in iTunes Connect.

sjkummer avatar Mar 25 '19 18:03 sjkummer

Hi @sjkummer " I am now caching all files on the local file system and make sure that everything is completely loaded before playing." Which APIs have you used? Can you show your code?Thanx!

david-clang avatar Apr 26 '19 04:04 david-clang

If the whilt loop calls play 100 times, there is a big chance that it will crash. If you use serial queue, you can avoid crash.

In my own project, I use serial queue call to play to avoid crashes,

crash code:

- (void)buttonAction {
    NSInteger testCount = 100;
    while (testCount) {
        testCount--;
        AVAudioPlayer *player = [self unusedPlayerWithPath:path];
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            if (player) {
                [player play];
            }
        });
    }
}

safe code:

- (void)buttonAction {
    NSInteger testCount = 100;
    while (testCount) {
        testCount--;
        AVAudioPlayer *player = [self unusedPlayerWithPath:path];
        dispatch_async(self.serialQueue,  ^{
            if (player) {
                [player play];
            }
        });
    }
}

Cache all the files on the local file system, will it crash if you call the call 100 times in a loop?@sjkummer

david-clang avatar Apr 26 '19 04:04 david-clang