unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* bug#31878: Module autoloading is not thread safe
@ 2018-06-18  9:43 Ludovic Courtès
  2018-06-18 11:11 ` Ludovic Courtès
  2022-04-04 11:47 ` Calvin Heim
  0 siblings, 2 replies; 12+ messages in thread
From: Ludovic Courtès @ 2018-06-18  9:43 UTC (permalink / raw)
  To: 31878

Hello,

The backtrace below (from Guile 2.2.3) shows the Guix multi-threaded
module compilation code crashing with an incorrect module resolution
failure (incorrect because the module does exist.)

I believe this comes from the fact that ‘autoloads-done’ and related
alists in (ice-9 boot-9) are manipulated in a non-thread-safe fashion.
Notice that a couple of threads in the backtrace are effectively
running:

  (member x autoloads-done)

Thanks,
Ludo’.

--8<---------------cut here---------------start------------->8---
$ out=/tmp/t NIX_BUILD_CORES=8 setarch x86_64 -R gdb --args  guile "--no-auto-compile" "-L" . "-C" . "/gnu/store/815przlfissan60p4bdn7cipfidc3q29-guix-extra-builder"        
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
ERROR: In procedure type-pointer:
ERROR: In procedure gdbscm_type_pointer: Wrong type argument in position 1 (expecting gdb:type): #f
/home/ludo/.gdbinit:8: Error in sourced command file:
Error while executing Scheme code.
Reading symbols from guile...Reading symbols from /gnu/store/nlkf6c702f8c6wsadbmib0w0mnxccqdi-guile-2.2.3-debug/lib/debug//gnu/store/1mr5izrbxwd7cbq8m1xrqm45rzkibpsj-guile-2.2.3/bin/guile.debug...
done. 
done. 
(gdb) shell rm -rf /tmp/t
(gdb) r
Starting program: /gnu/store/gdmn1al64y4366q5nb0v87qdv0q6xpmp-profile/bin/guile --no-auto-compile -L . -C . /gnu/store/815przlfissan60p4bdn7cipfidc3q29-guix-extra-builder
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib/libthread_db.so.1".
[New Thread 0x7ffff5e56700 (LWP 6455)]
[New Thread 0x7ffff5655700 (LWP 6456)]
[New Thread 0x7ffff4e54700 (LWP 6457)]
[New Thread 0x7ffff3ee8700 (LWP 6458)]
loading...       97.2% of 109 filesrandom seed for tests: 1529311210
loading...      100.0% of 109 files[New Thread 0x7fffe9c11700 (LWP 6460)]
compiling...      0.0% of 109 files[New Thread 0x7fffe9410700 (LWP 6461)]
com[New Thread 0x7fffe8c0f700 (LWP 6462)]
compiling...      0.0% of 109 files[New Thread 0x7fffe3fff700 (LWP 6463)]
compil[New Thread 0x7fffe37fe700 (LWP 6464)]
compiling...0% o  0.0% of 109 files[New Thread 0x7fffe2ffd700 (LWP 6465)]
compiling...    [New Thread 0x7fffe27fc700 (LWP 6466)]
c[New Thread 0x7fffe1ffb700 (LWP 6467)]
ompiling...       0.0% of 109 filesException thrown while printing backtrace:
In procedure Exception thrown while printing backtrace:
In procedure private-lookup: Module named (rnrs bytevectors) does not exist
Exception thrown while printing backtrace:
In procedure private-lookup: Module named (rnrs bytevectors) does not exist
Exception thrown while printing backtrace:
In procedure private-lookup: Module named (rnrs bytevectors) does not exist

Thread 11 "guile" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffe2ffd700 (LWP 6465)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51      ../sysdeps/unix/sysv/linux/raise.c: Dosiero aŭ dosierujo ne ekzistas.
(gdb) thread apply all bt

Thread 13 (Thread 0x7fffe1ffb700 (LWP 6467)):
#0  clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:78
#1  0x00007ffff76204a0 in ?? () at pthread_create.c:361 from /gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib/libpthread.so.0
#2  0x00007fffe1ffb700 in ?? ()
#3  0x0000000000000000 in ?? ()

Thread 12 (Thread 0x7fffe27fc700 (LWP 6466)):
#0  0x00007ffff76299df in __libc_write (fd=fd@entry=37, buf=buf@entry=0x15dcda0, nbytes=nbytes@entry=13) at ../sysdeps/unix/sysv/linux/write.c:27
#1  0x00007ffff7b052ce in fport_write (port=<optimized out>, src=<optimized out>, start=<optimized out>, count=13) at fports.c:597
#2  0x00007ffff7b34d0c in scm_i_write_bytes (port=#<port 13 1262640>, src="#<vu8vector>" = {...}, start=0, count=13) at ports.c:2857
#3  0x00007ffff7b37671 in scm_c_put_latin1_chars (port=#<port 13 1262640>, chars=<optimized out>, len=13) at ports.c:3457
#4  0x00007ffff7b39e95 in scm_simple_format (destination=#<port 13 1262640>, message="In procedure ~a: ", args=("private-lookup")) at print.c:1173
#5  0x00007ffff7b717fd in vm_regular_engine (thread=0x25, vp=0x804b40, registers=0xd, resume=-144533025) at vm-engine.c:784
#6  0x00007ffff7b74e5a in scm_call_n (proc=#<program 756ca0>, argv=argv@entry=0x7fffe27faef0, nargs=nargs@entry=4) at vm.c:1257
#7  0x00007ffff7af7f94 in scm_call_4 (proc=<optimized out>, arg1=arg1@entry=#<port 13 1262640>, arg2=arg2@entry=#f, arg3=arg3@entry=misc-error, 
    arg4=arg4@entry=("private-lookup" "Module named ~s does not exist" ((rnrs bytevectors)) #f)) at eval.c:508
#8  0x00007ffff7ae9e13 in scm_print_exception (port=port@entry=#<port 13 1262640>, frame=frame@entry=#f, key=key@entry=misc-error, 
    args=args@entry=("private-lookup" "Module named ~s does not exist" ((rnrs bytevectors)) #f)) at backtrace.c:113
#9  0x00007ffff7ae9eaf in error_during_backtrace (data=0x1262640, tag=misc-error, throw_args=("private-lookup" "Module named ~s does not exist" ((rnrs bytevectors)) #f)) at backtrace.c:257
#10 0x00007ffff7b717fd in vm_regular_engine (thread=0x25, vp=0x804b40, registers=0xd, resume=-144533025) at vm-engine.c:784
#11 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=<error reading variable: ERROR: Cannot access memory at address 0x0>0x12625c0, argv=<optimized out>, nargs=5) at vm.c:1257
#12 0x00007ffff7af828b in scm_apply_0 (proc=proc@entry=<error reading variable: ERROR: Cannot access memory at address 0x0>0x12625c0, args=()) at eval.c:594
#13 0x00007ffff7b6408f in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 12625e0>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x12625c0, 
    pre_unwind_handler=#f) at throw.c:134
#14 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#15 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7ae9a90 <display_backtrace_body>, body_data=body_data@entry=0x7fffe27fb320, 
    handler=handler@entry=0x7ffff7ae9e80 <error_during_backtrace>, handler_data=<optimized out>, pre_unwind_handler=pre_unwind_handler@entry=0x0, pre_unwind_handler_data=0x0) at throw.c:377
#16 0x00007ffff7b6452e in scm_internal_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7ae9a90 <display_backtrace_body>, body_data=body_data@entry=0x7fffe27fb320, 
    handler=handler@entry=0x7ffff7ae9e80 <error_during_backtrace>, handler_data=<optimized out>) at throw.c:386
#17 0x00007ffff7ae9a85 in scm_display_backtrace_with_highlights (stack=<optimized out>, port=<optimized out>, first=<optimized out>, depth=<optimized out>, highlights=<optimized out>)
    at backtrace.c:282
#18 0x00007ffff7b717fd in vm_regular_engine (thread=0x25, vp=0x804b40, registers=0xd, resume=-144533025) at vm-engine.c:784
#19 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 756d00>, argv=<optimized out>, nargs=5) at vm.c:1257
#20 0x00007ffff7af828b in scm_apply_0 (proc=#<program 756d00>, args=()) at eval.c:594
#21 0x00007ffff7af8e8d in scm_apply_1 (proc=<optimized out>, arg1=arg1@entry=misc-error, args=<optimized out>) at eval.c:600
#22 0x00007ffff7b643ac in scm_throw (key=key@entry=misc-error, args=<optimized out>) at throw.c:266
#23 0x00007ffff7b64925 in scm_ithrow (key=key@entry=misc-error, args=<optimized out>, no_return=no_return@entry=1) at throw.c:611
#24 0x00007ffff7af6495 in scm_error_scm (key=misc-error, subr=<optimized out>, message=<optimized out>, args=<optimized out>, data=<optimized out>) at error.c:94
#25 0x00007ffff7b717fd in vm_regular_engine (thread=0x25, vp=0x804b40, registers=0xd, resume=-144533025) at vm-engine.c:784
#26 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 121dfe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#27 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 121dfe0>) at eval.c:481
#28 0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 121dfe0>) at async.c:400
#29 0x00007ffff7b717fd in vm_regular_engine (thread=0x25, vp=0x804b40, registers=0xd, resume=-144533025) at vm-engine.c:784
#30 0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651e00>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#31 0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#32 0x00007ffff7b62b16 in really_launch (d=0x1653ac0) at threads.c:794
#33 0x00007ffff7af22da in c_body (d=0x7fffe27fbe50) at continuations.c:422
#34 0x00007ffff7b717fd in vm_regular_engine (thread=0x25, vp=0x804b40, registers=0xd, resume=-144533025) at vm-engine.c:784
#35 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 12049a0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#36 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 12049a0>) at eval.c:481
#37 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 12049a0>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1204980, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1204960) at throw.c:137
#38 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#39 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe27fbe50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe27fbe50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#40 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe27fbe50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe27fbe50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#41 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#42 0x00007ffff7b62c3c in with_guile (base=0x7fffe27fbeb8, data=0x7fffe27fbee0) at threads.c:661
#43 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#44 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653ac0, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#45 launch_thread (d=0x1653ac0) at threads.c:803
#46 0x00007ffff7620567 in start_thread (arg=0x7fffe27fc700) at pthread_create.c:463
#47 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 11 (Thread 0x7fffe2ffd700 (LWP 6465)):
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff5e8cc31 in __GI_abort () at abort.c:79
#2  0x00007ffff7b780bd in scm_dynamic_call (func=<optimized out>, dobj=<optimized out>) at dynl.c:393
#3  0x00007ffff7b717fd in vm_regular_engine (thread=0x2, vp=0x804bd0, registers=0x0, resume=-169297328) at vm-engine.c:784
#4  0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 1574fe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#5  0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 1574fe0>) at eval.c:481
#6  0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 1574fe0>) at async.c:400
#7  0x00007ffff7b717fd in vm_regular_engine (thread=0x2, vp=0x804bd0, registers=0x0, resume=-169297328) at vm-engine.c:784
#8  0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651e40>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#9  0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#10 0x00007ffff7b62b16 in really_launch (d=0x1653b00) at threads.c:794
#11 0x00007ffff7af22da in c_body (d=0x7fffe2ffce50) at continuations.c:422
#12 0x00007ffff7b717fd in vm_regular_engine (thread=0x2, vp=0x804bd0, registers=0x0, resume=-169297328) at vm-engine.c:784
#13 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 1564a80>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#14 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 1564a80>) at eval.c:481
#15 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 1564a80>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1564a60, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1564a40) at throw.c:137
#16 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#17 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe2ffce50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe2ffce50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#18 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe2ffce50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe2ffce50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#19 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#20 0x00007ffff7b62c3c in with_guile (base=0x7fffe2ffceb8, data=0x7fffe2ffcee0) at threads.c:661
#21 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#22 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653b00, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#23 launch_thread (d=0x1653b00) at threads.c:803
#24 0x00007ffff7620567 in start_thread (arg=0x7fffe2ffd700) at pthread_create.c:463
#25 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 10 (Thread 0x7fffe37fe700 (LWP 6464)):
#0  0x00007ffff7af5eba in scm_equal_p (x="guix/import/", y="guix/build/") at eq.c:326
#1  0x00007ffff7af5ed2 in scm_equal_p (x=("guix/import/" . "gnome"), y=y@entry=("guix/build/" . "bournish")) at eq.c:299
#2  0x00007ffff7b145bb in scm_member (x=("guix/build/" . "bournish"), 
    lst=(("guix/import/" . "gnome") ("guix/import/" . "github") ("guix/import/" . "gem") ("guix/import/" . "elpa") ("guix/import/" . "crate") ("srfi/" . "srfi-2") ("guix/import/" . "cran") ("guix/import/" . "cpan") ("guix/import/" . "json") ("guix/import/" . "utils") ("srfi/" . "srfi-41") ("gnu/" . "packages") ("guix/import/" . "cabal") ("system/base/" . "lalr") ("guix/" . "hg-download") ("guix/" . "graph") ("guix/" . "gnu-maintenance") ("guix/" . "upstream") ("guix/" . "gnupg") ("guix/" . "download") ("guix/" . "discovery") ("guix/" . "glob") ("guix/" . "git") ("" . "git") ("git/" . "tag") ("git/" . "status") ("git/" . "settings") ("git/" . "rev-parse") ("git/" . "remote") ("git/" . "reset") ("git/" . "fetch") ("git/" . "cred") ("git/" . "errors") ("git/" . "commit") ("git/" . "object") ("git/" . "tree") ("git/" . "oid") ("git/" . "clone") ("git/" . "repository") ("git/" . "branch") ("git/" . "reference") ("git/" . "bindings") ("git/" . "structs") ("bytestructures/" . "guile") ("bytestructures/guile/" . "cstring-pointer") ("bytestructures/guile/" . "string") ("bytestructures/guile/" . "numeric") ("bytestructures/guile/" . "pointer") ("bytestructures/guile/" . "union") ("bytestructures/guile/" . "struct") ("bytestructures/guile/" . "bitfields") ("bytestructures/guile/" . "numeric-metadata") ("bytestructures/guile/" . "numeric-all") ("bytestructures/guile/" . "numeric-data-model") ("bytestructures/guile/" . "explicit-endianness") ("bytestructures/guile/" . "vector") ("bytestructures/guile/" . "base") ("bytestructures/guile/" . "utils") ("bytestructures/guile/" . "bytevectors") ("bytestructures/r6/" . "bytevectors") ("git/" . "types") ("git/" . "config") ("guix/" . "git-download") ("guix/" . "docker") ("" . "json") ("json/" . "parser") ("json/" . "builder") ("guix/" . "cvs-download") ("guix/" . "cve") ("guix/" . "cpio") ("guix/" . "ci") ("guix/" . "http-client") ("guix/" . "ui") ("texinfo/" . "plain-text") ("texinfo/" . "string-utils") ("srfi/" . "srfi-14") ("" . "texinfo") ("guix/" . "licenses") ("guix/" . "profiles") ("guix/" . "i18n") ("guix/" . "cache") ("guix/build-system/" . "waf") ("guix/build-system/" . "texlive") ("guix/" . "svn-download") ("guix/build-system/" . "scons") ("guix/build-system/" . "ruby") ("guix/build-system/" . "r") ("guix/build-system/" . "python") ("guix/build-system/" . "perl") ("guix/build-system/" . "ocaml") ("guix/build-system/" . "minify") ("guix/build-system/" . "meson") ("guix/build-system/" . "haskell") ("guix/build-system/" . "go") ("guix/build-system/" . "glib-or-gtk") ("guix/build-system/" . "font") ("guix/build-system/" . "emacs") ("guix/build-system/" . "dub") ("guix/build-system/" . "cmake") ("guix/build-system/" . "cargo") ("guix/build-system/" . "asdf") ("guix/build-system/" . "ant") ("guix/build-system/" . "android-ndk") ("guix/build-system/" . "gnu") ("guix/" . "packages") ("guix/" . "build-system") ("guix/" . "gexp") ("guix/" . "grafts") ("guix/" . "derivations") ("guix/" . "store") ("" . "gnutls") ("guix/" . "hash") ("guix/" . "gcrypt") ("guix/" . "base32") ("guix/" . "base16") ("guix/" . "monads") ("system/" . "syntax") ("guix/" . "utils") ("srfi/" . "srfi-39") ("guix/" . "search-paths") ("guix/build/" . "waf-build-system") ("guix/build/" . "texlive-build-system") ("guix/build/" . "union") ("guix/build/" . "svn") ("guix/build/" . "store-copy") ("guix/build/" . "scons-build-system") ("guix/build/" . "ruby-build-system") ("guix/build/" . "r-build-system") ("guix/build/" . "qt-utils") ("guix/build/" . "python-build-system") ("guix/build/" . "pull") ("guix/build/" . "perl-build-system") ("guix/build/" . "ocaml-build-system") ("guix/build/" . "minify-build-system") ("guix/build/" . "meson-build-system") ("guix/build/" . "rpath") ("guix/build/" . "make-bootstrap") ("guix/build/" . "java-utils") ("guix/build/" . "hg") ("guix/build/" . "haskell-build-system") ("guix/build/" . "graft") ("guix/build/" . "go-build-system") ("guix/build/" . "gnu-dist") ("guix/build/" . "glib-or-gtk-build-system") ("guix/build/" . "git") ("guix/build/" . "font-build-system") ("guix/build/" . "emacs-build-system") ("guix/build/" . "emacs-utils") ("guix/build/" . "dub-build-system") ("guix/build/" . "download-nar") ("guix/" . "zlib") ("guix/" . "config") ("guix/" . "serialization") ("guix/" . "combinators") ("guix/build/" . "download") ("guix/" . "progress") ("guix/" . "records") ("guix/" . "ftp-client") ("srfi/" . "srfi-31") ("guix/" . "base64") ("" . "rnrs") ("rnrs/" . "unicode") ("rnrs/" . "sorting") ("rnrs/" . "programs") ("rnrs/io/" . "simple") ("rnrs/arithmetic/" . "flonums") ("rnrs/" . "r5rs") ("ice-9/" . "r5rs") ("ice-9/" . "safe-r5rs") ("ice-9/" . "null") ("rnrs/arithmetic/" . "fixnums") ("web/" . "client") ("web/" . "response") ("web/" . "request") ("web/" . "http") ("ice-9/" . "textual-ports") ("web/" . "uri") ("guix/build/" . "cvs") ("guix/build/" . "cmake-build-system") ("guix/build/" . "cargo-build-system") ("guix/build/" . "bournish") ("system/repl/" . "command") ("" . "statprof") ("ice-9/" . "and-let-star") ("ice-9/" . "session") ("ice-9/" . "documentation") ("system/vm/" . "trap-state") ("system/vm/" . "trace") ("system/vm/" . "traps") ("system/" . "xref") ("system/repl/" . "debug") ("system/vm/" . "inspect") ("ice-9/" . "pretty-print") ("system/vm/" . "frame") ("system/vm/" . "disassembler") ("system/repl/" . "common") ("ice-9/" . "history") ("guix/build/" . "asdf-build-system") ("guix/build/" . "lisp-utils") ("ice-9/" . "hash-table") ("guix/build/" . "ant-build-system") ("sxml/" . "simple") ("sxml/" . "transform") ("sxml/" . "ssax") ("sxml/ssax/" . "input-parse") ("guix/build/" . "android-ndk-build-system") ("ice-9/" . "popen") ("guix/build/" . "syscalls") ("guix/build/" . "gnu-build-system") ("srfi/" . "srfi-19") ("ice-9/" . "i18n") ("srfi/" . "srfi-6") ("guix/build/" . "gremlin") ("guix/" . "elf") ("language/bytecode/" . "spec") ("language/cps/" . "spec") ("language/cps/" . "compile-bytecode") ("system/vm/" . "assembler") ("system/vm/" . "linker") ("language/cps/" . "split-rec") ("language/cps/" . "reify-primitives") ("language/cps/" . "handle-interrupts") ("language/cps/" . "closure-conversion") ("language/cps/" . "slot-allocation") ("language/tree-il/" . "spec") ("language/tree-il/" . "compile-cps") ("language/tree-il/" . "analyze") ("system/vm/" . "program") ("system/vm/" . "debug") ("system/vm/" . "loader") ("system/vm/" . "dwarf") ("system/vm/" . "elf") ("language/value/" . "spec") ("language/scheme/" . "spec") ("language/scheme/" . "decompile-tree-il") ("language/scheme/" . "compile-tree-il") ("guix/build/" . "compile") ("language/cps/" . "optimize") ("language/cps/" . "verify") ("language/cps/" . "primitives") ("language/" . "bytecode") ("language/cps/" . "type-fold") ("language/cps/" . "specialize-numbers") ("language/cps/" . "specialize-primcalls") ("language/cps/" . "simplify") ("language/cps/" . "self-references") ("language/cps/" . "rotate-loops") ("language/cps/" . "prune-bailouts") ("language/cps/" . "prune-top-level-scopes") ("language/cps/" . "peel-loops") ("language/cps/" . "licm") ("language/cps/" . "elide-values") ("language/cps/" . "dce") ("language/cps/" . "type-checks") ("language/cps/" . "types") ("language/cps/" . "cse") ("language/cps/" . "effects-analysis") ("language/cps/" . "contification") ("language/cps/" . "renumber") ("language/cps/" . "constructors") ("language/cps/" . "with-cps") ("language/cps/" . "utils") ("language/cps/" . "intmap") ("language/cps/" . "intset") ("language/" . "cps") ("language/tree-il/" . "optimize") ("language/tree-il/" . "debug") ("language/tree-il/" . "fix-letrec") ("language/tree-il/" . "peval") ("language/tree-il/" . "effects") ("language/tree-il/" . "primitives") ("srfi/" . "srfi-16") ("language/" . "tree-il") ("guix/build/" . "utils") ("rnrs/io/" . "ports") ("srfi/" . "srfi-8") ("rnrs/" . "files") ("rnrs/records/" . "syntactic") ("rnrs/" . "hashtables") ("srfi/" . "srfi-69") ("srfi/" . "srfi-13") ("rnrs/" . "enums") ("rnrs/" . "syntax-case") ("rnrs/" . "exceptions") ("rnrs/records/" . "inspection") ("rnrs/arithmetic/" . "bitwise") ("rnrs/" . "control") ("rnrs/" . "conditions") ("rnrs/records/" . "procedural") ("rnrs/" . "lists") ("ice-9/" . "iconv") ("rnrs/" . "base") ("ice-9/" . "binary-ports") ("ice-9/" . "rdelim") ("ice-9/" . "ftw") ("srfi/" . "srfi-60") ("guix/" . "modules") ("srfi/" . "srfi-35") ("srfi/" . "srfi-34") ("guix/" . "sets") ("ice-9/" . "vlist") ("guix/" . "memoization") ("guix/" . "profiling") ("system/base/" . "compile") ("ice-9/" . "receive") ("ice-9/" . "optargs") ("system/base/" . "pmatch") ("system/vm/" . "vm") ("system/base/" . "message") ("system/base/" . "language") ("system/base/" . "syntax") ("system/base/" . "target") ("system/" . "foreign") ("ice-9/" . "regex") ("ice-9/" . "format") ("srfi/" . "srfi-26") ("ice-9/" . "command-line") ("srfi/" . "srfi-4") ("rnrs/" . "bytevectors") ("ice-9/" . "ports") ("ice-9/" . "deprecated") ("ice-9/" . "threads") ("ice-9/" . "futures") ("ice-9/" . "q") ("srfi/" . "srfi-11") ("srfi/srfi-9/" . "gnu") ("srfi/" . "srfi-9") ("system/base/" . "ck") ("srfi/" . "srfi-1") ("ice-9/" . "control") ("ice-9/" . "match") (guile . guile))) at list.c:732
#3  0x00007ffff7b717fd in vm_regular_engine (thread=0x15, vp=0x804c60, registers=0x15, resume=2308) at vm-engine.c:784
#4  0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 14e7fe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#5  0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 14e7fe0>) at eval.c:481
#6  0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 14e7fe0>) at async.c:400
#7  0x00007ffff7b717fd in vm_regular_engine (thread=0x15, vp=0x804c60, registers=0x15, resume=2308) at vm-engine.c:784
#8  0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651e80>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#9  0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#10 0x00007ffff7b62b16 in really_launch (d=0x1653b60) at threads.c:794
#11 0x00007ffff7af22da in c_body (d=0x7fffe37fde50) at continuations.c:422
#12 0x00007ffff7b717fd in vm_regular_engine (thread=0x15, vp=0x804c60, registers=0x15, resume=2308) at vm-engine.c:784
#13 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 14d6180>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#14 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 14d6180>) at eval.c:481
#15 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 14d6180>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x14d6160, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x14d6140) at throw.c:137
#16 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#17 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe37fde50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe37fde50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#18 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe37fde50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe37fde50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#19 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#20 0x00007ffff7b62c3c in with_guile (base=0x7fffe37fdeb8, data=0x7fffe37fdee0) at threads.c:661
#21 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#22 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653b60, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#23 launch_thread (d=0x1653b60) at threads.c:803
#24 0x00007ffff7620567 in start_thread (arg=0x7fffe37fe700) at pthread_create.c:463
#25 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 9 (Thread 0x7fffe3fff700 (LWP 6463)):
#0  0x00007ffff5f80b27 in __GI__dl_mcount_wrapper_check (selfpc=0x7ffff5e7e0f0 <__gconv_transform_utf8_internal>) at dl-profstub.c:38
#1  0x00007ffff5e79948 in __gconv (cd=0x7fffd8009bc0, inbuf=inbuf@entry=0x0, inbufend=inbufend@entry=0x0, outbuf=outbuf@entry=0x0, outbufend=outbufend@entry=0x0, 
    irreversible=irreversible@entry=0x7fffe3ffbf08) at gconv.c:58
#2  0x00007ffff5e79323 in iconv (cd=<optimized out>, inbuf=0x0, inbytesleft=0x0, outbuf=0x0, outbytesleft=0x0) at iconv.c:42
#3  0x00007ffff70a2170 in mem_cd_iconveh_internal () from /gnu/store/rqr8v7q7fnhxziaq3s9qmsmkpr7yax24-libunistring-0.9.9/lib/libunistring.so.2
#4  0x00007ffff70a3561 in libunistring_mem_cd_iconveh () from /gnu/store/rqr8v7q7fnhxziaq3s9qmsmkpr7yax24-libunistring-0.9.9/lib/libunistring.so.2
#5  0x00007ffff70a36ae in libunistring_mem_iconveh () from /gnu/store/rqr8v7q7fnhxziaq3s9qmsmkpr7yax24-libunistring-0.9.9/lib/libunistring.so.2
#6  0x00007ffff70a392f in mem_iconveha_notranslit () from /gnu/store/rqr8v7q7fnhxziaq3s9qmsmkpr7yax24-libunistring-0.9.9/lib/libunistring.so.2
#7  0x00007ffff70a3d9a in libunistring_mem_iconveha () from /gnu/store/rqr8v7q7fnhxziaq3s9qmsmkpr7yax24-libunistring-0.9.9/lib/libunistring.so.2
#8  0x00007ffff70aa214 in u32_conv_from_encoding () from /gnu/store/rqr8v7q7fnhxziaq3s9qmsmkpr7yax24-libunistring-0.9.9/lib/libunistring.so.2
#9  0x00007ffff7b5cb13 in scm_from_stringn (str=str@entry=0x7ffff7b8d920 "Module named ~s does not exist", len=30, len@entry=18446744073709551615, encoding=0x7ffff7e6e44c "UTF-8", 
    handler=SCM_FAILED_CONVERSION_QUESTION_MARK) at strings.c:1510
#10 0x00007ffff7b5cc84 in scm_from_locale_stringn (str=str@entry=0x7ffff7b8d920 "Module named ~s does not exist", len=len@entry=18446744073709551615) at strings.c:1564
#11 0x00007ffff7b5cc9c in scm_from_locale_string (str=str@entry=0x7ffff7b8d920 "Module named ~s does not exist") at strings.c:1551
#12 0x00007ffff7af6526 in scm_error (key=misc-error, subr=subr@entry=0x7ffff7b8d8a5 "private-lookup", message=message@entry=0x7ffff7b8d920 "Module named ~s does not exist", 
    args=((rnrs bytevectors)), rest=rest@entry=#f) at error.c:59
#13 0x00007ffff7af6932 in scm_misc_error (subr=subr@entry=0x7ffff7b8d8a5 "private-lookup", message=message@entry=0x7ffff7b8d920 "Module named ~s does not exist", args=<optimized out>)
    at error.c:299
#14 0x00007ffff7b1ae19 in scm_private_variable (module_name=(rnrs bytevectors), name=bytevector-u32-ref) at modules.c:661
#15 0x00007ffff7b1aee1 in scm_private_lookup (module_name=(rnrs bytevectors), name=bytevector-u32-ref) at modules.c:700
#16 0x00007ffff7b73df8 in vm_regular_engine (thread=0x7ffff5e7e0f0 <__gconv_transform_utf8_internal>, vp=0x804cf0, registers=0x0, resume=0) at vm-engine.c:2063
#17 0x00007ffff7b74e5a in scm_call_n (proc=#<program 7ffff2f1dd28>, argv=argv@entry=0x7fffe3ffe5d8, nargs=nargs@entry=1) at vm.c:1257
#18 0x00007ffff7af7f18 in scm_call_1 (proc=<optimized out>, arg1=140737288552224) at eval.c:487
#19 0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff5e7e0f0 <__gconv_transform_utf8_internal>, vp=0x804cf0, registers=0x0, resume=0) at vm-engine.c:784
#20 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 149afe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#21 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 149afe0>) at eval.c:481
#22 0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 149afe0>) at async.c:400
#23 0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff5e7e0f0 <__gconv_transform_utf8_internal>, vp=0x804cf0, registers=0x0, resume=0) at vm-engine.c:784
#24 0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651ec0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#25 0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#26 0x00007ffff7b62b16 in really_launch (d=0x1653ba0) at threads.c:794
#27 0x00007ffff7af22da in c_body (d=0x7fffe3ffee50) at continuations.c:422
#28 0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff5e7e0f0 <__gconv_transform_utf8_internal>, vp=0x804cf0, registers=0x0, resume=0) at vm-engine.c:784
#29 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 1499e40>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#30 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 1499e40>) at eval.c:481
#31 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 1499e40>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1499e20, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1499e00) at throw.c:137
#32 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#33 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe3ffee50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe3ffee50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#34 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe3ffee50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe3ffee50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#35 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#36 0x00007ffff7b62c3c in with_guile (base=0x7fffe3ffeeb8, data=0x7fffe3ffeee0) at threads.c:661
#37 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#38 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653ba0, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#39 launch_thread (d=0x1653ba0) at threads.c:803
#40 0x00007ffff7620567 in start_thread (arg=0x7fffe3fff700) at pthread_create.c:463
#41 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 8 (Thread 0x7fffe8c0f700 (LWP 6462)):
#0  0x00007ffff7b73c34 in vm_regular_engine (thread=0x7ffff7dfe878, vp=0x804d80, registers=0x1189801, resume=0) at vm-engine.c:3889
#1  0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 1491fe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#2  0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 1491fe0>) at eval.c:481
#3  0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 1491fe0>) at async.c:400
#4  0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7dfe878, vp=0x804d80, registers=0x1189801, resume=0) at vm-engine.c:784
#5  0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651f00>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#6  0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#7  0x00007ffff7b62b16 in really_launch (d=0x1653be0) at threads.c:794
#8  0x00007ffff7af22da in c_body (d=0x7fffe8c0ee50) at continuations.c:422
#9  0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7dfe878, vp=0x804d80, registers=0x1189801, resume=0) at vm-engine.c:784
#10 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 1487740>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#11 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 1487740>) at eval.c:481
#12 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 1487740>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1487720, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1487700) at throw.c:137
#13 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#14 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe8c0ee50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe8c0ee50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#15 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe8c0ee50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe8c0ee50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#16 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#17 0x00007ffff7b62c3c in with_guile (base=0x7fffe8c0eeb8, data=0x7fffe8c0eee0) at threads.c:661
#18 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#19 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653be0, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#20 launch_thread (d=0x1653be0) at threads.c:803
#21 0x00007ffff7620567 in start_thread (arg=0x7fffe8c0f700) at pthread_create.c:463
#22 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 7 (Thread 0x7fffe9410700 (LWP 6461)):
#0  0x00007ffff7af5e8d in scm_is_pair (x="ssh/") at ../libguile/pairs.h:159
#1  scm_equal_p (x="ssh/", y="guix/build/") at eq.c:297
#2  0x00007ffff7af5ed2 in scm_equal_p (x=("ssh/" . "auth"), y=y@entry=("guix/build/" . "ant-build-system")) at eq.c:299
#3  0x00007ffff7b145bb in scm_member (x=("guix/build/" . "ant-build-system"), 
    lst=(("ssh/" . "auth") ("ssh/" . "session") ("ssh/" . "log") ("guix/" . "self") ("guix/" . "scripts") ("guix/store/" . "database") ("guix/store/" . "deduplication") ("" . "sqlite3") ("guix/" . "nar") ("guix/" . "pki") ("guix/" . "pk-crypto") ("guix/import/" . "texlive") ("sxml/" . "xpath") ("guix/import/" . "stackage") ("guix/import/" . "snix") ("srfi/" . "srfi-37") ("guix/import/" . "pypi") ("guix/import/" . "print") ("guix/import/" . "hackage") ("guix/import/" . "gnu") ("guix/import/" . "gnome") ("guix/import/" . "github") ("guix/import/" . "gem") ("guix/import/" . "elpa") ("guix/import/" . "crate") ("srfi/" . "srfi-2") ("guix/import/" . "cran") ("guix/import/" . "cpan") ("guix/import/" . "json") ("guix/import/" . "utils") ("srfi/" . "srfi-41") ("gnu/" . "packages") ("guix/import/" . "cabal") ("system/base/" . "lalr") ("guix/" . "hg-download") ("guix/" . "graph") ("guix/" . "gnu-maintenance") ("guix/" . "upstream") ("guix/" . "gnupg") ("guix/" . "download") ("guix/" . "discovery") ("guix/" . "glob") ("guix/" . "git") ("" . "git") ("git/" . "tag") ("git/" . "status") ("git/" . "settings") ("git/" . "rev-parse") ("git/" . "remote") ("git/" . "reset") ("git/" . "fetch") ("git/" . "cred") ("git/" . "errors") ("git/" . "commit") ("git/" . "object") ("git/" . "tree") ("git/" . "oid") ("git/" . "clone") ("git/" . "repository") ("git/" . "branch") ("git/" . "reference") ("git/" . "bindings") ("git/" . "structs") ("bytestructures/" . "guile") ("bytestructures/guile/" . "cstring-pointer") ("bytestructures/guile/" . "string") ("bytestructures/guile/" . "numeric") ("bytestructures/guile/" . "pointer") ("bytestructures/guile/" . "union") ("bytestructures/guile/" . "struct") ("bytestructures/guile/" . "bitfields") ("bytestructures/guile/" . "numeric-metadata") ("bytestructures/guile/" . "numeric-all") ("bytestructures/guile/" . "numeric-data-model") ("bytestructures/guile/" . "explicit-endianness") ("bytestructures/guile/" . "vector") ("bytestructures/guile/" . "base") ("bytestructures/guile/" . "utils") ("bytestructures/guile/" . "bytevectors") ("bytestructures/r6/" . "bytevectors") ("git/" . "types") ("git/" . "config") ("guix/" . "git-download") ("guix/" . "docker") ("" . "json") ("json/" . "parser") ("json/" . "builder") ("guix/" . "cvs-download") ("guix/" . "cve") ("guix/" . "cpio") ("guix/" . "ci") ("guix/" . "http-client") ("guix/" . "ui") ("texinfo/" . "plain-text") ("texinfo/" . "string-utils") ("srfi/" . "srfi-14") ("" . "texinfo") ("guix/" . "licenses") ("guix/" . "profiles") ("guix/" . "i18n") ("guix/" . "cache") ("guix/build-system/" . "waf") ("guix/build-system/" . "texlive") ("guix/" . "svn-download") ("guix/build-system/" . "scons") ("guix/build-system/" . "ruby") ("guix/build-system/" . "r") ("guix/build-system/" . "python") ("guix/build-system/" . "perl") ("guix/build-system/" . "ocaml") ("guix/build-system/" . "minify") ("guix/build-system/" . "meson") ("guix/build-system/" . "haskell") ("guix/build-system/" . "go") ("guix/build-system/" . "glib-or-gtk") ("guix/build-system/" . "font") ("guix/build-system/" . "emacs") ("guix/build-system/" . "dub") ("guix/build-system/" . "cmake") ("guix/build-system/" . "cargo") ("guix/build-system/" . "asdf") ("guix/build-system/" . "ant") ("guix/build-system/" . "android-ndk") ("guix/build-system/" . "gnu") ("guix/" . "packages") ("guix/" . "build-system") ("guix/" . "gexp") ("guix/" . "grafts") ("guix/" . "derivations") ("guix/" . "store") ("" . "gnutls") ("guix/" . "hash") ("guix/" . "gcrypt") ("guix/" . "base32") ("guix/" . "base16") ("guix/" . "monads") ("system/" . "syntax") ("guix/" . "utils") ("srfi/" . "srfi-39") ("guix/" . "search-paths") ("guix/build/" . "waf-build-system") ("guix/build/" . "texlive-build-system") ("guix/build/" . "union") ("guix/build/" . "svn") ("guix/build/" . "store-copy") ("guix/build/" . "scons-build-system") ("guix/build/" . "ruby-build-system") ("guix/build/" . "r-build-system") ("guix/build/" . "qt-utils") ("guix/build/" . "python-build-system") ("guix/build/" . "pull") ("guix/build/" . "perl-build-system") ("guix/build/" . "ocaml-build-system") ("guix/build/" . "minify-build-system") ("guix/build/" . "meson-build-system") ("guix/build/" . "rpath") ("guix/build/" . "make-bootstrap") ("guix/build/" . "java-utils") ("guix/build/" . "hg") ("guix/build/" . "haskell-build-system") ("guix/build/" . "graft") ("guix/build/" . "go-build-system") ("guix/build/" . "gnu-dist") ("guix/build/" . "glib-or-gtk-build-system") ("guix/build/" . "git") ("guix/build/" . "font-build-system") ("guix/build/" . "emacs-build-system") ("guix/build/" . "emacs-utils") ("guix/build/" . "dub-build-system") ("guix/build/" . "download-nar") ("guix/" . "zlib") ("guix/" . "config") ("guix/" . "serialization") ("guix/" . "combinators") ("guix/build/" . "download") ("guix/" . "progress") ("guix/" . "records") ("guix/" . "ftp-client") ("srfi/" . "srfi-31") ("guix/" . "base64") ("" . "rnrs") ("rnrs/" . "unicode") ("rnrs/" . "sorting") ("rnrs/" . "programs") ("rnrs/io/" . "simple") ("rnrs/arithmetic/" . "flonums") ("rnrs/" . "r5rs") ("ice-9/" . "r5rs") ("ice-9/" . "safe-r5rs") ("ice-9/" . "null") ("rnrs/arithmetic/" . "fixnums") ("web/" . "client") ("web/" . "response") ("web/" . "request") ("web/" . "http") ("ice-9/" . "textual-ports") ("web/" . "uri") ("guix/build/" . "cvs") ("guix/build/" . "cmake-build-system") ("guix/build/" . "cargo-build-system") ("guix/build/" . "bournish") ("system/repl/" . "command") ("" . "statprof") ("ice-9/" . "and-let-star") ("ice-9/" . "session") ("ice-9/" . "documentation") ("system/vm/" . "trap-state") ("system/vm/" . "trace") ("system/vm/" . "traps") ("system/" . "xref") ("system/repl/" . "debug") ("system/vm/" . "inspect") ("ice-9/" . "pretty-print") ("system/vm/" . "frame") ("system/vm/" . "disassembler") ("system/repl/" . "common") ("ice-9/" . "history") ("guix/build/" . "asdf-build-system") ("guix/build/" . "lisp-utils") ("ice-9/" . "hash-table") ("guix/build/" . "ant-build-system") ("sxml/" . "simple") ("sxml/" . "transform") ("sxml/" . "ssax") ("sxml/ssax/" . "input-parse") ("guix/build/" . "android-ndk-build-system") ("ice-9/" . "popen") ("guix/build/" . "syscalls") ("guix/build/" . "gnu-build-system") ("srfi/" . "srfi-19") ("ice-9/" . "i18n") ("srfi/" . "srfi-6") ("guix/build/" . "gremlin") ("guix/" . "elf") ("language/bytecode/" . "spec") ("language/cps/" . "spec") ("language/cps/" . "compile-bytecode") ("system/vm/" . "assembler") ("system/vm/" . "linker") ("language/cps/" . "split-rec") ("language/cps/" . "reify-primitives") ("language/cps/" . "handle-interrupts") ("language/cps/" . "closure-conversion") ("language/cps/" . "slot-allocation") ("language/tree-il/" . "spec") ("language/tree-il/" . "compile-cps") ("language/tree-il/" . "analyze") ("system/vm/" . "program") ("system/vm/" . "debug") ("system/vm/" . "loader") ("system/vm/" . "dwarf") ("system/vm/" . "elf") ("language/value/" . "spec") ("language/scheme/" . "spec") ("language/scheme/" . "decompile-tree-il") ("language/scheme/" . "compile-tree-il") ("guix/build/" . "compile") ("language/cps/" . "optimize") ("language/cps/" . "verify") ("language/cps/" . "primitives") ("language/" . "bytecode") ("language/cps/" . "type-fold") ("language/cps/" . "specialize-numbers") ("language/cps/" . "specialize-primcalls") ("language/cps/" . "simplify") ("language/cps/" . "self-references") ("language/cps/" . "rotate-loops") ("language/cps/" . "prune-bailouts") ("language/cps/" . "prune-top-level-scopes") ("language/cps/" . "peel-loops") ("language/cps/" . "licm") ("language/cps/" . "elide-values") ("language/cps/" . "dce") ("language/cps/" . "type-checks") ("language/cps/" . "types") ("language/cps/" . "cse") ("language/cps/" . "effects-analysis") ("language/cps/" . "contification") ("language/cps/" . "renumber") ("language/cps/" . "constructors") ("language/cps/" . "with-cps") ("language/cps/" . "utils") ("language/cps/" . "intmap") ("language/cps/" . "intset") ("language/" . "cps") ("language/tree-il/" . "optimize") ("language/tree-il/" . "debug") ("language/tree-il/" . "fix-letrec") ("language/tree-il/" . "peval") ("language/tree-il/" . "effects") ("language/tree-il/" . "primitives") ("srfi/" . "srfi-16") ("language/" . "tree-il") ("guix/build/" . "utils") ("rnrs/io/" . "ports") ("srfi/" . "srfi-8") ("rnrs/" . "files") ("rnrs/records/" . "syntactic") ("rnrs/" . "hashtables") ("srfi/" . "srfi-69") ("srfi/" . "srfi-13") ("rnrs/" . "enums") ("rnrs/" . "syntax-case") ("rnrs/" . "exceptions") ("rnrs/records/" . "inspection") ("rnrs/arithmetic/" . "bitwise") ("rnrs/" . "control") ("rnrs/" . "conditions") ("rnrs/records/" . "procedural") ("rnrs/" . "lists") ("ice-9/" . "iconv") ("rnrs/" . "base") ("ice-9/" . "binary-ports") ("ice-9/" . "rdelim") ("ice-9/" . "ftw") ("srfi/" . "srfi-60") ("guix/" . "modules") ("srfi/" . "srfi-35") ("srfi/" . "srfi-34") ("guix/" . "sets") ("ice-9/" . "vlist") ("guix/" . "memoization") ("guix/" . "profiling") ("system/base/" . "compile") ("ice-9/" . "receive") ("ice-9/" . "optargs") ("system/base/" . "pmatch") ("system/vm/" . "vm") ("system/base/" . "message") ("system/base/" . "language") ("system/base/" . "syntax") ("system/base/" . "target") ("system/" . "foreign") ("ice-9/" . "regex") ("ice-9/" . "format") ("srfi/" . "srfi-26") ("ice-9/" . "command-line") ("srfi/" . "srfi-4") ("rnrs/" . "bytevectors") ("ice-9/" . "ports") ("ice-9/" . "deprecated") ("ice-9/" . "threads") ("ice-9/" . "futures") ("ice-9/" . "q") ("srfi/" . "srfi-11") ("srfi/srfi-9/" . "gnu") ("srfi/" . "srfi-9") ("system/base/" . "ck") ("srfi/" . "srfi-1") ("ice-9/" . "control") ("ice-9/" . "match") (guile . guile))) at list.c:732
#4  0x00007ffff7b717fd in vm_regular_engine (thread=0x15, vp=0x804e10, registers=0x638fe0, resume=2308) at vm-engine.c:784
#5  0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 148efe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#6  0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 148efe0>) at eval.c:481
#7  0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 148efe0>) at async.c:400
#8  0x00007ffff7b717fd in vm_regular_engine (thread=0x15, vp=0x804e10, registers=0x638fe0, resume=2308) at vm-engine.c:784
#9  0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651f40>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#10 0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#11 0x00007ffff7b62b16 in really_launch (d=0x1653c40) at threads.c:794
#12 0x00007ffff7af22da in c_body (d=0x7fffe940fe50) at continuations.c:422
#13 0x00007ffff7b717fd in vm_regular_engine (thread=0x15, vp=0x804e10, registers=0x638fe0, resume=2308) at vm-engine.c:784
#14 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 1487c20>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#15 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 1487c20>) at eval.c:481
#16 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 1487c20>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1487c00, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1487be0) at throw.c:137
#17 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#18 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe940fe50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe940fe50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#19 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe940fe50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe940fe50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#20 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#21 0x00007ffff7b62c3c in with_guile (base=0x7fffe940feb8, data=0x7fffe940fee0) at threads.c:661
#22 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#23 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653c40, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#24 launch_thread (d=0x1653c40) at threads.c:803
#25 0x00007ffff7620567 in start_thread (arg=0x7fffe9410700) at pthread_create.c:463
#26 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 6 (Thread 0x7fffe9c11700 (LWP 6460)):
#0  scm_apply_subr (sp=0x7ffff7e082d8, nslots=3) at gsubr.c:300
#1  0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7e082d8, vp=0x804ea0, registers=0x7f42e0, resume=-136281360) at vm-engine.c:784
#2  0x00007ffff7b74e5a in scm_call_n (proc=#<program 7ffff2f1dd28>, argv=argv@entry=0x7fffe9c10348, nargs=nargs@entry=1) at vm.c:1257
#3  0x00007ffff7af7f18 in scm_call_1 (proc=<optimized out>, arg1=140737288552224) at eval.c:487
#4  0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7e082d8, vp=0x804ea0, registers=0x7f42e0, resume=-136281360) at vm-engine.c:784
#5  0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 756d00>, argv=<optimized out>, nargs=5) at vm.c:1257
#6  0x00007ffff7af828b in scm_apply_0 (proc=#<program 756d00>, args=()) at eval.c:594
#7  0x00007ffff7af8e8d in scm_apply_1 (proc=<optimized out>, arg1=arg1@entry=misc-error, args=<optimized out>) at eval.c:600
#8  0x00007ffff7b643ac in scm_throw (key=key@entry=misc-error, args=<optimized out>) at throw.c:266
#9  0x00007ffff7b64925 in scm_ithrow (key=key@entry=misc-error, args=<optimized out>, no_return=no_return@entry=1) at throw.c:611
#10 0x00007ffff7af6495 in scm_error_scm (key=misc-error, subr=<optimized out>, message=<optimized out>, args=<optimized out>, data=<optimized out>) at error.c:94
#11 0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7e082d8, vp=0x804ea0, registers=0x7f42e0, resume=-136281360) at vm-engine.c:784
#12 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<program 1489fe0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#13 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<program 1489fe0>) at eval.c:481
#14 0x00007ffff7ae9538 in scm_call_with_unblocked_asyncs (proc=#<program 1489fe0>) at async.c:400
#15 0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7e082d8, vp=0x804ea0, registers=0x7f42e0, resume=-136281360) at vm-engine.c:784
#16 0x00007ffff7b74e5a in scm_call_n (proc=#<program 1651f80>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#17 0x00007ffff7af7ef9 in scm_call_0 (proc=<optimized out>) at eval.c:481
#18 0x00007ffff7b62b16 in really_launch (d=0x1653c80) at threads.c:794
#19 0x00007ffff7af22da in c_body (d=0x7fffe9c10e50) at continuations.c:422
#20 0x00007ffff7b717fd in vm_regular_engine (thread=0x7ffff7e082d8, vp=0x804ea0, registers=0x7f42e0, resume=-136281360) at vm-engine.c:784
#21 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 1487fa0>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#22 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 1487fa0>) at eval.c:481
#23 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 1487fa0>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1487f80, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x1487f60) at throw.c:137
#24 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#25 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe9c10e50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe9c10e50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#26 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffe9c10e50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffe9c10e50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#27 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#28 0x00007ffff7b62c3c in with_guile (base=0x7fffe9c10eb8, data=0x7fffe9c10ee0) at threads.c:661
#29 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#30 0x00007ffff7b6230d in scm_i_with_guile (dynamic_state=<optimized out>, data=0x1653c80, func=0x7ffff7b62aa0 <really_launch>) at threads.c:704
#31 launch_thread (d=0x1653c80) at threads.c:803
#32 0x00007ffff7620567 in start_thread (arg=0x7fffe9c11700) at pthread_create.c:463
#33 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 5 (Thread 0x7ffff3ee8700 (LWP 6458)):
#0  0x00007ffff7629aac in __libc_read (fd=5, buf=buf@entry=0x7ffff3ee7a30, nbytes=nbytes@entry=1) at ../sysdeps/unix/sysv/linux/read.c:27
#1  0x00007ffff7b014d7 in read_finalization_pipe_data (data=0x7ffff3ee7a30) at finalizers.c:199
#2  0x00007ffff785ab63 in GC_do_blocking_inner () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#3  0x00007ffff784f389 in GC_with_callee_saves_pushed () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#4  0x00007ffff7854fec in GC_do_blocking () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#5  0x00007ffff7b6302a in scm_without_guile (func=0x7ffff7b014c0 <read_finalization_pipe_data>, data=0x7ffff3ee7a30) at threads.c:722
#6  0x00007ffff7b01887 in finalization_thread_proc (unused=<optimized out>) at finalizers.c:212
#7  0x00007ffff7af22da in c_body (d=0x7ffff3ee7e50) at continuations.c:422
#8  0x00007ffff7b717fd in vm_regular_engine (thread=0x5, vp=0x804f30, registers=0x1, resume=-144532820) at vm-engine.c:784
#9  0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 83af60>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#10 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 83af60>) at eval.c:481
#11 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 83af60>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x83af40, 
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x83af00) at throw.c:137
#12 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#13 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7ffff3ee7e50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7ffff3ee7e50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#14 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7ffff3ee7e50, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7ffff3ee7e50, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#15 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#16 0x00007ffff7b62c3c in with_guile (base=0x7ffff3ee7eb8, data=0x7ffff3ee7ee0) at threads.c:661
#17 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#18 0x00007ffff7b62fd8 in scm_i_with_guile (dynamic_state=<optimized out>, data=<optimized out>, func=<optimized out>) at threads.c:704
#19 scm_with_guile (func=<optimized out>, data=<optimized out>) at threads.c:710
#20 0x00007ffff7620567 in start_thread (arg=0x7ffff3ee8700) at pthread_create.c:463
#21 0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 4 (Thread 0x7ffff4e54700 (LWP 6457)):
#0  0x00007ffff7626552 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x7ffff7a796e8 <mark_cv+40>) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0x7ffff7a792c0 <mark_mutex>, cond=0x7ffff7a796c0 <mark_cv>) at pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0x7ffff7a796c0 <mark_cv>, mutex=0x7ffff7a792c0 <mark_mutex>) at pthread_cond_wait.c:655
#3  0x00007ffff785b967 in GC_wait_marker () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#4  0x00007ffff7851e5a in GC_help_marker () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#5  0x00007ffff785b93c in GC_mark_thread () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#6  0x00007ffff7620567 in start_thread (arg=0x7ffff4e54700) at pthread_create.c:463
#7  0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 3 (Thread 0x7ffff5655700 (LWP 6456)):
#0  0x00007ffff7626552 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x7ffff7a796e8 <mark_cv+40>) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0x7ffff7a792c0 <mark_mutex>, cond=0x7ffff7a796c0 <mark_cv>) at pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0x7ffff7a796c0 <mark_cv>, mutex=0x7ffff7a792c0 <mark_mutex>) at pthread_cond_wait.c:655
#3  0x00007ffff785b967 in GC_wait_marker () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#4  0x00007ffff7851e5a in GC_help_marker () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#5  0x00007ffff785b93c in GC_mark_thread () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#6  0x00007ffff7620567 in start_thread (arg=0x7ffff5655700) at pthread_create.c:463
#7  0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 2 (Thread 0x7ffff5e56700 (LWP 6455)):
#0  0x00007ffff7626552 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x7ffff7a796e8 <mark_cv+40>) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0x7ffff7a792c0 <mark_mutex>, cond=0x7ffff7a796c0 <mark_cv>) at pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0x7ffff7a796c0 <mark_cv>, mutex=0x7ffff7a792c0 <mark_mutex>) at pthread_cond_wait.c:655
#3  0x00007ffff785b967 in GC_wait_marker () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#4  0x00007ffff7851e5a in GC_help_marker () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#5  0x00007ffff785b93c in GC_mark_thread () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#6  0x00007ffff7620567 in start_thread (arg=0x7ffff5e56700) at pthread_create.c:463
#7  0x00007ffff5f48eaf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7ffff7fefb80 (LWP 6451)):
#0  0x00007ffff7626552 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x686e64) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0x154b3c0, cond=cond@entry=0x686e38) at pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=cond@entry=0x686e38, mutex=mutex@entry=0x154b3c0) at pthread_cond_wait.c:655
#3  0x00007ffff7b634c5 in scm_pthread_cond_wait (cond=cond@entry=0x686e38, mutex=mutex@entry=0x154b3c0) at threads.c:1621
#4  0x00007ffff7b6368b in block_self (queue=((#<smob thread 6bde90>) #<smob thread 6bde90>), mutex=mutex@entry=0x154b3c0, waittime=waittime@entry=0x0) at threads.c:316
#5  0x00007ffff7b63b70 in timed_wait (c=0x1650a80, current_thread=0x686e00, current_thread=0x686e00, waittime=0x0, m=0x154b3c0, kind=SCM_MUTEX_STANDARD) at threads.c:1347
#6  scm_timed_wait_condition_variable (cond=#<smob condition-variable 149cdc0>, mutex=#<smob mutex 149cd90>, timeout=#<undefined 904>) at threads.c:1440
#7  0x00007ffff7b717fd in vm_regular_engine (thread=0x686e64, vp=0x72bf30, registers=0x0, resume=-144546478) at vm-engine.c:784
#8  0x00007ffff7b74e5a in scm_call_n (proc=#<program 7ffff7e5c030>, argv=argv@entry=0x7fffffffc038, nargs=nargs@entry=1) at vm.c:1257
#9  0x00007ffff7af8ff7 in scm_primitive_eval (
    exp=(begin (use-modules (srfi srfi-26) (ice-9 match) (ice-9 format) (ice-9 threads) (guix build compile) (guix build utils)) (define (regular? file) (not (member file (quote ("." ".."))))) (define (report-load file total completed) (display #\return) (format #t "loading...\t~5,1f% of ~d files" (* 100.0 (/ completed total)) total) (force-output)) (define (report-compilation file total completed) (display #\return) (format #t "compiling...\t~5,1f% of ~d files" (* 100.0 (/ completed total)) total) (force-output)) (define (process-directory directory files output) (parameterize ((current-warning-port (%make-void-port "w"))) (compile-files directory ((@ (guile) getenv) "out") files #:workers (parallel-job-count) #:report-load report-load #:report-compilation report-compilation))) (setvbuf (current-output-port) _IONBF) (setvbuf (current-error-port) _IONBF) (set! %load-path (cons "/gnu/store/7ylh9biay97wi1j5zza43si5g0kcr0rk-guix-extra-source" %load-path)) (set! %load-path (append (quote ("/gnu/store/6qa3bz89xr8p3a1cl1rjz6vg4i51rj77-guix-core-source")) (map (lambda (extension) (string-append extension "/share/guile/site/" (effective-version))) (quote ("/gnu/store/2rfa6337gb84bx4f2jzn5h9wfi3lhjik-guile-git-0.0-6.36f93c1" "/gnu/store/1aglyrvw57cbw4njc2q4blmbqin3r7k2-guile-bytestructures-1.0.3" "/gnu/store/6jjn9fsma94qa6y86qwiyyqfsm2mjkxy-guile-json-1.0.1" "/gnu/store/5lmr2x0cl45x0f15hsbaw4y560gnwry3-guile-ssh-0.11.2" "/gnu/store/r21yw2lkm4fr1n7x1nxgpqrjw0xkln9r-guile-sqlite3-0.0-4.10c13a7"))) %load-path)) (set! %load-compiled-path (append (quote ("/gnu/store/fw419jy6qwkwfclj2vr56va4nwnrwczn-guix-core")) (map (lambda (extension) (string-append extension "/lib/guile/" (effective-version) "/site-ccache")) (quote ("/gnu/store/2rfa6337gb84bx4f2jzn5h9wfi3lhjik-guile-git-0.0-6.36f93c1" "/gnu/store/1aglyrvw57cbw4njc2q4blmbqin3r7k2-guile-bytestructures-1.0.3" "/gnu/store/6jjn9fsma94qa6y86qwiyyqfsm2mjkxy-guile-json-1.0.1" "/gnu/store/5lmr2x0cl45x0f15hsbaw4y560gnwry3-guile-ssh-0.11.2" "/gnu/store/r21yw2lkm4fr1n7x1nxgpqrjw0xkln9r-guile-sqlite3-0.0-4.10c13a7"))) %load-compiled-path)) (compile #f) (mkdir ((@ (guile) getenv) "out")) (chdir "/gnu/store/7ylh9biay97wi1j5zza43si5g0kcr0rk-guix-extra-source") (process-directory "." (quote ("guix/build/android-ndk-build-system.scm" "guix/build/ant-build-system.scm" "guix/build/asdf-build-system.scm" "guix/build/lisp-utils.scm" "guix/build/bournish.scm" "guix/build/cargo-build-system.scm" "guix/build/cmake-build-system.scm" "guix/build/compile.scm" "guix/build/cvs.scm" "guix/build/download-nar.scm" "guix/zlib.scm" "guix/build/dub-build-system.scm" "guix/build/emacs-build-system.scm" "guix/build/emacs-utils.scm" "guix/build/font-build-system.scm" "guix/build/git.scm" "guix/build/glib-or-gtk-build-system.scm" "guix/build/gnu-dist.scm" "guix/build/go-build-system.scm" "guix/build/graft.scm" "guix/build/haskell-build-system.scm" "guix/build/hg.scm" "guix/build/java-utils.scm" "guix/build/make-bootstrap.scm" "guix/build/meson-build-system.scm" "guix/build/rpath.scm" "guix/build/minify-build-system.scm" "guix/build/ocaml-build-system.scm" "guix/build/perl-build-system.scm" "guix/build/pull.scm" "guix/build/python-build-system.scm" "guix/build/qt-utils.scm" "guix/build/r-build-system.scm" "guix/build/ruby-build-system.scm" "guix/build/scons-build-system.scm" "guix/build/store-copy.scm" "guix/build/svn.scm" "guix/build/texlive-build-system.scm" "guix/build/waf-build-system.scm" "guix/build-system/android-ndk.scm" "guix/build-system/ant.scm" "guix/build-system/asdf.scm" "guix/build-system/cargo.scm" "guix/build-system/cmake.scm" "guix/build-system/dub.scm" "guix/build-system/emacs.scm" "guix/build-system/font.scm" "guix/build-system/glib-or-gtk.scm" "guix/build-system/go.scm" "guix/build-system/haskell.scm" "guix/build-system/meson.scm" "guix/build-system/minify.scm" "guix/build-system/ocaml.scm" "guix/build-system/perl.scm" "guix/build-system/python.scm" "guix/build-system/r.scm" "guix/build-system/ruby.scm" "guix/build-system/scons.scm" "guix/build-system/texlive.scm" "guix/svn-download.scm" "guix/build-system/waf.scm" "guix/cache.scm" "guix/ci.scm" "guix/http-client.scm" "guix/ui.scm" "guix/licenses.scm" "guix/cpio.scm" "guix/cve.scm" "guix/cvs-download.scm" "guix/docker.scm" "guix/git-download.scm" "guix/git.scm" "guix/glob.scm" "guix/gnu-maintenance.scm" "guix/upstream.scm" "guix/gnupg.scm" "guix/graph.scm" "guix/hg-download.scm" "guix/import/cabal.scm" "guix/import/cpan.scm" "guix/import/utils.scm" "gnu/packages.scm" "guix/import/json.scm" "guix/import/cran.scm" "guix/import/crate.scm" "guix/import/elpa.scm" "guix/import/gem.scm" "guix/import/github.scm" "guix/import/gnome.scm" "guix/import/gnu.scm" "guix/import/hackage.scm" "guix/import/print.scm" "guix/import/pypi.scm" "guix/import/snix.scm" "guix/import/stackage.scm" "guix/import/texlive.scm" "guix/nar.scm" "guix/store/database.scm" "guix/store/deduplication.scm" "guix/pki.scm" "guix/pk-crypto.scm" "guix/scripts.scm" "guix/self.scm" "guix/ssh.scm" "guix/store/ssh.scm" "guix/tests/http.scm" "guix/tests.scm" "gnu/packages/bootstrap.scm" "guix/workers.scm")) ((@ (guile) getenv) "out")) (newline))) at eval.c:662
#10 0x00007ffff7b14cdb in scm_primitive_load (filename=<optimized out>) at load.c:123
#11 0x00007ffff7b717fd in vm_regular_engine (thread=0x686e64, vp=0x72bf30, registers=0x0, resume=-144546478) at vm-engine.c:784
#12 0x00007ffff7b74e5a in scm_call_n (proc=#<program 7ffff7e5c030>, argv=argv@entry=0x7fffffffc298, nargs=nargs@entry=1) at vm.c:1257
#13 0x00007ffff7af8ff7 in scm_primitive_eval (
    exp=exp@entry=((@ (ice-9 control) %) (begin (set! %load-path (cons "." %load-path)) (set! %load-compiled-path (cons "." %load-compiled-path)) ((@@ (ice-9 command-line) load/lang) "/gnu/store/815przlfissan60p4bdn7cipfidc3q29-guix-extra-builder") (quit)))) at eval.c:662
#14 0x00007ffff7af9053 in scm_eval (
    exp=((@ (ice-9 control) %) (begin (set! %load-path (cons "." %load-path)) (set! %load-compiled-path (cons "." %load-compiled-path)) ((@@ (ice-9 command-line) load/lang) "/gnu/store/815przlfissan60p4bdn7cipfidc3q29-guix-extra-builder") (quit))), module_or_state=module_or_state@entry="#<struct module>" = {...}) at eval.c:696
#15 0x00007ffff7b440b0 in scm_shell (argc=7, argv=0x7fffffffc908) at script.c:454
#16 0x00007ffff7b0fadd in invoke_main_func (body_data=0x7fffffffc7b0) at init.c:340
#17 0x00007ffff7af22da in c_body (d=0x7fffffffc6f0) at continuations.c:422
#18 0x00007ffff7b717fd in vm_regular_engine (thread=0x686e64, vp=0x72bf30, registers=0x0, resume=-144546478) at vm-engine.c:784
#19 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 71e520>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#20 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 71e520>) at eval.c:481
#21 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 71e520>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x71e4c0, 
urrent-warning-port (%make-void-port "w"))) (compile-files directory ((@ (guile) getenv) "out") files #:workers (parallel-job-count) #:report-load report-load #:report-compilation report-compilation))) (setvbuf (current-output-port) _IONBF) (setvbuf (current-error-port) _IONBF) (set! %load-path (cons "/gnu/store/7ylh9biay97wi1j5zza43si5g0kcr0rk-guix-extra-source" %load-path)) (set! %load-path (append (quote ("/gnu/store/6qa3bz89xr8p3a1cl1rjz6vg4i51rj77-guix-core-source")) (map (lambda (extension) (string-append extension "/share/guile/site/" (effective-version))) (quote ("/gnu/store/2rfa6337gb84bx4f2jzn5h9wfi3lhjik-guile-git-0.0-6.36f93c1" "/gnu/store/1aglyrvw57cbw4njc2q4blmbqin3r7k2-guile-bytestructures-1.0.3" "/gnu/store/6jjn9fsma94qa6y86qwiyyqfsm2mjkxy-guile-json-1.0.1" "/gnu/store/5lmr2x0cl45x0f15hsbaw4y560gnwry3-guile-ssh-0.11.2" "/gnu/store/r21yw2lkm4fr1n7x1nxgpqrjw0xkln9r-guile-sqlite3-0.0-4.10c13a7"))) %load-path)) (set! %load-compiled-path (append (quote ("/gnu/store/fw419jy6qwkwfclj2vr56va4nwnrwczn-guix-core")) (map (lambda (extension) (string-append extension "/lib/guile/" (effective-version) "/site-ccache")) (quote ("/gnu/store/2rfa6337gb84bx4f2jzn5h9wfi3lhjik-guile-git-0.0-6.36f93c1" "/gnu/store/1aglyrvw57cbw4njc2q4blmbqin3r7k2-guile-bytestructures-1.0.3" "/gnu/store/6jjn9fsma94qa6y86qwiyyqfsm2mjkxy-guile-json-1.0.1" "/gnu/store/5lmr2x0cl45x0f15hsbaw4y560gnwry3-guile-ssh-0.11.2" "/gnu/store/r21yw2lkm4fr1n7x1nxgpqrjw0xkln9r-guile-sqlite3-0.0-4.10c13a7"))) %load-compiled-path)) (compile #f) (mkdir ((@ (guile) getenv) "out")) (chdir "/gnu/store/7ylh9biay97wi1j5zza43si5g0kcr0rk-guix-extra-source") (process-directory "." (quote ("guix/build/android-ndk-build-system.scm" "guix/build/ant-build-system.scm" "guix/build/asdf-build-system.scm" "guix/build/lisp-utils.scm" "guix/build/bournish.scm" "guix/build/cargo-build-system.scm" "guix/build/cmake-build-system.scm" "guix/build/compile.scm" "guix/build/cvs.scm" "guix/build/download-nar.scm" "guix/zlib.scm" "guix/build/dub-build-system.scm" "guix/build/emacs-build-system.scm" "guix/build/emacs-utils.scm" "guix/build/font-build-system.scm" "guix/build/git.scm" "guix/build/glib-or-gtk-build-system.scm" "guix/build/gnu-dist.scm" "guix/build/go-build-system.scm" "guix/build/graft.scm" "guix/build/haskell-build-system.scm" "guix/build/hg.scm" "guix/build/java-utils.scm" "guix/build/make-bootstrap.scm" "guix/build/meson-build-system.scm" "guix/build/rpath.scm" "guix/build/minify-build-system.scm" "guix/build/ocaml-build-system.scm" "guix/build/perl-build-system.scm" "guix/build/pull.scm" "guix/build/python-build-system.scm" "guix/build/qt-utils.scm" "guix/build/r-build-system.scm" "guix/build/ruby-build-system.scm" "guix/build/scons-build-system.scm" "guix/build/store-copy.scm" "guix/build/svn.scm" "guix/build/texlive-build-system.scm" "guix/build/waf-build-system.scm" "guix/build-system/android-ndk.scm" "guix/build-system/ant.scm" "guix/build-system/asdf.scm" "guix/build-system/cargo.scm" "guix/build-system/cmake.scm" "guix/build-system/dub.scm" "guix/build-system/emacs.scm" "guix/build-system/font.scm" "guix/build-system/glib-or-gtk.scm" "guix/build-system/go.scm" "guix/build-system/haskell.scm" "guix/build-system/meson.scm" "guix/build-system/minify.scm" "guix/build-system/ocaml.scm" "guix/build-system/perl.scm" "guix/build-system/python.scm" "guix/build-system/r.scm" "guix/build-system/ruby.scm" "guix/build-system/scons.scm" "guix/build-system/texlive.scm" "guix/svn-download.scm" "guix/build-system/waf.scm" "guix/cache.scm" "guix/ci.scm" "guix/http-client.scm" "guix/ui.scm" "guix/licenses.scm" "guix/cpio.scm" "guix/cve.scm" "guix/cvs-download.scm" "guix/docker.scm" "guix/git-download.scm" "guix/git.scm" "guix/glob.scm" "guix/gnu-maintenance.scm" "guix/upstream.scm" "guix/gnupg.scm" "guix/graph.scm" "guix/hg-download.scm" "guix/import/cabal.scm" "guix/import/cpan.scm" "guix/import/utils.scm" "gnu/packages.scm" "guix/import/json.scm" "guix/import/cran.scm" "guix/import/crate.scm" "guix/import/elpa.scm" "guix/import/gem.scm" "guix/import/github.scm" "guix/import/gnome.scm" "guix/import/gnu.scm" "guix/import/hackage.scm" "guix/import/print.scm" "guix/import/pypi.scm" "guix/import/snix.scm" "guix/import/stackage.scm" "guix/import/texlive.scm" "guix/nar.scm" "guix/store/database.scm" "guix/store/deduplication.scm" "guix/pki.scm" "guix/pk-crypto.scm" "guix/scripts.scm" "guix/self.scm" "guix/ssh.scm" "guix/store/ssh.scm" "guix/tests/http.scm" "guix/tests.scm" "gnu/packages/bootstrap.scm" "guix/workers.scm")) ((@ (guile) getenv) "out")) (newline))) at eval.c:662
#10 0x00007ffff7b14cdb in scm_primitive_load (filename=<optimized out>) at load.c:123
#11 0x00007ffff7b717fd in vm_regular_engine (thread=0x686e64, vp=0x72bf30, registers=0x0, resume=-144546478) at vm-engine.c:784
#12 0x00007ffff7b74e5a in scm_call_n (proc=#<program 7ffff7e5c030>, argv=argv@entry=0x7fffffffc298, nargs=nargs@entry=1) at vm.c:1257
#13 0x00007ffff7af8ff7 in scm_primitive_eval (
    exp=exp@entry=((@ (ice-9 control) %) (begin (set! %load-path (cons "." %load-path)) (set! %load-compiled-path (cons "." %load-compiled-path)) ((@@ (ice-9 command-line) load/lang) "/gnu/store/815przlfissan60p4bdn7cipfidc3q29-guix-extra-builder") (quit)))) at eval.c:662
#14 0x00007ffff7af9053 in scm_eval (
    exp=((@ (ice-9 control) %) (begin (set! %load-path (cons "." %load-path)) (set! %load-compiled-path (cons "." %load-compiled-path)) ((@@ (ice-9 command-line) load/lang) "/gnu/store/815przlfissan60p4bdn7cipfidc3q29-guix-extra-builder") (quit))), module_or_state=module_or_state@entry="#<struct module>" = {...}) at eval.c:696
#15 0x00007ffff7b440b0 in scm_shell (argc=7, argv=0x7fffffffc908) at script.c:454
#16 0x00007ffff7b0fadd in invoke_main_func (body_data=0x7fffffffc7b0) at init.c:340
#17 0x00007ffff7af22da in c_body (d=0x7fffffffc6f0) at continuations.c:422
#18 0x00007ffff7b717fd in vm_regular_engine (thread=0x686e64, vp=0x72bf30, registers=0x0, resume=-144546478) at vm-engine.c:784
#19 0x00007ffff7b74e5a in scm_call_n (proc=proc@entry=#<smob catch-closure 71e520>, argv=argv@entry=0x0, nargs=nargs@entry=0) at vm.c:1257
#20 0x00007ffff7af7ef9 in scm_call_0 (proc=proc@entry=#<smob catch-closure 71e520>) at eval.c:481
#21 0x00007ffff7b64026 in catch (tag=tag@entry=#t, thunk=#<smob catch-closure 71e520>, handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x71e4c0, 
---Type <return> to continue, or q <return> to quit---
    pre_unwind_handler=<error reading variable: ERROR: Cannot access memory at address 0x0>0x71e4a0) at throw.c:137
#22 0x00007ffff7b64365 in scm_catch_with_pre_unwind_handler (key=key@entry=#t, thunk=<optimized out>, handler=<optimized out>, pre_unwind_handler=<optimized out>) at throw.c:254
#23 0x00007ffff7b6451f in scm_c_catch (tag=tag@entry=#t, body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffffffc6f0, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffffffc6f0, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at throw.c:377
#24 0x00007ffff7af28c0 in scm_i_with_continuation_barrier (body=body@entry=0x7ffff7af22d0 <c_body>, body_data=body_data@entry=0x7fffffffc6f0, handler=handler@entry=0x7ffff7af2560 <c_handler>, 
    handler_data=handler_data@entry=0x7fffffffc6f0, pre_unwind_handler=pre_unwind_handler@entry=0x7ffff7af23c0 <pre_unwind_handler>, pre_unwind_handler_data=0x726bc0) at continuations.c:360
#25 0x00007ffff7af2955 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:456
#26 0x00007ffff7b62c3c in with_guile (base=0x7fffffffc758, data=0x7fffffffc780) at threads.c:661
#27 0x00007ffff7854fb8 in GC_call_with_stack_base () from /gnu/store/kxga4lq2qfn0rn8yyjz86dk40bxzjhlq-libgc-7.6.4/lib/libgc.so.1
#28 0x00007ffff7b62fd8 in scm_i_with_guile (dynamic_state=<optimized out>, data=data@entry=0x7fffffffc780, func=func@entry=0x7ffff7b0fac0 <invoke_main_func>) at threads.c:704
#29 scm_with_guile (func=func@entry=0x7ffff7b0fac0 <invoke_main_func>, data=data@entry=0x7fffffffc7b0) at threads.c:710
#30 0x00007ffff7b0fc72 in scm_boot_guile (argc=argc@entry=7, argv=argv@entry=0x7fffffffc908, main_func=main_func@entry=0x400ce0 <inner_main>, closure=closure@entry=0x0) at init.c:323
#31 0x0000000000400b80 in main (argc=7, argv=0x7fffffffc908) at guile.c:101

--8<---------------cut here---------------end--------------->8---





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-06-18  9:43 bug#31878: Module autoloading is not thread safe Ludovic Courtès
@ 2018-06-18 11:11 ` Ludovic Courtès
  2018-06-18 12:17   ` Ludovic Courtès
  2022-04-04 11:47 ` Calvin Heim
  1 sibling, 1 reply; 12+ messages in thread
From: Ludovic Courtès @ 2018-06-18 11:11 UTC (permalink / raw)
  To: 31878, Andy Wingo

[-- Attachment #1: Type: text/plain, Size: 274 bytes --]

ludo@gnu.org (Ludovic Courtès) skribis:

> I believe this comes from the fact that ‘autoloads-done’ and related
> alists in (ice-9 boot-9) are manipulated in a non-thread-safe fashion.

Here’s a proposed fix for ‘stable-2.2’ as discussed on #guile, Andy:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 5282 bytes --]

diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index 4e51e9281..960cb9fa3 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -1,6 +1,6 @@
 ;;; -*- mode: scheme; coding: utf-8; -*-
 
-;;;; Copyright (C) 1995-2014, 2016-2017  Free Software Foundation, Inc.
+;;;; Copyright (C) 1995-2014, 2016-2018  Free Software Foundation, Inc.
 ;;;;
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
@@ -2952,8 +2952,11 @@ module '(ice-9 q) '(make-q q-length))}."
 ;;; {Autoloading modules}
 ;;;
 
-;;; XXX FIXME autoloads-in-progress and autoloads-done
-;;;           are not handled in a thread-safe way.
+(define (call-with-module-autoload-lock thunk)
+  ;; This binding is overridden when (ice-9 threads) is available to
+  ;; implement a critical section around the call to THUNK.  It must be
+  ;; used anytime the autoload variables below are used.
+  (thunk))
 
 (define autoloads-in-progress '())
 
@@ -2973,37 +2976,40 @@ but it fails to load."
                                                 file-name-separator-string))
                                dir-hint-module-name))))
     (resolve-module dir-hint-module-name #f)
-    (and (not (autoload-done-or-in-progress? dir-hint name))
-         (let ((didit #f))
-           (dynamic-wind
-            (lambda () (autoload-in-progress! dir-hint name))
-            (lambda ()
-              (with-fluids ((current-reader #f))
-                (save-module-excursion
-                 (lambda () 
-                   (define (call/ec proc)
-                     (let ((tag (make-prompt-tag)))
-                       (call-with-prompt
-                        tag
-                        (lambda ()
-                          (proc (lambda () (abort-to-prompt tag))))
-                        (lambda (k) (values)))))
-                   ;; The initial environment when loading a module is a fresh
-                   ;; user module.
-                   (set-current-module (make-fresh-user-module))
-                   ;; Here we could allow some other search strategy (other than
-                   ;; primitive-load-path), for example using versions encoded
-                   ;; into the file system -- but then we would have to figure
-                   ;; out how to locate the compiled file, do auto-compilation,
-                   ;; etc. Punt for now, and don't use versions when locating
-                   ;; the file.
-                   (call/ec
-                    (lambda (abort)
-                      (primitive-load-path (in-vicinity dir-hint name)
-                                           abort)
-                      (set! didit #t)))))))
-            (lambda () (set-autoloaded! dir-hint name didit)))
-           didit))))
+
+    (call-with-module-autoload-lock
+     (lambda ()
+       (and (not (autoload-done-or-in-progress? dir-hint name))
+            (let ((didit #f))
+              (dynamic-wind
+                (lambda () (autoload-in-progress! dir-hint name))
+                (lambda ()
+                  (with-fluids ((current-reader #f))
+                    (save-module-excursion
+                     (lambda () 
+                       (define (call/ec proc)
+                         (let ((tag (make-prompt-tag)))
+                           (call-with-prompt
+                               tag
+                             (lambda ()
+                               (proc (lambda () (abort-to-prompt tag))))
+                             (lambda (k) (values)))))
+                       ;; The initial environment when loading a module is a fresh
+                       ;; user module.
+                       (set-current-module (make-fresh-user-module))
+                       ;; Here we could allow some other search strategy (other than
+                       ;; primitive-load-path), for example using versions encoded
+                       ;; into the file system -- but then we would have to figure
+                       ;; out how to locate the compiled file, do auto-compilation,
+                       ;; etc. Punt for now, and don't use versions when locating
+                       ;; the file.
+                       (call/ec
+                        (lambda (abort)
+                          (primitive-load-path (in-vicinity dir-hint name)
+                                               abort)
+                          (set! didit #t)))))))
+                (lambda () (set-autoloaded! dir-hint name didit)))
+              didit))))))
 
 \f
 
@@ -4061,6 +4067,19 @@ when none is available, reading FILE-NAME with READER."
 ;; Load (ice-9 threads), initializing some internal data structures.
 (resolve-interface '(ice-9 threads))
 
+(set! call-with-module-autoload-lock
+  (let* ((threads (resolve-module '(ice-9 threads)))
+         (mutex   ((module-ref threads 'make-mutex) 'recursive))
+         (lock    (module-ref threads 'lock-mutex))
+         (unlock  (module-ref threads 'unlock-mutex)))
+    (lambda (thunk)
+      (dynamic-wind
+        (lambda ()
+          (lock mutex))
+        thunk
+        (lambda ()
+          (unlock mutex))))))
+
 \f
 
 ;;; SRFI-4 in the default environment.  FIXME: we should figure out how

[-- Attachment #3: Type: text/plain, Size: 44 bytes --]


How does that look?

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-06-18 11:11 ` Ludovic Courtès
@ 2018-06-18 12:17   ` Ludovic Courtès
  2018-08-22 23:22     ` Mark H Weaver
       [not found]     ` <876002dm18.fsf@netris.org>
  0 siblings, 2 replies; 12+ messages in thread
From: Ludovic Courtès @ 2018-06-18 12:17 UTC (permalink / raw)
  To: 31878-done; +Cc: Andy Wingo

ludo@gnu.org (Ludovic Courtès) skribis:

> ludo@gnu.org (Ludovic Courtès) skribis:
>
>> I believe this comes from the fact that ‘autoloads-done’ and related
>> alists in (ice-9 boot-9) are manipulated in a non-thread-safe fashion.
>
> Here’s a proposed fix for ‘stable-2.2’ as discussed on #guile, Andy:

After further discussion on IRC, I pushed a variant of this patch as
commit 761cf0fb8c364e885e4c6fced34563f8157c3b84.

Ludo’.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-06-18 12:17   ` Ludovic Courtès
@ 2018-08-22 23:22     ` Mark H Weaver
  2018-08-23  2:18       ` Mark H Weaver
       [not found]     ` <876002dm18.fsf@netris.org>
  1 sibling, 1 reply; 12+ messages in thread
From: Mark H Weaver @ 2018-08-22 23:22 UTC (permalink / raw)
  To: 31878

Hi Ludovic,

ludo@gnu.org (Ludovic Courtès) writes:

> ludo@gnu.org (Ludovic Courtès) skribis:
>
>> ludo@gnu.org (Ludovic Courtès) skribis:
>>
>>> I believe this comes from the fact that ‘autoloads-done’ and related
>>> alists in (ice-9 boot-9) are manipulated in a non-thread-safe fashion.
>>
>> Here’s a proposed fix for ‘stable-2.2’ as discussed on #guile, Andy:
>
> After further discussion on IRC, I pushed a variant of this patch as
> commit 761cf0fb8c364e885e4c6fced34563f8157c3b84.

There are problems with this fix, e.g. <https://bugs.gnu.org/32367>.

More generally, nearly arbitrary code can be run in the top-level
expressions of a module.  It could launch other threads which try to
load modules, or even send messages to other existing threads asking
them to do work.  In some cases, the body of the module might never
terminate.  The entire main program might be run from there.  I suspect
that's not unusual.

I can see another problem as well: while the module is in the process of
loading, the partially-loaded module is globally visible and accessible
to other threads.  If I'm not mistaken, with this patch, there's nothing
preventing other threads from attempting to use the partially-loaded
module.

I thought about how to fix this thread-safety problem a long time ago,
and came up with a rough outline of a solution.  The idea is that the
module should not be added to the global module table until the module
has finished loading.  While the module is being loaded, it would be
made visible only to the loading thread, and to any other threads
spawned during the loading process, by adding the module to a local list
of modules-being-loaded referenced by a fluid variable.  If any other
threads attempt to access the module, it would not be found in the
global module table, and thus trigger an auto-load, which would wait for
the lock to be released before proceeding.

What do you think?

      Mark






^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-08-22 23:22     ` Mark H Weaver
@ 2018-08-23  2:18       ` Mark H Weaver
  2018-08-23 13:54         ` Ludovic Courtès
  0 siblings, 1 reply; 12+ messages in thread
From: Mark H Weaver @ 2018-08-23  2:18 UTC (permalink / raw)
  To: 31878; +Cc: Ludovic Courtès

I wrote:

> I thought about how to fix this thread-safety problem a long time ago,
> and came up with a rough outline of a solution.  The idea is that the
> module should not be added to the global module table until the module
> has finished loading.  While the module is being loaded, it would be
> made visible only to the loading thread, and to any other threads
> spawned during the loading process, by adding the module to a local list
> of modules-being-loaded referenced by a fluid variable.  If any other
> threads attempt to access the module, it would not be found in the
> global module table, and thus trigger an auto-load, which would wait for
> the lock to be released before proceeding.

I forgot to mention an important aspect of the proposed auto-load
locking here.  It would not be a global lock, but rather a lock specific
to the module being loaded.  So, I guess we would need a global table of
locks for modules-being-loaded.

Since Guile (unfortunately) allows cyclic module dependencies, we would
need a mechanism to avoid deadlocks in case modules A and B both import
each other, and two threads concurrently attempt to load those modules.

The first idea that comes to mind is to also have a global structure
storing a partial order on the modules currently being loaded.  If,
while module A is being loaded, there's an attempt to auto-load module
B, then an entry (A < B) would added to the partial order.  The partial
order would not allow cycles to be introduced, reporting an error in
that case.  In case a cycle would be introduced when adding (A < B),
then the thread would simply be given access to the partially-loaded
module B, by adding B to its local list of modules-being-loaded.

Comments and suggestions welcome,

        Mark





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
       [not found]     ` <876002dm18.fsf@netris.org>
@ 2018-08-23 13:51       ` Ludovic Courtès
  0 siblings, 0 replies; 12+ messages in thread
From: Ludovic Courtès @ 2018-08-23 13:51 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: 31878

Hi Mark,

Mark H Weaver <mhw@netris.org> skribis:

> reopen 31878
> thanks
>
> Hi Ludovic,
>
> ludo@gnu.org (Ludovic Courtès) writes:
>
>> ludo@gnu.org (Ludovic Courtès) skribis:
>>
>>> ludo@gnu.org (Ludovic Courtès) skribis:
>>>
>>>> I believe this comes from the fact that ‘autoloads-done’ and related
>>>> alists in (ice-9 boot-9) are manipulated in a non-thread-safe fashion.
>>>
>>> Here’s a proposed fix for ‘stable-2.2’ as discussed on #guile, Andy:
>>
>> After further discussion on IRC, I pushed a variant of this patch as
>> commit 761cf0fb8c364e885e4c6fced34563f8157c3b84.
>
> There are problems with this fix, e.g. <https://bugs.gnu.org/32367>.
>
> More generally, nearly arbitrary code can be run in the top-level
> expressions of a module.  It could launch other threads which try to
> load modules, or even send messages to other existing threads asking
> them to do work.  In some cases, the body of the module might never
> terminate.  The entire main program might be run from there.  I suspect
> that's not unusual.

Indeed, good catch.  :-/

> I can see another problem as well: while the module is in the process of
> loading, the partially-loaded module is globally visible and accessible
> to other threads.  If I'm not mistaken, with this patch, there's nothing
> preventing other threads from attempting to use the partially-loaded
> module.

The module is not reachable until ‘set-module-name!’ has been called on
it, but ‘process-define-module’ does that right away IIRC, i.e., before
the whole body has been evaluated.  So I guess you’re right: other
threads could stumble upon partially-loaded modules.

If the ‘define-module’ scoped encompassed the whole body like the R6
‘library’ form, it would be easy to determine when the whole module
top-level has been loaded.  Right now, I suppose we have to determine
the end-of-module-top-level “from the outside”, i.e., from
‘resolve-module’ or similar, no?

> I thought about how to fix this thread-safety problem a long time ago,
> and came up with a rough outline of a solution.  The idea is that the
> module should not be added to the global module table until the module
> has finished loading.  While the module is being loaded, it would be
> made visible only to the loading thread, and to any other threads
> spawned during the loading process, by adding the module to a local list
> of modules-being-loaded referenced by a fluid variable.  If any other
> threads attempt to access the module, it would not be found in the
> global module table, and thus trigger an auto-load, which would wait for
> the lock to be released before proceeding.
>
> What do you think?

It sounds like a good idea.

Thanks,
Ludo’.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-08-23  2:18       ` Mark H Weaver
@ 2018-08-23 13:54         ` Ludovic Courtès
  2018-08-23 19:40           ` Mark H Weaver
  0 siblings, 1 reply; 12+ messages in thread
From: Ludovic Courtès @ 2018-08-23 13:54 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: 31878

Mark H Weaver <mhw@netris.org> skribis:

> I forgot to mention an important aspect of the proposed auto-load
> locking here.  It would not be a global lock, but rather a lock specific
> to the module being loaded.  So, I guess we would need a global table of
> locks for modules-being-loaded.

Right (we can’t add a mutex to the module record without breaking the
ABI.)

> Since Guile (unfortunately) allows cyclic module dependencies, we would
> need a mechanism to avoid deadlocks in case modules A and B both import
> each other, and two threads concurrently attempt to load those modules.
>
> The first idea that comes to mind is to also have a global structure
> storing a partial order on the modules currently being loaded.  If,
> while module A is being loaded, there's an attempt to auto-load module
> B, then an entry (A < B) would added to the partial order.  The partial
> order would not allow cycles to be introduced, reporting an error in
> that case.  In case a cycle would be introduced when adding (A < B),
> then the thread would simply be given access to the partially-loaded
> module B, by adding B to its local list of modules-being-loaded.

Would it enough to (1) use recursive mutexes, and (2) have
‘resolve-module’ lookup modules first in the global name space, and
second in the local list of modules being loaded?

Thanks,
Ludo’.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-08-23 13:54         ` Ludovic Courtès
@ 2018-08-23 19:40           ` Mark H Weaver
  2018-08-24  8:45             ` Ludovic Courtès
  2018-10-21 18:16             ` Mark H Weaver
  0 siblings, 2 replies; 12+ messages in thread
From: Mark H Weaver @ 2018-08-23 19:40 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 31878

Hi Ludovic,

ludo@gnu.org (Ludovic Courtès) writes:

> Mark H Weaver <mhw@netris.org> skribis:
>
>> Since Guile (unfortunately) allows cyclic module dependencies, we would
>> need a mechanism to avoid deadlocks in case modules A and B both import
>> each other, and two threads concurrently attempt to load those modules.
>>
>> The first idea that comes to mind is to also have a global structure
>> storing a partial order on the modules currently being loaded.  If,
>> while module A is being loaded, there's an attempt to auto-load module
>> B, then an entry (A < B) would added to the partial order.  The partial
>> order would not allow cycles to be introduced, reporting an error in
>> that case.  In case a cycle would be introduced when adding (A < B),
>> then the thread would simply be given access to the partially-loaded
>> module B, by adding B to its local list of modules-being-loaded.
>
> Would it enough to (1) use recursive mutexes, and (2) have
> ‘resolve-module’ lookup modules first in the global name space, and
> second in the local list of modules being loaded?

Item (2) above is something that I had already envisioned in my
proposal, although I neglected to mention it.

However, I don't see how recursive mutexes would help here, or how they
could obviate the need for the other mechanisms I described above.

Suppose module A and module B are mutually dependent on each other.  If
thread 1 is loading module A concurrently with thread 2 loading module
B, then thread 1 will be the only thread with access to module A (via
thread 1's local list) and will hold the lock on it, and similarly for
thread 2 and module B.

Now, when thread 1 tries to load module B (while it's in the process of
loading module A), it should normally be blocked until module B is
finished loading.  If those modules were _not_ mutually dependent on
each other, we should insist on thread 1 waiting for module B to finish
loading before gaining access to it.  Only if there is a cyclic
dependency should it be granted access to the partially-loaded module.

If we simply use recursive mutexes, I think deadlock would occur in this
case.  Thread 1 would try to grab the lock on module B, which is already
held by thread 2, and vice versa.  Since it's not self-held, I fail to
see the relevance of the recursive mutex.

What do you think?

      Mark





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-08-23 19:40           ` Mark H Weaver
@ 2018-08-24  8:45             ` Ludovic Courtès
  2018-10-21 18:16             ` Mark H Weaver
  1 sibling, 0 replies; 12+ messages in thread
From: Ludovic Courtès @ 2018-08-24  8:45 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: 31878

Hi Mark,

Mark H Weaver <mhw@netris.org> skribis:

> ludo@gnu.org (Ludovic Courtès) writes:
>
>> Mark H Weaver <mhw@netris.org> skribis:
>>
>>> Since Guile (unfortunately) allows cyclic module dependencies, we would
>>> need a mechanism to avoid deadlocks in case modules A and B both import
>>> each other, and two threads concurrently attempt to load those modules.
>>>
>>> The first idea that comes to mind is to also have a global structure
>>> storing a partial order on the modules currently being loaded.  If,
>>> while module A is being loaded, there's an attempt to auto-load module
>>> B, then an entry (A < B) would added to the partial order.  The partial
>>> order would not allow cycles to be introduced, reporting an error in
>>> that case.  In case a cycle would be introduced when adding (A < B),
>>> then the thread would simply be given access to the partially-loaded
>>> module B, by adding B to its local list of modules-being-loaded.
>>
>> Would it enough to (1) use recursive mutexes, and (2) have
>> ‘resolve-module’ lookup modules first in the global name space, and
>> second in the local list of modules being loaded?
>
> Item (2) above is something that I had already envisioned in my
> proposal, although I neglected to mention it.
>
> However, I don't see how recursive mutexes would help here, or how they
> could obviate the need for the other mechanisms I described above.
>
> Suppose module A and module B are mutually dependent on each other.  If
> thread 1 is loading module A concurrently with thread 2 loading module
> B, then thread 1 will be the only thread with access to module A (via
> thread 1's local list) and will hold the lock on it, and similarly for
> thread 2 and module B.
>
> Now, when thread 1 tries to load module B (while it's in the process of
> loading module A), it should normally be blocked until module B is
> finished loading.  If those modules were _not_ mutually dependent on
> each other, we should insist on thread 1 waiting for module B to finish
> loading before gaining access to it.  Only if there is a cyclic
> dependency should it be granted access to the partially-loaded module.
>
> If we simply use recursive mutexes, I think deadlock would occur in this
> case.  Thread 1 would try to grab the lock on module B, which is already
> held by thread 2, and vice versa.  Since it's not self-held, I fail to
> see the relevance of the recursive mutex.

Oh, got it; you’re right.  So yes, the solution you outlined above is
probably what’s needed.

Thanks for explaining!

Ludo’.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-08-23 19:40           ` Mark H Weaver
  2018-08-24  8:45             ` Ludovic Courtès
@ 2018-10-21 18:16             ` Mark H Weaver
  2018-10-22 10:10               ` Ludovic Courtès
  1 sibling, 1 reply; 12+ messages in thread
From: Mark H Weaver @ 2018-10-21 18:16 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 31878

[-- Attachment #1: Type: text/plain, Size: 205 bytes --]

I've written a preliminary patch to implement the improved thread-safe
module autoloading that I outlined in earlier messages in this bug
report.

Comments, suggestions, and testing welcome.

      Mark



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] DRAFT: Fix thread-safe module loading --]
[-- Type: text/x-patch, Size: 30320 bytes --]

From 897a6f76280612e83f48d63430bf962520c0e7b3 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <mhw@netris.org>
Date: Sun, 21 Oct 2018 09:56:16 -0400
Subject: [PATCH] DRAFT: Fix thread-safe module loading.

* module/ice-9/boot-9.scm (%modules-being-loaded)
(%local-modules-being-loaded, %modules-waiting-for): New variables.
(%force-lazy-module-cell!, %module-waiting-for?)
(%module-waiting-for!): New procedures.
(resolve-module): If the requested module is not in the regular global
module table, look in '%local-modules-being-loaded' and
'%modules-being-loaded', and handle these cases appropriately.  Support
looping without recursively locking the autoload lock.  When
autoloading, unlock the mutex before calling 'try-load-module'.
(try-module-autoload): Add entries to '%modules-being-loaded' and
'%local-modules-being-loaded' before loading the module.  Also, load the
module with the autoload mutex unlocked.  When the load attempt
finishes (or fails), add the module to the regular global module table
if it was ever created, signal the threads waiting for this module, and
remove it from the '*-begin-loaded' and '%modules-waiting-for' tables.
(call-with-module-autoload-lock): Accept a unary procedure instead of a
thunk.
(module-name): Adapt to the new 'call-with-module-autoload-lock'.
(nested-define-module!): If we're asked to define a submodule of a
module that's currently being loaded, install the parent module being
loaded into the global module table.
* module/ice-9/threads.scm (call-with-module-autoload-lock):
Pass the mutex as an argument to the procedure.
* test-suite/tests/threads.test: Add tests.
* test-suite/tests/delayed-test.scm,
test-suite/tests/mutual-delayed-a.scm,
test-suite/tests/mutual-delayed-b.scm,
test-suite/tests/mutual-delayed-c.scm: New files.
* test-suite/Makefile.am (EXTRA_DIST): Add them.
---
 module/ice-9/boot-9.scm               | 292 ++++++++++++++++++++++----
 module/ice-9/threads.scm              |   4 +-
 test-suite/Makefile.am                |   7 +-
 test-suite/tests/delayed-test.scm     |  28 +++
 test-suite/tests/mutual-delayed-a.scm |  29 +++
 test-suite/tests/mutual-delayed-b.scm |  29 +++
 test-suite/tests/mutual-delayed-c.scm |  29 +++
 test-suite/tests/threads.test         |  66 +++++-
 8 files changed, 435 insertions(+), 49 deletions(-)
 create mode 100644 test-suite/tests/delayed-test.scm
 create mode 100644 test-suite/tests/mutual-delayed-a.scm
 create mode 100644 test-suite/tests/mutual-delayed-b.scm
 create mode 100644 test-suite/tests/mutual-delayed-c.scm

diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index d8801dada..404a19d49 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -2502,13 +2502,32 @@ interfaces are added to the inports list."
                  (tail (cdr names)))
         (if (null? tail)
             (module-define-submodule! cur head module)
-            (let ((cur (or (module-ref-submodule cur head)
-                           (let ((m (make-module 31)))
-                             (set-module-kind! m 'directory)
-                             (set-module-name! m (append (module-name cur)
-                                                         (list head)))
-                             (module-define-submodule! cur head m)
-                             m))))
+            (let ((cur
+                   (or (module-ref-submodule cur head)
+                       (let ((dir-name (append (module-name cur)
+                                               (list head))))
+                         (cond ((assoc dir-name %modules-being-loaded)
+                                => (lambda (entry)
+                                     ;; The module we're being asked to define
+                                     ;; is a submodule of a module that's
+                                     ;; currently being loaded.  In this case,
+                                     ;; we must install the parent module
+                                     ;; being loaded into the global module
+                                     ;; table.  This is unfortunate, but it's
+                                     ;; not clear how to avoid this without
+                                     ;; changing the structure of the global
+                                     ;; module table.
+                                     (let ((m (%force-lazy-module-cell!
+                                               (cddr entry)
+                                               dir-name)))
+                                       (module-define-submodule! cur head m)
+                                       m)))
+                               (else
+                                (let ((m (make-module 31)))
+                                  (set-module-kind! m 'directory)
+                                  (set-module-name! m dir-name)
+                                  (module-define-submodule! cur head m)
+                                  m)))))))
               (loop cur (car tail) (cdr tail)))))))
 
 
@@ -2607,13 +2626,13 @@ interfaces are added to the inports list."
 
 \f
 
-(define (call-with-module-autoload-lock thunk)
-  ;; This binding is overridden when (ice-9 threads) is available to
-  ;; implement a critical section around the call to THUNK.  It must be
-  ;; used anytime 'autoloads-done' and related variables are accessed
-  ;; and whenever submodules are accessed (via the 'nested-'
-  ;; procedures.)
-  (thunk))
+(define (call-with-module-autoload-lock proc)
+  ;; Apply PROC to the autoload lock or #f, while holding the lock.
+  ;; This must be used anytime 'autoloads-done' and related variables
+  ;; are accessed and whenever submodules are accessed (e.g. via the
+  ;; 'nested-' procedures.)  This is initially a stub, but it will be
+  ;; overwritten when (ice-9 threads) is loaded.
+  (proc #f))
 
 ;; Now that modules are booted, give module-name its final definition.
 ;;
@@ -2627,7 +2646,7 @@ interfaces are added to the inports list."
             ;; names and relies on being able to `resolve-module' them.
             (set-module-name! mod name)
             (call-with-module-autoload-lock
-             (lambda ()
+             (lambda (mutex)
                (nested-define-module! (resolve-module '() #f) name mod)))
             (accessor mod))))))
 
@@ -2701,36 +2720,175 @@ deterministic."
     (beautify-user-module! m)
     m))
 
+;; '%modules-being-loaded' is a global table of modules currently
+;; being loaded.  Its entries are of the form:
+;;
+;;   (NAME COND-VAR . LAZY-MODULE-CELL)
+;;
+;; where COND-VAR is a condition variable that will signaled when the
+;; current module load attempt succeeds (or fails), and LAZY-MODULE-CELL
+;; is a singleton list whose element is either a module or #f.  It
+;; should only be accessed from within 'call-with-module-autoload-lock'.
+;;
+;; The modules in '%modules-being-loaded' are normally not added to the
+;; regular global module table until they have finished loading.  The
+;; idea is that other threads should not be able to see the partially
+;; loaded module.  If another thread tries to load the partially loaded
+;; module, it will normally wait on COND-VAR until the module has
+;; finished loading (or the load attempt fails).  However, there are two
+;; cases when a thread is given access to a partially loaded module: (1)
+;; when the partially loaded module is in its
+;; '%local-modules-being-loaded' list, and (2) when a non-trivial cycle
+;; would be introduced in the reflexive and transitive closure of the
+;; global %modules-waiting-for relation.
+(define %modules-being-loaded
+  '())
+
+;; The entries in (fluid-ref %local-modules-being-loaded) are of
+;; the form:
+;;
+;;   (NAME . LAZY-MODULE-CELL)
+;;
+;; where LAZY-MODULE-CELL is a singleton list whose element is
+;; either a module or #f.  It should only be accessed from within
+;; 'call-with-module-autoload-lock'.
+;;
+;; Modules listed in (fluid-ref %local-modules-being-loaded) are visible
+;; to the local thread, even if they are not present in the regular
+;; global module table.
+(define %local-modules-being-loaded
+  (make-fluid '()))
+
+(define (%force-lazy-module-cell! cell name)
+  (or (car cell) ; the module already exists; return it
+      ;; otherwise, create a fresh new module, store it in the
+      ;; lazy-module-cell, and return it.
+      (let ((m (make-module 31)))
+        (set-module-name! m name)
+        (set-car! cell m)
+        m)))
+
+;; The '%modules-waiting-for' relation is a partial order on
+;; the modules present in the '%modules-being-loaded' table.
+;; Its entries are of the form:
+;;
+;;   (NAME-1 . NAME-2)
+;;
+;; '%modules-waiting-for' is used to prevent deadlocks that would
+;; otherwise occur when mutually dependent modules are loaded
+;; concurrently.  It should only be accessed from within
+;; 'call-with-module-autoload-lock'.
+(define %modules-waiting-for
+  '())
+
+;; Return #t if (NAME-1 NAME-2) is in the reflexive and transitive
+;; closure of '%modules-waiting-for'.  This procedure should only be
+;; called from within 'call-with-module-autoload-lock'.
+(define (%module-waiting-for? name-1 name-2)
+  (or (equal? name-1 name-2)
+      (cond ((assoc name-1 %modules-waiting-for)
+             => (lambda (entry)
+                  (%module-waiting-for? (cdr entry) name-2)))
+            (else #f))))
+
+;; Add (NAME-1 NAME-2) to the '%modules-waiting-for' relation if it's
+;; not already in the reflexive and transitive closure.  Raise an error
+;; if adding it would introduce a cycle.  This procedure should only be
+;; called from within 'call-with-module-autoload-lock'.
+(define (%module-waiting-for! name-1 name-2)
+  (unless (%module-waiting-for? name-1 name-2)
+    (when (%module-waiting-for? name-2 name-1)
+      (error "%module-waiting-for!: would introduce a cycle"
+             (list name-1 name-2 %modules-waiting-for)))
+    (set! %modules-waiting-for
+          (cons (cons name-1 name-2)
+                %modules-waiting-for))))
+
 ;; NOTE: This binding is used in libguile/modules.c.
 ;;
 (define resolve-module
-  (let ((root (make-module)))
+  (let ((root (make-module))
+        (ice-9-threads
+         (lambda (sym)
+           (module-ref (resolve-module '(ice-9 threads)) sym))))
+
     (set-module-name! root '())
     ;; Define the-root-module as '(guile).
     (module-define-submodule! root 'guile the-root-module)
 
     (lambda* (name #:optional (autoload #t) (version #f) #:key (ensure #t))
       (call-with-module-autoload-lock
-       (lambda ()
-         (let ((already (nested-ref-module root name)))
-           (cond
-            ((and already
-                  (or (not autoload) (module-public-interface already)))
-             ;; A hit, a palpable hit.
-             (if (and version
-                      (not (version-matches? version (module-version already))))
+       (lambda (mutex)
+         (let loop ((autoload autoload))
+           ;; First check the global module table.
+           (let ((already (nested-ref-module root name)))
+             (cond
+              ((and already
+                    (or (not autoload) (module-public-interface already)))
+               ;; A hit, a palpable hit.
+               (when (and version
+                          (not (version-matches? version (module-version already))))
                  (error "incompatible module version already loaded" name))
-             already)
-            (autoload
-             ;; Try to autoload the module, and recurse.
-             (try-load-module name version)
-             (resolve-module name #f #:ensure ensure))
-            (else
-             ;; No module found (or if one was, it had no public interface), and
-             ;; we're not autoloading. Make an empty module if #:ensure is true.
-             (or already
-                 (and ensure
-                      (make-modules-in root name)))))))))))
+               already)
+
+              ;; The module is not in the global module table.
+              ;; Check %local-modules-being-loaded.  If there's a
+              ;; matching entry, return the associated module,
+              ;; forcing the lazy module cell if needed.
+              ((assoc name (fluid-ref %local-modules-being-loaded))
+               => (lambda (entry)
+                    (%force-lazy-module-cell! (cdr entry) name)))
+
+              ;; Check the global '%modules-being-loaded' table.  If
+              ;; there's a matching entry, add an entry to the
+              ;; '%modules-waiting-for' relation (checking to
+              ;; make sure we don't introduce a cycle), wait on the
+              ;; associated condition variable for the module to be
+              ;; loaded, and try again.
+              ((assoc name %modules-being-loaded)
+               => (lambda (entry)
+                    (let ((cond-var (cadr entry))
+                          (lazy-module-cell (cddr entry))
+                          (local-modules (fluid-ref %local-modules-being-loaded)))
+                      (if (or (not mutex)
+                              (and (pair? local-modules)
+                                   ;; check for circular dependency below
+                                   (%module-waiting-for? name (caar local-modules))))
+                          ;; If (ice-9 threads) is not yet loaded, or
+                          ;; if adding the new entry to
+                          ;; '%module-waiting-for' would add a
+                          ;; circular dependency, then punt and
+                          ;; immediately return the partially-loaded
+                          ;; module.
+                          (%force-lazy-module-cell! lazy-module-cell name)
+                          ;; Otherwise, add an entry to the
+                          ;; '%modules-waiting-for' relation, wait on
+                          ;; the associated condition variable for the
+                          ;; module to be loaded, and try again.
+                          (begin
+                            (when (pair? local-modules)
+                              (%module-waiting-for! (caar local-modules) name))
+                            ;; wait for the pending module load to finish.
+                            ((ice-9-threads 'wait-condition-variable) cond-var mutex)
+                            (loop #f))))))   ; and try again
+
+              (autoload
+               ;; Here we try to autoload the module.  Unlock the mutex
+               ;; while we call 'try-load-module'.
+               (dynamic-wind
+                 (lambda () (when mutex
+                              ((ice-9-threads 'unlock-mutex) mutex)))
+                 (lambda () (try-load-module name version))
+                 (lambda () (when mutex
+                              ((ice-9-threads 'lock-mutex) mutex))))
+               ;; Now try again with autoload set to #f.
+               (loop #f))
+              (else
+               ;; No module found (or if one was, it had no public interface), and
+               ;; we're not autoloading. Make an empty module if #:ensure is true.
+               (or already
+                   (and ensure
+                        (make-modules-in root name))))))))))))
 
 
 (define (try-load-module name version)
@@ -2973,6 +3131,8 @@ module '(ice-9 q) '(make-q q-length))}."
   "Try to load a module of the given name.  If it is not found, return
 #f.  Otherwise return #t.  May raise an exception if a file is found,
 but it fails to load."
+  (define (ice-9-threads sym)
+    (module-ref (resolve-module '(ice-9 threads)) sym))
   (let* ((reverse-name (reverse module-name))
          (name (symbol->string (car reverse-name)))
          (dir-hint-module-name (reverse (cdr reverse-name)))
@@ -2980,17 +3140,34 @@ but it fails to load."
                           (map (lambda (elt)
                                  (string-append (symbol->string elt)
                                                 file-name-separator-string))
-                               dir-hint-module-name))))
-    (resolve-module dir-hint-module-name #f)
+                               dir-hint-module-name)))
+         (parent-module (resolve-module dir-hint-module-name #f)))
 
     (call-with-module-autoload-lock
-     (lambda ()
+     (lambda (mutex)
        (and (not (autoload-done-or-in-progress? dir-hint name))
-            (let ((didit #f))
+            (let ((lazy-module-cell (list #f))
+                  (cond-var (and mutex
+                                 ((ice-9-threads 'make-condition-variable))))
+                  (didit #f))
+
+              ;; Add an entry to the '%modules-being-loaded' table,
+              ;; with an associated condition variable to be signaled
+              ;; when the module is finished loading.
+              (set! %modules-being-loaded
+                    (cons (cons* module-name cond-var lazy-module-cell)
+                          %modules-being-loaded))
+
               (dynamic-wind
-                (lambda () (autoload-in-progress! dir-hint name))
                 (lambda ()
-                  (with-fluids ((current-reader #f))
+                  (autoload-in-progress! dir-hint name)
+                  (when mutex
+                    ((ice-9-threads 'unlock-mutex) mutex)))
+                (lambda ()
+                  (with-fluids ((%local-modules-being-loaded
+                                 (cons (cons module-name lazy-module-cell)
+                                       (fluid-ref %local-modules-being-loaded)))
+                                (current-reader #f))
                     (save-module-excursion
                      (lambda ()
                        (define (call/ec proc)
@@ -3014,7 +3191,38 @@ but it fails to load."
                           (primitive-load-path (in-vicinity dir-hint name)
                                                abort)
                           (set! didit #t)))))))
-                (lambda () (set-autoloaded! dir-hint name didit)))
+                (lambda ()
+                  (when mutex
+                    ((ice-9-threads 'lock-mutex) mutex))
+                  (set-autoloaded! dir-hint name didit)))
+
+              ;; If the local module was actually created, then we
+              ;; now add it to the global module table.
+              (let ((module (car lazy-module-cell)))
+                (when module
+                  (module-define-submodule! parent-module
+                                            (car reverse-name)
+                                            module)))
+
+              ;; Signal all threads waiting on the condition variable
+              ;; for this module to be loaded.
+              (when cond-var
+                ((ice-9-threads 'broadcast-condition-variable) cond-var))
+
+              ;; Remove the module from '%modules-being-loaded'.
+              (set! %modules-being-loaded
+                    (assoc-remove! %modules-being-loaded
+                                   module-name))
+
+              ;; Remove all '%modules-waiting-for' entries that are
+              ;; directly related to the module that we just loaded
+              ;; (or attempted to load).
+              (set! %modules-waiting-for
+                    (filter! (lambda (entry)
+                               (not (or (equal? module-name (car entry))
+                                        (equal? module-name (cdr entry)))))
+                             %modules-waiting-for))
+              
               didit))))))
 
 \f
diff --git a/module/ice-9/threads.scm b/module/ice-9/threads.scm
index c42bd266f..81fa22063 100644
--- a/module/ice-9/threads.scm
+++ b/module/ice-9/threads.scm
@@ -385,8 +385,8 @@ of applying P-PROC on ARGLISTS."
 ;; thread-safe.
 (set! (@ (guile) call-with-module-autoload-lock)
   (let ((mutex (make-mutex 'recursive)))
-    (lambda (thunk)
+    (lambda (proc)
       (with-mutex mutex
-        (thunk)))))
+        (proc mutex)))))
 
 ;;; threads.scm ends here
diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am
index 0934dbb34..354c33152 100644
--- a/test-suite/Makefile.am
+++ b/test-suite/Makefile.am
@@ -1,7 +1,6 @@
 ## Process this file with automake to produce Makefile.in.
 ##
-## Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-##   2010, 2011, 2012, 2013, 2014 Software Foundation, Inc.
+## Copyright 2001-2018 Software Foundation, Inc.
 ##
 ## This file is part of GUILE.
 ##
@@ -204,6 +203,10 @@ EXTRA_DIST = \
 	$(SCM_TESTS) \
 	tests/rnrs-test-a.scm \
 	tests/srfi-64-test.scm \
+	tests/mutual-delayed-a.scm \
+	tests/mutual-delayed-b.scm \
+	tests/mutual-delayed-c.scm \
+	tests/delayed-test.scm \
 	ChangeLog-2008
 
 \f
diff --git a/test-suite/tests/delayed-test.scm b/test-suite/tests/delayed-test.scm
new file mode 100644
index 000000000..cc584d61d
--- /dev/null
+++ b/test-suite/tests/delayed-test.scm
@@ -0,0 +1,28 @@
+;;;; delayed-test.scm --- A test helper.       -*- scheme -*-
+;;;;
+;;;; Copyright 2018 Free Software Foundation, Inc.
+;;;;
+;;;; This library is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU Lesser General Public
+;;;; License as published by the Free Software Foundation; either
+;;;; version 3 of the License, or (at your option) any later version.
+;;;; 
+;;;; This library is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;;; Lesser General Public License for more details.
+;;;; 
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+(define-module (tests delayed-test)
+  #:use-module (tests threads)
+  #:export (delayed-proc))
+
+(increment-delayed-test-count!)
+(define delayed-proc #f)
+(thread-safe-format "delayed-test: starting sleep\n")
+(sleep 2)
+(define (delayed-proc) 'done)
+(thread-safe-format "delayed-test: done\n")
diff --git a/test-suite/tests/mutual-delayed-a.scm b/test-suite/tests/mutual-delayed-a.scm
new file mode 100644
index 000000000..6a8c4f116
--- /dev/null
+++ b/test-suite/tests/mutual-delayed-a.scm
@@ -0,0 +1,29 @@
+;;;; mutual-delayed-a.scm --- A test helper.       -*- scheme -*-
+;;;;
+;;;; Copyright 2018 Free Software Foundation, Inc.
+;;;;
+;;;; This library is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU Lesser General Public
+;;;; License as published by the Free Software Foundation; either
+;;;; version 3 of the License, or (at your option) any later version.
+;;;; 
+;;;; This library is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;;; Lesser General Public License for more details.
+;;;; 
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+(define-module (tests mutual-delayed-a)
+  #:use-module (tests threads)
+  #:export (delayed-a))
+
+(define delayed-a #f)
+(thread-safe-format "mutual-delayed-a: starting sleep\n")
+(sleep 2)
+(thread-safe-format "mutual-delayed-a: loading mutual-delayed-b\n")
+(resolve-module '(tests mutual-delayed-b))
+(define (delayed-a) 'a)
+(thread-safe-format "mutual-delayed-a: done\n")
diff --git a/test-suite/tests/mutual-delayed-b.scm b/test-suite/tests/mutual-delayed-b.scm
new file mode 100644
index 000000000..81aad5b52
--- /dev/null
+++ b/test-suite/tests/mutual-delayed-b.scm
@@ -0,0 +1,29 @@
+;;;; mutual-delayed-b.scm --- A test helper.       -*- scheme -*-
+;;;;
+;;;; Copyright 2018 Free Software Foundation, Inc.
+;;;;
+;;;; This library is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU Lesser General Public
+;;;; License as published by the Free Software Foundation; either
+;;;; version 3 of the License, or (at your option) any later version.
+;;;; 
+;;;; This library is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;;; Lesser General Public License for more details.
+;;;; 
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+(define-module (tests mutual-delayed-b)
+  #:use-module (tests threads)
+  #:export (delayed-b))
+
+(define delayed-b #f)
+(thread-safe-format "mutual-delayed-b: starting sleep\n")
+(sleep 2)
+(thread-safe-format "mutual-delayed-b: loading mutual-delayed-c\n")
+(resolve-module '(tests mutual-delayed-c))
+(define (delayed-b) 'b)
+(thread-safe-format "mutual-delayed-b: done\n")
diff --git a/test-suite/tests/mutual-delayed-c.scm b/test-suite/tests/mutual-delayed-c.scm
new file mode 100644
index 000000000..90e84a52f
--- /dev/null
+++ b/test-suite/tests/mutual-delayed-c.scm
@@ -0,0 +1,29 @@
+;;;; mutual-delayed-c.scm --- A test helper.       -*- scheme -*-
+;;;;
+;;;; Copyright 2018 Free Software Foundation, Inc.
+;;;;
+;;;; This library is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU Lesser General Public
+;;;; License as published by the Free Software Foundation; either
+;;;; version 3 of the License, or (at your option) any later version.
+;;;; 
+;;;; This library is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;;; Lesser General Public License for more details.
+;;;; 
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+(define-module (tests mutual-delayed-c)
+  #:use-module (tests threads)
+  #:export (delayed-c))
+
+(define delayed-c #f)
+(thread-safe-format "mutual-delayed-c: starting sleep\n")
+(sleep 2)
+(thread-safe-format "mutual-delayed-c: loading mutual-delayed-a\n")
+(resolve-module '(tests mutual-delayed-a))
+(define (delayed-c) 'c)
+(thread-safe-format "mutual-delayed-c: done\n")
diff --git a/test-suite/tests/threads.test b/test-suite/tests/threads.test
index efdf36db2..434a1f4e8 100644
--- a/test-suite/tests/threads.test
+++ b/test-suite/tests/threads.test
@@ -1,7 +1,7 @@
 ;;;; threads.test --- Tests for Guile threading.    -*- scheme -*-
 ;;;;
 ;;;; Copyright 2003, 2006, 2007, 2009, 2010, 2011, 2012, 2013,
-;;;;   2014 Free Software Foundation, Inc.
+;;;;   2014, 2018 Free Software Foundation, Inc.
 ;;;;
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
@@ -17,10 +17,12 @@
 ;;;; License along with this library; if not, write to the Free Software
 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-(define-module (test-threads)
+(define-module (tests threads)
   #:use-module (ice-9 threads)
   #:use-module (system base compile)
-  #:use-module (test-suite lib))
+  #:use-module (test-suite lib)
+  #:export (increment-delayed-test-count!
+            thread-safe-format))
 
 (define (asyncs-still-working?)
   (let ((a #f))
@@ -448,3 +450,61 @@
   (pass-if "current-processor-count"
     (and (>= (current-processor-count) 1)
          (>= (total-processor-count) (current-processor-count)))))
+
+;;
+;; thread safe module loading
+;;
+
+(define thread-safe-format
+  (let ((mutex (make-mutex)))
+    (lambda args
+      (with-mutex mutex
+        (apply format (current-error-port) args)))))
+(define delayed-test-count-mutex (make-mutex))
+(define delayed-test-count 0)
+(define (increment-delayed-test-count!)
+  (with-mutex delayed-test-count-mutex
+    (set! delayed-test-count
+          (+ delayed-test-count 1))))
+
+(with-test-prefix "thread safe module loading"
+  ;; We deliberately avoid using 'par-map' below, because the
+  ;; effectiveness of these tests depend on them running roughly in
+  ;; parallel.  When 'par-map' is used on a machine with only 1 or 2
+  ;; cores, the tests below are unable to reliably detect the problems
+  ;; that exist before guile-2.2.5.
+  (define (spawn-test-thread module-name sym)
+    (call-with-new-thread
+     (lambda ()
+       (cond ((module-variable (resolve-module module-name) sym)
+              => (lambda (v)
+                   (and (variable? v)
+                        (procedure? (variable-ref v))
+                        ((variable-ref v)))))
+             (else
+              #f)))))
+  (define (join-thread-with-timeout deadline)
+    (lambda (thread)
+      (join-thread thread deadline 'timeout)))
+  (pass-if-equal "concurrent loading of the same module by multiple threads"
+      '(1 done done done done done done)
+    (let ((results
+           (map (join-thread-with-timeout (+ (current-time) 20))
+                (map (lambda (i)
+                       (spawn-test-thread '(tests delayed-test)
+                                          'delayed-proc))
+                     (iota 6)))))
+      (cons delayed-test-count results)))
+  (pass-if-equal "mutually dependent modules loaded concurrently"
+      '(a b c a b c a b c)
+    (map (join-thread-with-timeout (+ (current-time) 20))
+         (map (lambda (i)
+                (case (modulo i 3)
+                  ((0) (spawn-test-thread '(tests mutual-delayed-a)
+                                          'delayed-a))
+                  ((1) (spawn-test-thread '(tests mutual-delayed-b)
+                                          'delayed-b))
+                  ((2) (spawn-test-thread '(tests mutual-delayed-c)
+                                          'delayed-c))
+                  (else #f)))
+              (iota 9)))))
-- 
2.19.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-10-21 18:16             ` Mark H Weaver
@ 2018-10-22 10:10               ` Ludovic Courtès
  0 siblings, 0 replies; 12+ messages in thread
From: Ludovic Courtès @ 2018-10-22 10:10 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: 31878

Hi Mark,

Mark H Weaver <mhw@netris.org> skribis:

> I've written a preliminary patch to implement the improved thread-safe
> module autoloading that I outlined in earlier messages in this bug
> report.

Great, thanks a lot!

On a cursory look, it LGTM.  I wonder if we could somehow split
‘resolve-module’ and ‘try-module-autoload’ into smaller chunks because
they’ve become quite large and complex.

For example:

> +                (lambda ()
> +                  (when mutex
> +                    ((ice-9-threads 'lock-mutex) mutex))
> +                  (set-autoloaded! dir-hint name didit)))
> +
> +              ;; If the local module was actually created, then we
> +              ;; now add it to the global module table.
> +              (let ((module (car lazy-module-cell)))
> +                (when module
> +                  (module-define-submodule! parent-module
> +                                            (car reverse-name)
> +                                            module)))
> +
> +              ;; Signal all threads waiting on the condition variable
> +              ;; for this module to be loaded.
> +              (when cond-var
> +                ((ice-9-threads 'broadcast-condition-variable) cond-var))
> +
> +              ;; Remove the module from '%modules-being-loaded'.
> +              (set! %modules-being-loaded
> +                    (assoc-remove! %modules-being-loaded
> +                                   module-name))
> +
> +              ;; Remove all '%modules-waiting-for' entries that are
> +              ;; directly related to the module that we just loaded
> +              ;; (or attempted to load).
> +              (set! %modules-waiting-for
> +                    (filter! (lambda (entry)
> +                               (not (or (equal? module-name (car entry))
> +                                        (equal? module-name (cdr entry)))))
> +                             %modules-waiting-for))

Perhaps this bit could go in a ‘record-module-autoload-completion!’
procedure or something along these lines?

It’s great that you came up with tests to reproduce the problems.  I
confirm that “./check-guile threads.test” works for me.  The tests pass
even if I remove the {boot-9,threads}.scm changes, though.

However peg.test fails and it may be related:

--8<---------------cut here---------------start------------->8---
$ ./check-guile peg.test
Testing /data/src/guile-2.1/meta/guile ... peg.test
with GUILE_LOAD_PATH=/data/src/guile-2.1/test-suite
Running peg.test
Backtrace:
In ice-9/eval.scm:
   293:34 19 (_ #<directory (guile-user) 1f5c140>)
In ice-9/boot-9.scm:
   3032:4 18 (define-module* _ #:filename _ #:pure _ #:version _ #:imports _ #:exports _ #:replacements _ # _ # _ \u2026)
  2071:24 17 (call-with-deferred-observers #<procedure 1f06eb0 at ice-9/boot-9.scm:3033:5 ()>)
  3045:24 16 (_)
   222:29 15 (map1 (((test-suite lib)) ((ice-9 peg)) ((ice-9 pretty-print)) ((srfi srfi-1))))
   222:17 14 (map1 (((ice-9 peg)) ((ice-9 pretty-print)) ((srfi srfi-1))))
  2958:17 13 (resolve-interface (ice-9 peg) #:select _ #:hide _ #:prefix _ #:renamer _ #:version _)
In ice-9/threads.scm:
    390:8 12 (_ _)
In ice-9/boot-9.scm:
  2881:28 11 (_ #<mutex 1f5ff80>)
In ice-9/threads.scm:
    390:8 10 (_ _)
In ice-9/boot-9.scm:
  3171:20  9 (_ #<mutex 1f5ff80>)
   2312:4  8 (save-module-excursion #<procedure 21baf90 at ice-9/boot-9.scm:3172:21 ()>)
  3191:26  7 (_)
In unknown file:
           6 (primitive-load-path "ice-9/peg" #<procedure 20c2c20 at ice-9/boot-9.scm:3178:37 ()>)
In ice-9/peg.scm:
     20:0  5 (_)
In ice-9/boot-9.scm:
   3032:4  4 (define-module* _ #:filename _ #:pure _ #:version _ #:imports _ #:exports _ #:replacements _ # _ # _ \u2026)
  3045:24  3 (_)
   222:17  2 (map1 (((ice-9 peg codegen)) ((ice-9 peg string-peg)) ((ice-9 peg simplify-tree)) ((ice-9 peg #)) #))
   2961:6  1 (resolve-interface _ #:select _ #:hide _ #:prefix _ #:renamer _ #:version _)
In unknown file:
           0 (scm-error misc-error #f "~A ~S" ("no code for module" (ice-9 peg codegen)) #f)

ERROR: In procedure scm-error:
no code for module (ice-9 peg codegen)
--8<---------------cut here---------------end--------------->8---

Thoughts?

Thank you!

Ludo’.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#31878: Module autoloading is not thread safe
  2018-06-18  9:43 bug#31878: Module autoloading is not thread safe Ludovic Courtès
  2018-06-18 11:11 ` Ludovic Courtès
@ 2022-04-04 11:47 ` Calvin Heim
  1 sibling, 0 replies; 12+ messages in thread
From: Calvin Heim @ 2022-04-04 11:47 UTC (permalink / raw)
  To: ludo; +Cc: 31878

Hi Ludo and Mark,

> However peg.test fails and it may be related

The patch fails when a module has one of its submodules in its uses list, and
the program starts loading the module before it starts loading the submodule.
In the test case, (ice-9 peg) uses (ice-9 peg codegen) and the test starts
loading (ice-9 peg) before starting to load (ice-9 peg codegen).

I haven't uncovered the cause of the failure though.

Sincerely,
Calvin Heim






^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-04-04 11:47 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-18  9:43 bug#31878: Module autoloading is not thread safe Ludovic Courtès
2018-06-18 11:11 ` Ludovic Courtès
2018-06-18 12:17   ` Ludovic Courtès
2018-08-22 23:22     ` Mark H Weaver
2018-08-23  2:18       ` Mark H Weaver
2018-08-23 13:54         ` Ludovic Courtès
2018-08-23 19:40           ` Mark H Weaver
2018-08-24  8:45             ` Ludovic Courtès
2018-10-21 18:16             ` Mark H Weaver
2018-10-22 10:10               ` Ludovic Courtès
     [not found]     ` <876002dm18.fsf@netris.org>
2018-08-23 13:51       ` Ludovic Courtès
2022-04-04 11:47 ` Calvin Heim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).