Skyost / Bonsoir

A Zeroconf library that allows you to discover network services and to broadcast your own. Based on Apple Bonjour and Android NSD.
http://bonsoir.skyost.eu/
Other
107 stars 49 forks source link

Crash when pushing the app into the background and pulling it back into the foreground #65

Closed ctwdtw closed 10 months ago

ctwdtw commented 10 months ago

Describe the bug Crash when pushing the app into the background and pulling it back into the foreground

To Reproduce Steps to reproduce the behavior:

  1. build a simple app with the following code, I use Bonsoir 4.0.0
    
    import 'package:bonsoir/bonsoir.dart'; // 4.0.0
    import 'package:flutter/material.dart';
    import 'package:logger/logger.dart';

final logger = Logger();

void main() { runApp(const BonsoirApp()); }

class BonsoirApp extends StatelessWidget { const BonsoirApp({super.key});

@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Simple Flutter App'), ), body: FutureBuilder( future: BonsoirDiscoverRepo.instance.init(), builder: (ctx, snapShot) { if (snapShot.connectionState == ConnectionState.done) { return const Text('discovering'); } else { return const Text('waiting'); } }, ), ), ); } }

class BonsoirDiscoverRepo { static BonsoirDiscoverRepo get instance { _instance ??= BonsoirDiscoverRepo._internal(); return _instance!; }

static BonsoirDiscoverRepo? _instance; BonsoirDiscovery? _discover;

BonsoirDiscoverRepo._internal();

Future init() async { if (_discover == null) { _discover = BonsoirDiscovery(type: '_http._tcp'); await _discover!.ready; if (_discover!.eventStream == null) { return; } _discover!.eventStream! .where((event) => event.service?.name.contains('IGD-') ?? false) .listen( (event) async { if (event.type == BonsoirDiscoveryEventType.discoveryServiceFound) { event.service?.resolve(_discover!.serviceResolver); } else if (event.type == BonsoirDiscoveryEventType.discoveryServiceResolved) { logger.d('resolve: ${event.service?.toJson()}'); } else if (event.type == BonsoirDiscoveryEventType.discoveryServiceLost) { logger.d('lost: ${event.service?.toJson()}'); } }, ); await _discover!.start(); logger.d('start discover and put event to lower stream'); } else { logger.d('already start discover'); } } }

3. run the app with this command
```bash
fvm flutter run -d <my_iPhone_device_id> --release
  1. Push the app into the background
  2. Pulling the app into the foreground
  3. The App Crashed.

Expected behavior Should not crash, when I comment out the code inside Future<void> init() async {}, it did not crash

Screenshots N/A

Desktop (please complete the following information): Not Testing

Smartphone (please complete the following information):

Additional context I am not sure if I'm using Bonsoir in the correct way. My use case is the following:

  1. When a user holds my app and enters a room, the app can display devices broadcast its service name with the prefix MY_DEVICE_PREFIX
  2. When a user holds my app and leaves a room, the app can display the remaining devices broadcast its service name with the prefix MY_DEVICE_PREFIX (which could be none)

If I understand Bonsoir's behavior correctly, I think the above requirements can be imp. as a singleton. However, even if I update Bonsoir to 4.0.0, the discovering behavior seems still not stable. I may open another issue to describe it. Thank you.

ctwdtw commented 10 months ago

I also tested the example project with the following steps, and it crashed:

  1. Open Runner.xcworkspace in Xcode
  2. set EditScheme -> Run -> Build Configuration as Release
  3. run the app on an iPhone Simulator
  4. it crashes with the following message:
    
    Details

Simulator device returned an error for the requested operation. Domain: NSPOSIXErrorDomain Code: 3 Failure Reason: No such process User Info: { DVTErrorCreationDateKey = "2023-11-17 09:32:07 +0000"; IDERunOperationFailingWorker = IDELaunchiPhoneSimulatorLauncher; SimCallingSelector = "launchApplicationWithID:options:pid:error:"; }

Application launch for 'fr.skyost.bonsoirExample' did not return a valid pid nor a launch error. Domain: NSPOSIXErrorDomain Code: 3 Failure Reason: No such process

Analytics Event: com.apple.dt.IDERunOperationWorkerFinished : { "device_model" = "iPhone14,7"; "device_osBuild" = "16.4 (20E247)"; "device_platform" = "com.apple.platform.iphonesimulator"; "launchSession_schemeCommand" = Run; "launchSession_state" = 1; "launchSession_targetArch" = arm64; "operation_duration_ms" = 372; "operation_errorCode" = 3; "operation_errorDomain" = NSPOSIXErrorDomain; "operation_errorWorker" = IDELaunchiPhoneSimulatorLauncher; "operation_name" = IDERunOperationWorkerGroup; "param_consoleMode" = 0; "param_debugger_attachToExtensions" = 0; "param_debugger_attachToXPC" = 1; "param_debugger_type" = 3; "param_destination_isProxy" = 0; "param_destination_platform" = "com.apple.platform.iphonesimulator"; "param_diag_MainThreadChecker_stopOnIssue" = 0; "param_diag_MallocStackLogging_enableDuringAttach" = 0; "param_diag_MallocStackLogging_enableForXPC" = 1; "param_diag_allowLocationSimulation" = 1; "param_diag_checker_tpc_enable" = 1; "param_diag_gpu_frameCapture_enable" = 0; "param_diag_gpu_shaderValidation_enable" = 0; "param_diag_gpu_validation_enable" = 0; "param_diag_memoryGraphOnResourceException" = 0; "param_diag_queueDebugging_enable" = 1; "param_diag_runtimeProfile_generate" = 0; "param_diag_sanitizer_asan_enable" = 0; "param_diag_sanitizer_tsan_enable" = 0; "param_diag_sanitizer_tsan_stopOnIssue" = 0; "param_diag_sanitizer_ubsan_stopOnIssue" = 0; "param_diag_showNonLocalizedStrings" = 0; "param_diag_viewDebugging_enabled" = 1; "param_diag_viewDebugging_insertDylibOnLaunch" = 1; "param_install_style" = 0; "param_launcher_UID" = 2; "param_launcher_allowDeviceSensorReplayData" = 0; "param_launcher_kind" = 0; "param_launcher_style" = 0; "param_launcher_substyle" = 0; "param_runnable_appExtensionHostRunMode" = 0; "param_runnable_productType" = "com.apple.product-type.application"; "param_testing_launchedForTesting" = 0; "param_testing_suppressSimulatorApp" = 0; "param_testing_usingCLI" = 0; "sdk_canonicalName" = "iphonesimulator16.4"; "sdk_osVersion" = "16.4"; "sdk_variant" = iphonesimulator; }

System Information

macOS Version 13.5 (Build 22G74) Xcode 14.3.1 (21815) (Build 14E300c) Timestamp: 2023-11-17T17:32:07+08:00

Skyost commented 10 months ago

Hey,

Your code seems correct. Is the error detailed in https://github.com/Skyost/Bonsoir/issues/65#issuecomment-1816046858 the same you're describing in your first message ?

ctwdtw commented 10 months ago

No, when using fvm flutter run -d <my_iPhone_device_id> --release I did not get a crash stack trace. the app just crashed. I may need to install Crashlytic to dump the stack trace.

I guess the crash is because of the release build, that's why I tested the example project by changing EditScheme -> Run -> Build Configuration as Release and to my surprise, it crashed right after I ran the example app.

I have pushed a repo so that you can reproduce the bug I described here https://github.com/Skyost/Bonsoir/issues/65#issue-1998247533

https://github.com/ctwdtw/bonsoir_report

please have a look, thanks.

Skyost commented 10 months ago

Just tried to reproduce the bug thanks to your repo (https://github.com/ctwdtw/bonsoir_report), but the "push to background" - "pull into foreground" sequence doesn't seem to produce any crash, in debug mode at least.

ctwdtw commented 10 months ago

Yes, it does not crash in debug mode. As I pointed out in step 3 of how to reproduce the bug: fvm flutter run -d <my_iPhone_device_id> --release, it did crash on release mode with the push to background, and pull into foreground sequence.

Skyost commented 10 months ago

Just reproduced your bug, and I get the following message :

Unsupported value: -65569: Defunct connection of type __SwiftNativeNSerror

It seems that we're trying to send a __SwiftNativeNSerror to the Dart side, which is causing a crash.

olerhan commented 2 months ago

Hello, I encounter the following error when bringing my iOS application from the background to the foreground:

dnssd_clientstub write_all(22) DEFUNCT
dnssd_clientstub deliver_request ERROR: write_all(22, 88 bytes) failed
dnssd_clientstub write_all(22) DEFUNCT

After this, Bonsoir does not work properly. Is this a condition that needs to be managed, or is it a bug?

Skyost commented 2 months ago

@olerhan I don't know about this one. Does it happen with the example app ?