#2 wrong-type-argument arrayp error

Closed
opened 6 years ago by apteryx · 9 comments
apteryx commented 6 years ago

I'm using emacs-guix with the guix sources checked out under ~/src/guix.

After starting emacs, issuing M-x guix RET e leads to the following traceback:

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  replace-regexp-in-string("[ (]\\(#t\\)" "t" nil nil nil 1)
  guix-geiser-eval-read("(package-names)" #<buffer *Guix Internal REPL*>)
  guix-eval-read("(package-names)")
  #[nil "\300\301\302!\303\"\207" [sort guix-eval-read "(package-names)" string<] 3]()
  apply(#[nil "\300\301\302!\303\"\207" [sort guix-eval-read "(package-names)" string<] 3] nil)
  guix-package-names()
  guix-read-package-name()
  (list (guix-read-package-name) (guix-read-directory))
  call-interactively(guix-edit-action)
  magit-invoke-popup-action(101)
  funcall-interactively(magit-invoke-popup-action 101)
  call-interactively(magit-invoke-popup-action nil nil)
  command-execute(magit-invoke-popup-action)

To work around the issue, I must cd in ~/src/guix and build the sources (./pre-inst-env guix environment guix; make) and restart Emacs.

To trigger the issue I only need to make my ~/src/guix tree "dirty", say, by changing the hash of one package.

Here's my emacs-guix config in my .emacs:

(setq guix-directory "~/src/guix")
(setq guix-repl-use-latest nil)
(add-hook 'shell-mode-hook 'guix-build-log-minor-mode)
(add-hook 'geiser-repl-mode-hook 'guix-build-log-minor-mode)

;; geiser
(setq geiser-default-implementation 'guile)
(with-eval-after-load 'geiser-guile
  (add-to-list 'geiser-guile-load-path "~/src/guix")
  (add-to-list 'geiser-guile-load-path "~/src/shepherd"))
I'm using emacs-guix with the guix sources checked out under ~/src/guix. After starting emacs, issuing M-x guix RET e leads to the following traceback: ```` Debugger entered--Lisp error: (wrong-type-argument arrayp nil) replace-regexp-in-string("[ (]\\(#t\\)" "t" nil nil nil 1) guix-geiser-eval-read("(package-names)" #<buffer *Guix Internal REPL*>) guix-eval-read("(package-names)") #[nil "\300\301\302!\303\"\207" [sort guix-eval-read "(package-names)" string<] 3]() apply(#[nil "\300\301\302!\303\"\207" [sort guix-eval-read "(package-names)" string<] 3] nil) guix-package-names() guix-read-package-name() (list (guix-read-package-name) (guix-read-directory)) call-interactively(guix-edit-action) magit-invoke-popup-action(101) funcall-interactively(magit-invoke-popup-action 101) call-interactively(magit-invoke-popup-action nil nil) command-execute(magit-invoke-popup-action) ```` To work around the issue, I must cd in ~/src/guix and build the sources (./pre-inst-env guix environment guix; make) and restart Emacs. To trigger the issue I only need to make my ~/src/guix tree "dirty", say, by changing the hash of one package. Here's my emacs-guix config in my .emacs: ```` (setq guix-directory "~/src/guix") (setq guix-repl-use-latest nil) (add-hook 'shell-mode-hook 'guix-build-log-minor-mode) (add-hook 'geiser-repl-mode-hook 'guix-build-log-minor-mode) ;; geiser (setq geiser-default-implementation 'guile) (with-eval-after-load 'geiser-guile (add-to-list 'geiser-guile-load-path "~/src/guix") (add-to-list 'geiser-guile-load-path "~/src/shepherd")) ````
alezost commented 6 years ago
Owner

Hm, I don't reproduce this: it works as expected for me even with a dirty tree.

From your output, it looks like Geiser returns nothing when we try to receive package names.

Could you evaluate the following (with the dirty tree) code (in M-x ielm, for example):

(guix-eval "(length (package-names))")

Is there any output or any error?

Hm, I don't reproduce this: it works as expected for me even with a dirty tree. From your output, it looks like Geiser returns nothing when we try to receive package names. Could you evaluate the following (with the dirty tree) code (in `M-x ielm`, for example): ```elisp (guix-eval "(length (package-names))") ``` Is there any output or any error?
apteryx commented 6 years ago
Poster
ELISP> (guix-eval "(length (package-names))")
nil

It takes a long time (tens of seconds) and returns nil.

In top, Guile is peaked at 100%. I'm not sure what it is it is doing.

ELISP> (guix-eval "(length (package-names))") nil It takes a long time (tens of seconds) and returns nil. In top, Guile is peaked at 100%. I'm not sure what it is it is doing.
apteryx commented 6 years ago
Poster

Oh, it finished now. So it seems that when my tree is dirty Geiser starts compiling/evaluating stuff and it times out, returning nil.

A quick investigation suggests the timeout is 30000 ms (30 s), in geiser-connection.el (geiser-connection-timeout). I'll try bumping this to 120000 to see if it clears my issue.

Oh, it finished now. So it seems that when my tree is dirty Geiser starts compiling/evaluating stuff and it times out, returning nil. A quick investigation suggests the timeout is 30000 ms (30 s), in geiser-connection.el (geiser-connection-timeout). I'll try bumping this to 120000 to see if it clears my issue.
alezost commented 6 years ago
Owner

Oh, this is a very long time. That command folds over all packages, but it shouldn't take so long; it takes about 3 seconds on my (rather decent) computer. Perhaps, your "~/src/guix" directory is not in the %load-compiled-path, could you check it in the Guix REPL?

Sorry, I will be AFK for a day or two, so I will not answer until then :-)

Oh, this is a very long time. That command folds over all packages, but it shouldn't take so long; it takes about 3 seconds on my (rather decent) computer. Perhaps, your "~/src/guix" directory is not in the `%load-compiled-path`, could you check it in the Guix REPL? Sorry, I will be AFK for a day or two, so I will not answer until then :-)
apteryx commented 6 years ago
Poster

The guile process started by emacs-guix/geiser is taking a very long time when making a simple change to ~/src/guix/gnu/packages/python.scm (running for 10 minutes now), restarting Emacs and initializing Emacs-Guix (M-x guix RET e). That process is:

/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/bin/guile -L /gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/share/guile/site/2.2 -C /gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/lib/guile/2.2/site-ccache -L /gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/share/guile/site/2.2 -C /gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/lib/guile/2.2/site-ccache --listen=/tmp/emacs-guix-23596kjH/repl-socket -q -L /gnu/store/2x80jwfz64wrpkc8v4wk4y56qh0hyqri-geiser-0.9/share/geiser/guile/ -L ~/src/shepherd -L ~/src/guix

The ~/src/guix directory seems to be in my %load-compiled-path:

In *Guix REPL*:

scheme@(emacs-guix)> %load-path
$4 = ("/home/maxim/src/my-guix-packages" "/home/maxim/src/guix" "/home/maxim/src/shepherd" "/gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/share/guile/site/2.2" "/home/maxim/.config/guix/latest" "/gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/share/guile/site/2.2" "/gnu/store/2x80jwfz64wrpkc8v4wk4y56qh0hyqri-geiser-0.9/share/geiser/guile/" "~/src/shepherd" "~/src/guix" "/home/maxim/.guix-profile/share/guile/site/2.2" "/run/current-system/profile/share/guile/site/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile/site/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile/site" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile")
scheme@(emacs-guix)> %load-compiled-path
$5 = ("/home/maxim/src/my-guix-packages" "/home/maxim/src/guix" "/home/maxim/src/shepherd" "/gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/lib/guile/2.2/site-ccache" "/home/maxim/.config/guix/latest" "/gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/lib/guile/2.2/site-ccache" "/home/maxim/.guix-profile/lib/guile/2.2/site-ccache" "/home/maxim/.guix-profile/share/guile/site/2.2" "/run/current-system/profile/lib/guile/2.2/site-ccache" "/run/current-system/profile/share/guile/site/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/lib/guile/2.2/ccache" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/lib/guile/2.2/site-ccache")
The guile process started by emacs-guix/geiser is taking a very long time when making a simple change to ~/src/guix/gnu/packages/python.scm (running for 10 minutes now), restarting Emacs and initializing Emacs-Guix (M-x guix RET e). That process is: /gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/bin/guile -L /gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/share/guile/site/2.2 -C /gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/lib/guile/2.2/site-ccache -L /gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/share/guile/site/2.2 -C /gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/lib/guile/2.2/site-ccache --listen=/tmp/emacs-guix-23596kjH/repl-socket -q -L /gnu/store/2x80jwfz64wrpkc8v4wk4y56qh0hyqri-geiser-0.9/share/geiser/guile/ -L ~/src/shepherd -L ~/src/guix The ~/src/guix directory seems to be in my %load-compiled-path: In \*Guix REPL\*: ```` scheme@(emacs-guix)> %load-path $4 = ("/home/maxim/src/my-guix-packages" "/home/maxim/src/guix" "/home/maxim/src/shepherd" "/gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/share/guile/site/2.2" "/home/maxim/.config/guix/latest" "/gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/share/guile/site/2.2" "/gnu/store/2x80jwfz64wrpkc8v4wk4y56qh0hyqri-geiser-0.9/share/geiser/guile/" "~/src/shepherd" "~/src/guix" "/home/maxim/.guix-profile/share/guile/site/2.2" "/run/current-system/profile/share/guile/site/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile/site/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile/site" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/share/guile") scheme@(emacs-guix)> %load-compiled-path $5 = ("/home/maxim/src/my-guix-packages" "/home/maxim/src/guix" "/home/maxim/src/shepherd" "/gnu/store/h5brjj5x4sgy3fhz10jba7qaavv5jqjm-emacs-guix-0.3.3/lib/guile/2.2/site-ccache" "/home/maxim/.config/guix/latest" "/gnu/store/7m239pi63wf3naj1g26b4253ykibjw5k-guix-0.13.0-5.228a398/lib/guile/2.2/site-ccache" "/home/maxim/.guix-profile/lib/guile/2.2/site-ccache" "/home/maxim/.guix-profile/share/guile/site/2.2" "/run/current-system/profile/lib/guile/2.2/site-ccache" "/run/current-system/profile/share/guile/site/2.2" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/lib/guile/2.2/ccache" "/gnu/store/yihvhxv3xyyvl1m2cy1lnf1lyi9h76fk-guile-2.2.2/lib/guile/2.2/site-ccache") ````
apteryx commented 6 years ago
Poster

Given a completely compiled master guix checked out under ~/src/guix, we apply the following change (could be anything, really):

diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index 9352b4f65..43ee954fc 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -2063,7 +2063,7 @@ from the module-init-tools project.")
                     version ".tar.gz"))
               (sha256
                (base32
-                "0qqgbgpm5wdllk0s04pf80nwc8pr93xazwri1bylm1f15zn5ck1y"))
+                "1qqgbgpm5wdllk0s04pf80nwc8pr93xazwri1bylm1f15zn5ck1y"))
               (patches (search-patches "eudev-rules-directory.patch"))))
     (build-system gnu-build-system)
     (arguments

The evaluation of the trivially changed linux.scm file took around 15 seconds when triggered by "./pre-inst-env guix environment guix'.

The guile process started in those conditions in a fresh Emacs with 'M-x guix RET e' took nearly 180 seconds:

25398 maxim     20   0  0.348g 0.085g   0.0  2.3   0:08.06 S          `- .emacs-25.2-rea                              
25578 maxim     20   0  0.530g 0.288g   0.0  7.9   2:54.64 S              `- guile 

That's an order (12 times) slower. I'm curious to find out why this is so!

Given a completely compiled master guix checked out under ~/src/guix, we apply the following change (could be anything, really): ```` diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm index 9352b4f65..43ee954fc 100644 --- a/gnu/packages/linux.scm +++ b/gnu/packages/linux.scm @@ -2063,7 +2063,7 @@ from the module-init-tools project.") version ".tar.gz")) (sha256 (base32 - "0qqgbgpm5wdllk0s04pf80nwc8pr93xazwri1bylm1f15zn5ck1y")) + "1qqgbgpm5wdllk0s04pf80nwc8pr93xazwri1bylm1f15zn5ck1y")) (patches (search-patches "eudev-rules-directory.patch")))) (build-system gnu-build-system) (arguments ```` The evaluation of the trivially changed linux.scm file took around 15 seconds when triggered by "./pre-inst-env guix environment guix'. The guile process started in those conditions in a fresh Emacs with 'M-x guix RET e' took nearly 180 seconds: ```` 25398 maxim 20 0 0.348g 0.085g 0.0 2.3 0:08.06 S `- .emacs-25.2-rea 25578 maxim 20 0 0.530g 0.288g 0.0 7.9 2:54.64 S `- guile ```` That's an order (12 times) slower. I'm curious to find out why this is so!
apteryx commented 6 years ago
Poster

The previous comparison was flawed; I was comparing the time it takes for the modified module (linux.scm) to be auto-compiled vs the time it takes to simply evaluate it.

Steps followed to understand this:

  1. rm /home/maxim/.cache/guile/ccache/2.2-LE-8-3.A/home/maxim/src/guix/gnu/packages/linux.scm.go
  2. cd ~/src/guix; time guile -C . -L . ~/repro.scm. The file linux.scm gets auto-compiled in about 2 m 30 s which is similar to the time guile runs as a subprocess in Emacs when doing M-x guix RET e (top measured 2 m 50 s in the TIME+ column).
  3. Purging the compiled file with step 1. and then strictly evaluating the linux.scm file by doing: time --no-auto-compile guile -C . -L . ~/repro.scm, it takes less than 6 seconds, which is comparable to what we get when using guix directly. This can be explained by the use of "--no-auto-compile" by the guix script itself (guix/scripts/guix).

To get the same behavior from Emacs-Guix (--no-auto-compile), one can define the following variable in their .emacs: (setq guix-guile-program '("guile" "--no-auto-compile"))

Hopefully this long text will prove useful to someone else. Closing.

The reproduction script:

(use-modules (ice-9 format)
	     (gnu packages)
	     (guix packages)
	     (srfi srfi-1)
	     (srfi srfi-19))

(define (package-names)
  "Return a list of names of available packages."
  (delete-duplicates
   (fold-packages (lambda (pkg res)
                    (cons (package-name pkg) res))
		  '())))

(define (main)
  (let* ((start-time (current-time))
	 (packages-count (length (package-names)))
	 (elapsed (time-difference (current-time)
				   start-time))
	 (elapsed-sec (+ (time-second elapsed)
			 (/ (time-nanosecond elapsed) 1e9))))
    (format #t "Number of packages: ~a~%Elapsed time: ~,3f s~%"
	    packages-count elapsed-sec)))

(main)
The previous comparison was flawed; I was comparing the time it takes for the modified module (linux.scm) to be auto-compiled vs the time it takes to simply evaluate it. Steps followed to understand this: 1. `rm /home/maxim/.cache/guile/ccache/2.2-LE-8-3.A/home/maxim/src/guix/gnu/packages/linux.scm.go` 2. `cd ~/src/guix; time guile -C . -L . ~/repro.scm`. The file linux.scm gets auto-compiled in about 2 m 30 s which is similar to the time guile runs as a subprocess in Emacs when doing M-x guix RET e (top measured 2 m 50 s in the TIME+ column). 3. Purging the compiled file with step 1. and then strictly evaluating the linux.scm file by doing: `time --no-auto-compile guile -C . -L . ~/repro.scm`, it takes less than 6 seconds, which is comparable to what we get when using guix directly. This can be explained by the use of "--no-auto-compile" by the guix script itself (guix/scripts/guix). To get the same behavior from Emacs-Guix (--no-auto-compile), one can define the following variable in their .emacs: `(setq guix-guile-program '("guile" "--no-auto-compile"))` Hopefully this long text will prove useful to someone else. Closing. The reproduction script: ```` (use-modules (ice-9 format) (gnu packages) (guix packages) (srfi srfi-1) (srfi srfi-19)) (define (package-names) "Return a list of names of available packages." (delete-duplicates (fold-packages (lambda (pkg res) (cons (package-name pkg) res)) '()))) (define (main) (let* ((start-time (current-time)) (packages-count (length (package-names))) (elapsed (time-difference (current-time) start-time)) (elapsed-sec (+ (time-second elapsed) (/ (time-nanosecond elapsed) 1e9)))) (format #t "Number of packages: ~a~%Elapsed time: ~,3f s~%" packages-count elapsed-sec))) (main) ````
alezost commented 6 years ago
Owner

Wow, thank you very much for your detailed investigation!

Now I see why I didn't reproduce: I made a change in a tiny module ("lirc.scm"), so its auto-compilation was fast for me, and you experimented with the big ones ("python.scm" and "linux.scm").

I added "--no-auto-compile" option to the default value of guix-guile-program and adjusted the documentation to mention it (commit 50313f2af3). Thank you again for this great job!

Wow, thank you very much for your detailed investigation! Now I see why I didn't reproduce: I made a change in a tiny module ("lirc.scm"), so its auto-compilation was fast for me, and you experimented with the big ones ("python.scm" and "linux.scm"). I added "--no-auto-compile" option to the default value of `guix-guile-program` and adjusted the documentation to mention it (commit 50313f2af311c1a19133e287c959272fddef59e3). Thank you again for this great job!
apteryx commented 6 years ago
Poster

Very nice! Thanks! I'm off to enjoy Emacs-Guix :)

Very nice! Thanks! I'm off to enjoy Emacs-Guix :)
Sign in to join this conversation.
No Label
No Milestone
No assignee
2 Participants
Loading...
Cancel
Save
There is no content yet.