Repository: iterative/dvc

Issue:
macOS: analytics daemon crashes due to fork related error
After the daemon changes introduced in #4262 (f799e1e3), DVC on macOS crashes when we try to spawn the analytics daemon.

```
dvc git:f799e1e3 ✩  py:dvc ❯ dvc version
WARNING: Unable to detect supported link types, as cache directory '.dvc/cache' doesn't exist. It is usually auto-created by commands such as `dvc add/fetch/pull/run/import`, but you could create it manually to enable this check.
DVC version: 1.1.11+f799e1
Python version: 3.8.5
Platform: macOS-10.15.6-x86_64-i386-64bit
Binary: False
Package: None
Supported remotes: azure, gdrive, gs, hdfs, http, https, s3, ssh, oss
Repo: dvc, git
Filesystem type (workspace): ('apfs', '/dev/disk1s1')
objc[34576]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
objc[34576]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
```
![Screen Shot 2020-07-28 at 4 37 51 PM](https://user-images.githubusercontent.com/651988/88633994-bd026280-d0f0-11ea-9d1f-a60e755bbbfa.png)

Disabling analytics avoids the crash
```
dvc git:f799e1e3 ✩  py:dvc ❯ dvc config --local core.analytics false
dvc git:f799e1e3 ✩  py:dvc ❯ dvc version
WARNING: Unable to detect supported link types, as cache directory '.dvc/cache' doesn't exist. It is usually auto-created by commands such as `dvc add/fetch/pull/run/import`, but you could create it manually to enable this check.
DVC version: 1.1.11+f799e1
Python version: 3.8.5
Platform: macOS-10.15.6-x86_64-i386-64bit
Binary: False
Package: None
Supported remotes: azure, gdrive, gs, hdfs, http, https, s3, ssh, oss
Repo: dvc, git
Filesystem type (workspace): ('apfs', '/dev/disk1s1')
```

This problem appears to be related to `fork` being unsafe in macOS 

See related Python issue: https://bugs.python.org/issue33725 and Python 3.8 [multiprocessing docs](https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods)


Discussion:
As mentioned in the python issue, setting the `OBJC_DISABLE_INITIALIZE_FORK_SAFETY` env variable before running python/dvc can be used as a workaround, but that doesn't seem like an ideal solution for us
@pmrowla Thank you for the investigation! :pray: Quick solution is to continue using Popen on mac and windows. Will take a look.

Resolving patch:
diff --git a/dvc/daemon.py b/dvc/daemon.py
--- a/dvc/daemon.py
+++ b/dvc/daemon.py
@@ -3,6 +3,7 @@
 import inspect
 import logging
 import os
+import platform
 import sys
 from subprocess import Popen
 
@@ -15,25 +16,24 @@
 DETACHED_PROCESS = 0x00000008
 
 
-def _spawn_windows(cmd, env):
-    from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW
-
+def _popen(cmd, **kwargs):
     prefix = [sys.executable]
     if not is_binary():
         prefix += [sys.argv[0]]
 
+    return Popen(prefix + cmd, close_fds=True, shell=False, **kwargs)
+
+
+def _spawn_windows(cmd, env):
+    from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW
+
     creationflags = CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS
 
     startupinfo = STARTUPINFO()
     startupinfo.dwFlags |= STARTF_USESHOWWINDOW
 
-    Popen(
-        prefix + cmd,
-        env=env,
-        close_fds=True,
-        shell=False,
-        creationflags=creationflags,
-        startupinfo=startupinfo,
+    _popen(
+        cmd, env=env, creationflags=creationflags, startupinfo=startupinfo,
     ).communicate()
 
 
@@ -65,8 +65,13 @@ def _spawn_posix(cmd, env):
     sys.stdout.close()
     sys.stderr.close()
 
-    os.environ.update(env)
-    main(cmd)
+    if platform.system() == "Darwin":
+        # workaround for MacOS bug
+        # https://github.com/iterative/dvc/issues/4294
+        _popen(cmd, env=env).communicate()
+    else:
+        os.environ.update(env)
+        main(cmd)
 
     os._exit(0)  # pylint: disable=protected-access
 


Test patch: