NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.1k stars 14.15k forks source link

Segfault when loading a package in R on Mac M1 #293777

Open kaneplusplus opened 8 months ago

kaneplusplus commented 8 months ago

Describe the bug

I'm getting a segfault when trying to load libraries in R in the nix-shell on a Mac M1.

Steps To Reproduce

Steps to reproduce the behavior:

  1. from zsh: nix-shell -p R rPackages.dplyr
  2. from the resulting nix-shell Rscript -e "library(dplyr)".

Expected behavior

I expected the library to load and then R to exit back to the nix-shell. Please note that this does not appear to be dplyr specific. I'm able to reproduce this with every other package I tried (ggplot2, survival, etc.).

Screenshots

 *** caught segfault ***
address 0x0, cause 'invalid permissions'

Traceback:
 1: dyn.load(file, DLLpath = DLLpath, ...)
 2: library.dynam(lib, package, package.lib)
 3: loadNamespace(i, c(lib.loc, .libPaths()), versionCheck = vI[[i]])
 4: namespaceImport(ns, loadNamespace(i, c(lib.loc, .libPaths()),     versionCheck = vI[[i]]), from = package)
 5: loadNamespace(package, lib.loc)
 6: doTryCatch(return(expr), name, parentenv, handler)
 7: tryCatchOne(expr, names, parentenv, handlers[[1L]])
 8: tryCatchList(expr, classes, parentenv, handlers)
 9: tryCatch({    attr(package, "LibPath") <- which.lib.loc    ns <- loadNamespace(package, lib.loc)    env <- attachNamespace(ns, pos = pos, deps, exclude, include.only)}, error = function(e) {    P <- if (!is.null(cc <- conditionCall(e)))         paste(" in", deparse(cc)[1L])    else ""    msg <- gettextf("package or namespace load failed for %s%s:\n %s",         sQuote(package), P, conditionMessage(e))    if (logical.return && !quietly)         message(paste("Error:", msg), domain = NA)    else stop(msg, call. = FALSE, domain = NA)})
10: library(dplyr)
An irrecoverable exception occurred. R is aborting now ...
Segmentation fault: 11

Additional context

Add any other context about the problem here.

Notify maintainers

@adisbladis

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.


[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
> nix-shell -p nix-info --run "nix-info -m"
these 2 paths will be fetched (0.01 MiB download, 0.11 MiB unpacked):
  /nix/store/xkkpiw8wj0cglvkzpp8gd2h5mgsq1kik-DarwinTools-1
  /nix/store/highid3c54gk59sxhibjhkyq2s2yvrch-nix-info
copying path '/nix/store/xkkpiw8wj0cglvkzpp8gd2h5mgsq1kik-DarwinTools-1' from 'https://cache.nixos.org'...
copying path '/nix/store/highid3c54gk59sxhibjhkyq2s2yvrch-nix-info' from 'https://cache.nixos.org'...
 - system: `"aarch64-darwin"`
 - host os: `Darwin 23.3.0, macOS 14.3.1`
 - multi-user?: `yes`
 - sandbox: `no`
 - version: `nix-env (Nix) 2.20.4`
 - channels(root): `"nixpkgs"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixpkgs````

---

Add a :+1: [reaction] to [issues you find important].

[reaction]: https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/
[issues you find important]: https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc
natsukium commented 8 months ago

I cannot reproduce this error on the master branch. (f98a3ccfa6faa5da98aa361835f005fc9a148f5d) Can you tell me the revision of nix-channel?

kaneplusplus commented 8 months ago

Certainly.

> nix-channel --version
nix-channel (Nix) 2.20.4

If it's helpful, I'm happy to completely uninstall, retry, and report back.

kaneplusplus commented 8 months ago

OK, I figured it out.

If I start a nix-shell and check .libPaths() (where R looks for packages). I get the following:

> nix-shell -p R rPackages.ggplot2

[nix-shell:~/projects/telperian/build-and-deploy/build-packages/MCRC/inst/sim-real]$ R
...
> head(.libPaths())
[1] "/Users/mike/Library/R/arm64/4.3/library"
[2] "/nix/store/1pabv9bhqx6fsvc4lzs1darqrs1gnjvc-r-ggplot2-3.4.4/library"
[3] "/nix/store/3mcgh9kp5jfwi4ikq7c6g63imilajcfq-r-cli-3.6.2/library"
[4] "/nix/store/1722gizcnb92k3akvnkpn8mj9xd63asl-r-glue-1.6.2/library"
[5] "/nix/store/9axazs50jwrqcfdhpya0v96kcv53vkac-r-gtable-0.3.4/library"

For some reason the first place R looks for R packages on my machine is where my mac arm64 packages are. R tries to load the package and crashes.

A fix is to get rid of the first entry in .libPaths() with:

> .libPaths(.libPaths()[-1])
> head(.libPaths())
[1] "/nix/store/1pabv9bhqx6fsvc4lzs1darqrs1gnjvc-r-ggplot2-3.4.4/library"
[2] "/nix/store/3mcgh9kp5jfwi4ikq7c6g63imilajcfq-r-cli-3.6.2/library"
[3] "/nix/store/1722gizcnb92k3akvnkpn8mj9xd63asl-r-glue-1.6.2/library"
...

Now I can load packages.

jbedo commented 7 months ago

Do you have it set in .Rprofile?

kaneplusplus commented 6 months ago

I do not. I'm not sure why it was getting the first path from.

philipp-baumann commented 1 month ago

@jbedo Can we change to not inheriting R_LIBS_USER, which is the default on both macOS and linux for nix R builds, if it exists? It causes a lot of pain and runtime impurity by default, which should really be avoided. We use R_LIBS_SITE in nix. Shall i make a separate issue for it? @kaneplusplus we have rix::rix_init() that writes a custom .Rprofile that removes R_LIBS_USER from .libPaths() by default. It works, but i really would like that R packaged in nixpkgs has a better default.

jbedo commented 1 month ago

@jbedo Can we change to not inheriting R_LIBS_USER, which is the default on both macOS and linux for nix R builds, if it exists? It causes a lot of pain and runtime impurity by default, which should really be avoided. We use R_LIBS_SITE in nix. Shall i make a separate issue for it? @kaneplusplus we have rix::rix_init() that writes a custom .Rprofile that removes R_LIBS_USER from .libPaths() by default. It works, but i really would like that R packaged in nixpkgs has a better default.

I don't think that's a good idea, there are users that rely on that functionality. I also generally prefer to keep behaviour as close to upstream as possible. We already have ways to increase purity (e.g., the --pure) flag.

philipp-baumann commented 3 weeks ago

@jbedo Can we change to not inheriting R_LIBS_USER, which is the default on both macOS and linux for nix R builds, if it exists? It causes a lot of pain and runtime impurity by default, which should really be avoided. We use R_LIBS_SITE in nix. Shall i make a separate issue for it? @kaneplusplus we have rix::rix_init() that writes a custom .Rprofile that removes R_LIBS_USER from .libPaths() by default. It works, but i really would like that R packaged in nixpkgs has a better default.

I don't think that's a good idea, there are users that rely on that functionality. I also generally prefer to keep behaviour as close to upstream as possible. We already have ways to increase purity (e.g., the --pure) flag.

nix-shell --pure does not change the system-polluted .libPaths(), since its a runtime purity problem. I still think its a bad idea to have this default.

  1. it puts offnew nix R users and future contributors, because its just an unpleasant experience if you are not a computer scientist and want to learn about nix and profit from it. We have seen quite some issues ourselves and seen people struggling with segfaults and unnoticed package loads from an existing R user library on the host system.
  2. its so easy if users rely on that functionality to just set .libPaths() to include R_LIBS_USERS. What use cases do see that cannot be tackled otherwise?
jbedo commented 3 weeks ago

The tradeoff is between two groups of users, those who manage R dependencies with Nix exclusively and those that do not. The change you're suggesting diverges from upstream behaviour and favours the former group at the expense of the latter. Either way does not prevent users from achieving their goals, but I feel not changing upstream defaults is least surprising and also has lower maintenance cost, particularly with documentation.

This discussion is worthwhile however offtopic for this issue, let's continue in a new one.