Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug report] iOS Crash in PHImageManager #1262

Open
umar-hunch opened this issue Feb 14, 2025 · 2 comments
Open

[Bug report] iOS Crash in PHImageManager #1262

umar-hunch opened this issue Feb 14, 2025 · 2 comments

Comments

@umar-hunch
Copy link

Version

3.6.3

Platforms

iOS

Device Model

iPhone 12 Pro Max

flutter info

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.5, on macOS 14.5 23F79 darwin-arm64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.97.1)
[✓] Network resources

• No issues found!

How to reproduce?

A significant percentage of our Crashlytics logs for iOS seems to be connect to PHImage Manager issues. Seems like either a deadlock or race condition.

Logs

Crashed: com.apple.root.user-interactive-qos
0  libsystem_platform.dylib       0x4ce4 _os_unfair_lock_recursive_abort + 36
1  libsystem_platform.dylib       0x1e1c _os_unfair_lock_lock_slow + 308
2  libobjc.A.dylib                0xfd08 locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>::lockWith(lockdebug::lock_mixin<objc_lock_base_t>&) + 72
3  libobjc.A.dylib                0xf30c objc_storeWeak + 148
4  Foundation                     0xb8394 -[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 1124
5  CoreFoundation                 0x3039c ___forwarding___ + 1004
6  CoreFoundation                 0x2fef0 _CF_forwarding_prep_0 + 96
7  CoreServices                   0x2f4f8 __51-[LSApplicationWorkspace deviceIdentifierForVendor]_block_invoke + 264
8  CoreServices                   0x2f2e8 _LSRetryForConnectionInterrupted + 56
9  CoreServices                   0x2f248 -[LSApplicationWorkspace deviceIdentifierForVendor] + 160
10 UIKitCore                      0xd57158 -[UIDevice identifierForVendor] + 40
11 Runner                         0xacf198 +[UXAppUtil uniqueDeviceId] + 128516
12 Runner                         0xaf71e0 -[UXInternalLog initWithTag:level:screen:params:timeline:sessionId:date:] + 30888
13 Runner                         0xabdff8 +[UXCamHandler addInternalTag:logLevel:properties:] + 58468
14 Runner                         0xab7b2c post_crash_callback + 32664
15 Runner                         0xaf4894 signal_handler_callback + 20316
16 Runner                         0xad0890 internal_callback_iterator(int, __siginfo*, __darwin_ucontext*, void*) + 134396
17 Runner                         0xad07f4 UXCamplcrash_signal_handler + 134240
18 libsystem_platform.dylib       0x4ca8 _sigtramp + 56
19 libsystem_kernel.dylib         0x33c00 abort_with_payload_wrapper_internal + 104
20 libsystem_kernel.dylib         0x33b98 abort_with_payload_wrapper_internal + 30
21 libobjc.A.dylib                0x3f8b0 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 116
22 libobjc.A.dylib                0x103ac objc_storeWeakOrNil + 30
23 libobjc.A.dylib                0xf840 weak_register_no_lock + 396
24 libobjc.A.dylib                0xf450 objc_storeWeak + 472
25 Photos                         0x20510 -[PHImageManager runRequestWithContext:] + 76
26 Photos                         0x1b01c -[PHImageManager requestNewCGImageForAsset:targetSize:contentMode:options:resultHandler:] + 940
27 Photos                         0x21d70 -[PHImageManager requestImageForAsset:targetSize:contentMode:options:resultHandler:] + 172
28 photo_manager                  0xac84 -[PMManager fetchThumb:option:resultHandler:progressHandler:] + 488
29 photo_manager                  0xaa20 -[PMManager getThumbWithId:option:resultHandler:progressHandler:] + 192
30 photo_manager                  0x14d2c -[PMPlugin handleMethodResultHandler:manager:notificationManager:] + 2388
31 photo_manager                  0x1437c __19-[PMPlugin onAuth:]_block_invoke + 40
32 libdispatch.dylib              0x2248 _dispatch_call_block_and_release + 32
33 libdispatch.dylib              0x3fa8 _dispatch_client_callout + 20
34 libdispatch.dylib              0x16094 _dispatch_root_queue_drain + 860
35 libdispatch.dylib              0x166c4 _dispatch_worker_thread2 + 156
36 libsystem_pthread.dylib        0x3644 _pthread_wqthread + 228
37 libsystem_pthread.dylib        0x1474 start_wqthread + 8

Example code (optional)

@override
  Future<List<AssetPathEntity>> fetchAlbums() async {
    // Request permissions to access the photos
    bool galleryPermission =
        await PermissionManager().requestGalleryPermission();
    if (!galleryPermission) {
      throw PermissionsNotGrantedException();
    }

    // Fetch the list of albums
    final List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(
      type: RequestType.image,
      filterOption: FilterOptionGroup(
        imageOption: const FilterOption(
          sizeConstraint: SizeConstraint(ignoreSize: true),
        ),
        orders: [
          const OrderOption(type: OrderOptionType.createDate, asc: false),
        ],
      ),
    );
    List<AssetPathEntity> albumList = [];
    for (var album in albums) {
      int count = await album.assetCountAsync;
      if (count > 0) {
        albumList.add(album);
      }
    }

    return albumList;
  }

  @override
  Future<List<AssetEntity>> fetchImagesFromAlbum(AssetPathEntity album,
      {int page = 0, int pageSize = 40}) async {
    // Fetch the images from the specified album
    final List<AssetEntity> images =
        await album.getAssetListPaged(page: page, size: pageSize);
    List<AssetEntity> imageList = [];
    for (var image in images) {
      String? mimeType = await image.mimeTypeAsync;
      if (!invalidMimeTypes.contains(mimeType)) {
        imageList.add(image);
      }
    }
    return imageList;
  }

  @override
  Future<List<Uint8List>> convertToThumbnail(List<AssetEntity> images) async {
    // Convert the images to thumbnails in parallel
    final List<Future<Uint8List?>> futures = images.map((image) async {
      try {
        return await image.thumbnailData;
      } catch (e) {
        // ErrorLoggingObserver.logError(e, StackTrace.current, hint: {
        //   "Multiple Image upload": "Failed to convert image to thumbnail",
        // });
        return null;
      }
    }).toList();

    // Wait for all futures to complete, even if some fail
    final List<Uint8List?> results = await Future.wait(
      futures,
      eagerError: false, // Prevents early termination on error
    );

    // Filter out nulls from failed conversions
    return results.whereType<Uint8List>().toList();
  }

Contact

[email protected]

@umar-hunch umar-hunch changed the title [Bug report] [Bug report] iOS Crash in PHImageManager Feb 14, 2025
@fluttercandies-dev
Copy link

AI Summary: The app crashes on iOS due to a deadlock or race condition within PHImageManager, specifically when fetching thumbnails, possibly related to weak object registration.

@lockingroad
Copy link

I had the same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants