tekartik / process_run.dart

Process run helper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

crash due to "Message from debugger: Terminated due to signal 13"

LeXuanKhanh opened this issue · comments

Hello, I try to run executable file on Mac, when run on android studio it work fine but when I run the project on xcode to debug or build a release app (using flutter build macos) and open, it crash. The only thing it say is Message from debugger: Terminated due to signal 13

I try to create a new project and run a simple command with executable file like brew --version to reproduce the error, it crash and log the same thing

I have already disabled sandbox mode

Environment:
Mac OS: 10.15.7
Xcode: 12.0.1 (12A7300)
Flutter: Channel dev, 1.26.0-8.0.pre

If you catch and log the exception that would be great. I assume you have so disabled sandbox mode on release:

In macos/Runner/Release.entitlements and macos/Runner/DebugProfile.entitlements,
make sure the following var is defined:

<dict>
	<key>com.apple.security.app-sandbox</key>
	<false/>
</dict>

You can also try the app here on macos, when you press the floating button you can try a command such as brew --version

https://github.com/alextekartik/flutter_app_example/tree/master/process_run_example#mac-support

process_run_macos_release

After googling a bit, I got an explanation from a Chinese blog, seem like it cause by the socket which flutter use to communicate to native code, he only found it in iOS 13

https://blog.csdn.net/gjm_123/article/details/103714034?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

I fixed it by ignoring the error signal, add signal(SIGPIPE, SIG_IGN) in applicationDidBecomeActive in AppDelegate

@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
    override func applicationDidBecomeActive(_ notification: Notification) {
        signal(SIGPIPE, SIG_IGN) //Ignore signal
    }
    
    override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        return true
    }
}

After adding it, i can run the executable file commands without crash, but the shell can't find it and always return No such file or directory, it happen when i run debug with Xcode or build the release app then run it
The funny is if i want to run that executable, i have to change directory to its location ( Ex: run flutter --version, you have to cd /flutter/ bin then run ./flutter --version )

I have tested to run it in Android Studio, both debugging and release mode (using flutter run --release) and it works just fine with executable file

This is done on your example project, i only modified the AppDelegate, disable the sandbox mode and add the change directory button

Screen Shot 2021-01-30 at 9 58 16 PM

What version of Xcode did you build the release in the picture which you show me ?

@alextekartik I have the same problem which has been very tough to debug. However, the error is Terminated due to signal 13

Important: The issue only happens when you BUILD the app. Running in release mode does not crash.

How to replicate the problem:

@leoafarias seem like this bug is cause by the Process class in 'dart:io' which is warped by this library, not library itself, i reported to flutter team a month ago but it seem like my information i provided is not clear enough so far i still not get any response

Counld you open the issue in flutter github ?
My previous issue on flutter

flutter/flutter#76990

@LeXuanKhanh thanks for the info but I think there might be a secondary issue. The commands which I am try do work when I do flutter run -d macos --release but not when I run the .app after flutter build macos, is there are reason for this difference.

Just one more insight it seems that which is the culprit in this case as it is always returning null. When trying to call the command like FlutterCmd for example I get a Null check operator used on a null value, however, this only happens when the app is built.

If the process can't find the executable, the command is not found or invalid then its will crash

When you run flutter run -d macos --release or flutter build macos, the environment variables of the Process which Flutter is created for you is different, specially the PATH variables ( which process use to call some relative path executable like brew, like when you want to you flutter globally you must export its PATH in command line ), you can download the example above and run with different build or run method and print the environment variables to see what i mean

Therefore, for example you try to call FlutterCmd, the process will add automatically apply the PATH in environment variables to call it, it will success in release but when you build, the PATH is different or missing so the process can't find the executable, so it will crash

I recommend using absolute path for third parties executable, so like if u want to call FlutterCmd, you must use like usr/bin/FlutterCmd

And there 1 more problem tho, if you create Process when the app is built, the directory which the Process is spawn is in root directory which you can't execute any command due to Mac Os permission, you must manually change the directory of the Process

When trying to call the command like FlutterCmd for example I get a Null check operator used on a null value
Are you using Flutter 2.0 ?

@LeXuanKhanh Yes I am on flutter 2.0, I am trying to get better info but it's being a bit tough due to some null-safety migration, but I believe that has worked on a previous version of process_run. Will try to get more info...

hi @leoafarias , i have checked again in flutter 2.2 and its still happen (have migrated my project) , but i figure out something. In the "Build the app" case, if you have the command is execute immediately after the app is launched then its crash, but if you delay the that command (ex: 1 second) then it will not cause any crash

@LeXuanKhanh interesting... thanks for letting me know, haven't had time to dig in much more on it since we last spoke

in debug move , the PATH is injected to the Application

but on the release mode
when you do

flutter build macos

it seems the which command is not finding any of the commands we supposed to have or installed
in the path...

if we have a file ie. (profile) with app the path define can we just source it?

ie.:

export PATH="$PATH":"$HOME/.pub-cache/bin"
# homebrew for mac m1 paths
eval "$(/opt/homebrew/bin/brew shellenv)"

im kinda stock with this issue, since what i needed was to have some of the cli be invoked in my flutter app.

Hope someone can bring better solutiont to this...

im still bit confuse on how to make the command available if it exist in the system already

@goldcoders try using command in interactive shell with -c argument (ex: zsh, bash or powershell), the default shell PATH is not consistent when you build or run debug

You can an the extension like this ( I haven't tested this on Linux yet ):

extension StringEx on String {
  String get crossPlatformCommand {
    if (Platform.isWindows) {
      return 'powershell -c "${this}"';
    }

    if (Platform.isMacOS) {
      if (this.contains('youtube-dl') || (this.contains('ffmpeg'))) {
        //return '/usr/local/bin/' + this.substring(2);
        return 'zsh -c "${this.substring(2)}"';
      }

      return 'zsh -c "${this}"';
    }

    return this;
  }
}

How to use:

    final result = await newShell.run('pwd'.crossPlatformCommand).toResult();

    if (result.isError(onError: (error, _) {
      showSnackBar(videoLocation + '\n' + error);
    })) {
      return;
    }
commented

Providing full path to the packages did the trick both on debug and in release, built app via Xcode.
for example, await shell.run("/usr/local/bin/brew -v")

open -a /Applications/MyApp.app
This command can make your release app run normally