regexp_exec thread-unsafe

  • Open
  • quality assurance status badge
Details
3 participants
  • Paolo Bonzini
  • Paul Eggert
  • Ludovic Courtès
Owner
unassigned
Submitted by
Ludovic Courtès
Severity
normal
L
L
Ludovic Courtès wrote on 14 May 2013 23:21
(address . bug-gnulib@gnu.org)(address . bug-guile@gnu.org)
87ehd9i7fc.fsf@gnu.org
Hello,

Guile imports Gnulib ‘regexp’ module, and for some reason it gets
compiled even on glibc systems.

The problem is that Gnulib’s ‘regex_internal.h’ reads this:

#if defined _LIBC
# include <bits/libc-lock.h>
#else
# define __libc_lock_init(NAME) do { } while (0)
# define __libc_lock_lock(NAME) do { } while (0)
# define __libc_lock_unlock(NAME) do { } while (0)
#endif

and ‘regexp_exec’ happily does:

__libc_lock_lock (dfa->lock);
if (preg->no_sub)
err = re_search_internal (preg, string, length, start, length,
length, 0, NULL, eflags);
else
err = re_search_internal (preg, string, length, start, length,
length, nmatch, pmatch, eflags);
__libc_lock_unlock (dfa->lock);

Obviously that doesn’t work well, and it caused a regression in Guile.
With MALLOC_CHECK_=2 and a Guile program, it aborts like this (sorry, I
failed to come up with a reduced test case):

Toggle snippet (99 lines)
(gdb) bt full
#0 0x00007f793608d2b5 in raise () from /home/ludo/.guix-profile/lib/libc.so.6
No symbol table info available.
#1 0x00007f793608e738 in abort () from /home/ludo/.guix-profile/lib/libc.so.6
No symbol table info available.
#2 0x00007f79360d2afe in malloc_printerr () from /home/ludo/.guix-profile/lib/libc.so.6
No symbol table info available.
#3 0x00007f79360d5bf5 in realloc_check () from /home/ludo/.guix-profile/lib/libc.so.6
No symbol table info available.
#4 0x00007f7937a6efed in register_state (dfa=0x10872c0, newstate=newstate@entry=0x1c6dce0, hash=hash@entry=576)
at regex_internal.c:1590
new_alloc = 8
new_array = 0x0
spot = 0x11981c0
i = <optimized out>
#5 0x00007f7937a72373 in create_cd_newstate (hash=<optimized out>, context=1, nodes=0x12, dfa=0x1c6dce0) at regex_internal.c:1734
i = <optimized out>
nctx_nodes = <optimized out>
err = <optimized out>
newstate = 0x1c6dce0
#6 re_acquire_state_context (err=err@entry=0x7fff67bd9e40, dfa=dfa@entry=0x10872c0, nodes=nodes@entry=0x7fff67bd9e60,
context=context@entry=1) at regex_internal.c:1554
hash = 6
spot = <optimized out>
i = <optimized out>
#7 0x00007f79379bb54b in build_trtable (dfa=<optimized out>, state=state@entry=0x1c44820) at regexec.c:3474
next_node = <optimized out>
err = _REG_NOERROR
i = 1
j = 2
ch = <optimized out>
need_word_trtable = true
elem = <optimized out>
mask = <optimized out>
dests_node_malloced = true
dest_states_malloced = true
trtable = <optimized out>
dest_states = 0x1c688f0
dest_states_word = 0x1c68918
dest_states_nl = 0x1c68940
follows = {alloc = 74, nelem = 18, elems = 0x1c5d4e0}
dests_node = 0x1c642b0
dests_ch = 0x1c65ab0
acceptable = {288063250384289792, 576460743847706622, 0, 0}
dests_alloc = 0x1c642b0
#8 0x00007f7937a77714 in transit_state (state=0x1c44820, mctx=0x7fff67bda000, err=0x7fff67bd9fb0) at regexec.c:2339
trtable = <optimized out>
ch = 116 't'
#9 check_matching (p_match_first=0x7fff67bd9fb8, fl_longest_match=true, mctx=0x7fff67bda000) at regexec.c:1187
old_state = 0x1c44820
next_char_idx = <optimized out>
dfa = <optimized out>
err = _REG_NOERROR
match = 0
match_last = <optimized out>
next_start_idx = 0
cur_str_idx = <optimized out>
cur_state = 0x1c44820
at_init_state = <optimized out>
#10 re_search_internal (preg=0x1256700, string=0x1c612d0 "http://hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.4",
length=67, start=0, last_start=0, stop=<optimized out>, nmatch=9, pmatch=0x1c63d50, eflags=0) at regexec.c:856
err = _REG_NOERROR
dfa = 0x10872c0
left_lim = 0
right_lim = 0
incr = 1
fl_longest_match = <optimized out>
match_kind = 8
match_first = 0
match_last = <optimized out>
extra_nmatch = 0
sb = false
mctx = {input = {raw_mbs = 0x1c612d0 "http://hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.4",
mbs = 0x1c612d0 "http://hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.4", wcs = 0x1c63f50,
offsets = 0x0, cur_state = {__count = 0, __value = {__wch = 0, __wchb = "\000\000\000"}}, raw_mbs_idx = 0,
valid_len = 67, valid_raw_len = 67, bufs_len = 68, cur_idx = 2, raw_len = 67, len = 67, raw_stop = 67, stop = 67,
tip_context = 6, trans = 0x0, word_char = 0x1087378, icase = 0 '\000', is_utf8 = 1 '\001', map_notascii = 0 '\000',
mbs_allocated = 0 '\000', offsets_needed = 0 '\000', newline_anchor = 0 '\000', word_ops_used = 0 '\000',
mb_cur_max = 6}, dfa = 0x10872c0, eflags = 0, match_last = 18446744073709551615, last_node = 0,
state_log = 0x1c64070, state_log_top = 1, nbkref_ents = 0, abkref_ents = 0, bkref_ents = 0x0, max_mb_elem_len = 0,
nsub_tops = 0, asub_tops = 0, sub_tops = 0x0}
fastmap = 0x0
t = 0x0
#11 0x00007f7937a7b5c0 in rpl_regexec (preg=0x1256700, string=0x3399 <Address 0x3399 out of bounds>,
string@entry=0x1c612d0 "http://hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.4", nmatch=6, nmatch@entry=9,
pmatch=0xffffffffffffffff, pmatch@entry=0x1c63d50, eflags=0) at regexec.c:254
err = _REG_NOERROR
start = 13209
length = 0
#12 0x00007f7937a68873 in scm_regexp_exec (rx=0x1836090, str=0x1806b00, start=<optimized out>, flags=0x2) at regex-posix.c:288
status = <optimized out>
nmatches = 9
offset = 0
matches = 0x1c63d50
c_str = 0x1c612d0 "http://hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.4"
mvec = 0x4
substr = <optimized out>

How should that be fixed? Shouldn’t __libc_lock_unlock & co. be rebased
on top of pthread_mutex_t?

Thanks,
Ludo’.
L
L
Ludovic Courtès wrote on 15 May 2013 09:34
(address . 14404@debbugs.gnu.org)
87fvxoofx0.fsf@gnu.org
And here’s a reduced test case that “works” quite well on Guile 2.0.9:

Toggle snippet (27 lines)
(use-modules (ice-9 threads)
(ice-9 regex)
(web uri)
(srfi srfi-1)
(srfi srfi-26))

(let ((do-regexps (lambda ()
(define seed1 (random 100000))
(define seed2 (random 100000))
(let loop ()
(let ((p (make-regexp "^http://([^/]+)/(.*)$"))
(s (string-append
"http://" (number->string seed1)
"hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.4"
(number->string seed2))))
(or (uri? (string->uri s))
(exit 42))
(regexp-exec p s)
(loop))))))
(unfold (cute >= <> (current-processor-count))
(lambda (i)
(call-with-new-thread do-regexps))
1+
0)
(do-regexps))

Ludo’.
P
P
Paul Eggert wrote on 19 May 2013 23:30
(name . Ludovic Courtès)(address . ludo@gnu.org)
5199448F.9050608@cs.ucla.edu
On 05/14/2013 02:21 PM, Ludovic Courtès wrote:

Toggle quote (3 lines)
> How should that be fixed? Shouldn’t __libc_lock_unlock & co. be rebased
> on top of pthread_mutex_t?

Yes, thanks, that sounds right. I pushed the following patch into gnulib;
could you please see whether it fixes the problem for you? It'd be
helpful to try it on non-glibc systems too, if possible.

---
ChangeLog | 19 +++++++++++++++++++
lib/regcomp.c | 11 ++++++++---
lib/regex_internal.h | 23 +++++++++++++++++------
lib/regexec.c | 4 ----
modules/regex | 1 +
5 files changed, 45 insertions(+), 13 deletions(-)

Toggle diff (161 lines)
diff --git a/ChangeLog b/ChangeLog
index 08042c5..35b6dd2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
2013-05-19 Paul Eggert <eggert@cs.ucla.edu>
+ regex: fix dfa race in multithreaded uses
+ Problem reported by Ludovic Courtès in
+ <http://lists.gnu.org/archive/html/bug-gnulib/2013-05/msg00058.html>.
+ * lib/regex_internal.h (lock_define, lock_init, lock_fini):
+ New macros. All uses of __libc_lock_define, __libc_lock_init
+ changed to use the first two of these.
+ (__libc_lock_lock, __libc_lock_unlock): New macros, for
+ non-glibc platforms.
+ (struct re_dfa_t): Define the lock unconditionally.
+ * lib/regexec.c (regexec, re_search_stub): Remove some now-incorrect
+ '#ifdef _LIBC"s.
+ * modules/regex (Depends-on): Add pthread, if we use the
+ included regex.
+
+ * lib/regcomp.c: Do actions that are not needed for glibc,
+ but may be needed elsewhere.
+ (regfree, re_compile_internal): Destroy the lock.
+ (re_compile_internal): Check for lock-initialization failure.
+
malloca: port to compilers that reject size-zero arrays
This fixes a bug introduced in my previous patch.
* lib/malloca.c (struct preliminary_header): Use an int
diff --git a/lib/regcomp.c b/lib/regcomp.c
index 4a8485e..5344381 100644
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -663,7 +663,10 @@ regfree (preg)
{
re_dfa_t *dfa = preg->buffer;
if (BE (dfa != NULL, 1))
- free_dfa_content (dfa);
+ {
+ lock_fini (dfa->lock);
+ free_dfa_content (dfa);
+ }
preg->buffer = NULL;
preg->allocated = 0;
@@ -784,6 +787,8 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
preg->used = sizeof (re_dfa_t);
err = init_dfa (dfa, length);
+ if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0))
+ err = REG_ESPACE;
if (BE (err != REG_NOERROR, 0))
{
free_dfa_content (dfa);
@@ -797,8 +802,6 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
strncpy (dfa->re_str, pattern, length + 1);
#endif
- __libc_lock_init (dfa->lock);
-
err = re_string_construct (&regexp, pattern, length, preg->translate,
(syntax & RE_ICASE) != 0, dfa);
if (BE (err != REG_NOERROR, 0))
@@ -806,6 +809,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
re_compile_internal_free_return:
free_workarea_compile (preg);
re_string_destruct (&regexp);
+ lock_fini (dfa->lock);
free_dfa_content (dfa);
preg->buffer = NULL;
preg->allocated = 0;
@@ -838,6 +842,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
if (BE (err != REG_NOERROR, 0))
{
+ lock_fini (dfa->lock);
free_dfa_content (dfa);
preg->buffer = NULL;
preg->allocated = 0;
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 439444c..63a9979 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -32,12 +32,25 @@
#include <wctype.h>
#include <stdbool.h>
#include <stdint.h>
+
#if defined _LIBC
# include <bits/libc-lock.h>
+#endif
+/* Use __libc_lock_define (, NAME) if the library defines the macro,
+ and if the compiler is known to support empty macro arguments. */
+#if (defined __libc_lock_define \
+ && ((defined __GNUC__ && !defined __STRICT_ANSI__) \
+ || (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__)))
+# define lock_define(name) __libc_lock_define (, name)
+# define lock_init(lock) (__libc_lock_init (lock), 0)
+# define lock_fini(lock) 0
#else
-# define __libc_lock_init(NAME) do { } while (0)
-# define __libc_lock_lock(NAME) do { } while (0)
-# define __libc_lock_unlock(NAME) do { } while (0)
+# include <pthread.h>
+# define lock_define(name) pthread_mutex_t name;
+# define lock_init(lock) pthread_mutex_init (&(lock), 0)
+# define lock_fini(lock) pthread_mutex_destroy (&(lock))
+# define __libc_lock_lock(lock) pthread_mutex_lock (&(lock))
+# define __libc_lock_unlock(lock) pthread_mutex_unlock (&(lock))
#endif
/* In case that the system doesn't have isblank(). */
@@ -698,9 +711,7 @@ struct re_dfa_t
#ifdef DEBUG
char* re_str;
#endif
-#ifdef _LIBC
- __libc_lock_define (, lock)
-#endif
+ lock_define (lock)
};
#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
diff --git a/lib/regexec.c b/lib/regexec.c
index 09c3eec..114287e 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -228,9 +228,7 @@ regexec (preg, string, nmatch, pmatch, eflags)
{
reg_errcode_t err;
Idx start, length;
-#ifdef _LIBC
re_dfa_t *dfa = preg->buffer;
-#endif
if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
return REG_BADPAT;
@@ -421,9 +419,7 @@ re_search_stub (struct re_pattern_buffer *bufp,
Idx nregs;
regoff_t rval;
int eflags = 0;
-#ifdef _LIBC
re_dfa_t *dfa = bufp->buffer;
-#endif
Idx last_start = start + range;
/* Check for out-of-range. */
diff --git a/modules/regex b/modules/regex
index 8f5eda0..2dbb777 100644
--- a/modules/regex
+++ b/modules/regex
@@ -24,6 +24,7 @@ memmove [test $ac_use_included_regex = yes]
mbrtowc [test $ac_use_included_regex = yes]
mbsinit [test $ac_use_included_regex = yes]
nl_langinfo [test $ac_use_included_regex = yes]
+pthread [test $ac_use_included_regex = yes]
stdbool [test $ac_use_included_regex = yes]
stdint [test $ac_use_included_regex = yes]
wchar [test $ac_use_included_regex = yes]
--
1.7.11.7
L
L
Ludovic Courtès wrote on 20 May 2013 16:20
(name . Paul Eggert)(address . eggert@cs.ucla.edu)
87d2slu413.fsf@gnu.org
Paul Eggert <eggert@cs.ucla.edu> skribis:

Toggle quote (9 lines)
> On 05/14/2013 02:21 PM, Ludovic Courtès wrote:
>
>> How should that be fixed? Shouldn’t __libc_lock_unlock & co. be rebased
>> on top of pthread_mutex_t?
>
> Yes, thanks, that sounds right. I pushed the following patch into gnulib;
> could you please see whether it fixes the problem for you? It'd be
> helpful to try it on non-glibc systems too, if possible.

Thank you for the quick reply. I haven’t tested yet, but I have a question:

Toggle quote (11 lines)
> --- a/modules/regex
> +++ b/modules/regex
> @@ -24,6 +24,7 @@ memmove [test $ac_use_included_regex = yes]
> mbrtowc [test $ac_use_included_regex = yes]
> mbsinit [test $ac_use_included_regex = yes]
> nl_langinfo [test $ac_use_included_regex = yes]
> +pthread [test $ac_use_included_regex = yes]
> stdbool [test $ac_use_included_regex = yes]
> stdint [test $ac_use_included_regex = yes]
> wchar [test $ac_use_included_regex = yes]

Seems like this is going to add -lpthread to LDFLAGS, right?

That would raise two issues: first, it should add -pthread to both
CFLAGS and LDFLAGS, not just -lpthread.

Second, Guile can be compiled with and without thread support. In the
latter case, we wouldn’t want Gnulib to stealthily pull in pthreads.
How can this be addressed?

Thanks!

Ludo’.
P
P
Paolo Bonzini wrote on 27 May 2013 00:11
(name . Ludovic Courtès)(address . ludo@gnu.org)
51A288AD.4070405@gnu.org
Il 20/05/2013 16:20, Ludovic Courtès ha scritto:
Toggle quote (33 lines)
> Paul Eggert <eggert@cs.ucla.edu> skribis:
>
>> On 05/14/2013 02:21 PM, Ludovic Courtès wrote:
>>
>>> How should that be fixed? Shouldn’t __libc_lock_unlock & co. be rebased
>>> on top of pthread_mutex_t?
>>
>> Yes, thanks, that sounds right. I pushed the following patch into gnulib;
>> could you please see whether it fixes the problem for you? It'd be
>> helpful to try it on non-glibc systems too, if possible.
>
> Thank you for the quick reply. I haven’t tested yet, but I have a question:
>
>> --- a/modules/regex
>> +++ b/modules/regex
>> @@ -24,6 +24,7 @@ memmove [test $ac_use_included_regex = yes]
>> mbrtowc [test $ac_use_included_regex = yes]
>> mbsinit [test $ac_use_included_regex = yes]
>> nl_langinfo [test $ac_use_included_regex = yes]
>> +pthread [test $ac_use_included_regex = yes]
>> stdbool [test $ac_use_included_regex = yes]
>> stdint [test $ac_use_included_regex = yes]
>> wchar [test $ac_use_included_regex = yes]
>
> Seems like this is going to add -lpthread to LDFLAGS, right?
>
> That would raise two issues: first, it should add -pthread to both
> CFLAGS and LDFLAGS, not just -lpthread.
>
> Second, Guile can be compiled with and without thread support. In the
> latter case, we wouldn’t want Gnulib to stealthily pull in pthreads.
> How can this be addressed?

Use the lock module instead.

Paolo
P
P
Paul Eggert wrote on 30 May 2013 02:59
(name . Paolo Bonzini)(address . bonzini@gnu.org)
51A6A489.2060101@cs.ucla.edu
On 05/26/2013 03:11 PM, Paolo Bonzini wrote:
Toggle quote (2 lines)
> Use the lock module instead.

Adding the lock module should work. But this will require
some reengineering of Guile, so that Guile uses the lock module
rather than its own thread packaging. Another possibility, which
might be a bit simpler, would be for Guile to pretend to
have the lock module. It could do that by creating a file
glthread/lock.h that looks something like this:

#include "../libguile/threads.h"
#define gl_lock_define(class, name) class scm_i_pthread_mutex_t name;
#define glthread_lock_init scm_i_pthread_mutex_init
#define glthread_lock_destroy scm_i_pthread_mutex_destroy
#define glthread_lock_lock scm_i_pthread_mutex_lock
#define glthread_lock_unlock scm_i_pthread_mutex_lock_unlock

and by putting AC_DEFINE([GNULIB_LOCK]) into configure.ac.
P
P
Paolo Bonzini wrote on 30 May 2013 09:28
(name . Paul Eggert)(address . eggert@cs.ucla.edu)
51A6FFB0.4000004@gnu.org
Il 30/05/2013 02:59, Paul Eggert ha scritto:
Toggle quote (20 lines)
> On 05/26/2013 03:11 PM, Paolo Bonzini wrote:
>> Use the lock module instead.
>
> Adding the lock module should work. But this will require
> some reengineering of Guile, so that Guile uses the lock module
> rather than its own thread packaging. Another possibility, which
> might be a bit simpler, would be for Guile to pretend to
> have the lock module. It could do that by creating a file
> glthread/lock.h that looks something like this:
>
> #include "../libguile/threads.h"
> #define gl_lock_define(class, name) class scm_i_pthread_mutex_t name;
> #define glthread_lock_init scm_i_pthread_mutex_init
> #define glthread_lock_destroy scm_i_pthread_mutex_destroy
> #define glthread_lock_lock scm_i_pthread_mutex_lock
> #define glthread_lock_unlock scm_i_pthread_mutex_lock_unlock
>
> and by putting AC_DEFINE([GNULIB_LOCK]) into configure.ac.
>

Whatever, all I care about is gnulib code not reinventing the wheel and
observing --disable-threads/gl_THREADLIB_DEFAULT_NO.

Paolo
L
L
Ludovic Courtès wrote on 12 Mar 2014 00:15
(name . Paul Eggert)(address . eggert@cs.ucla.edu)(address . 14404@debbugs.gnu.org)
87iorknx8g.fsf@gnu.org
Paul Eggert <eggert@cs.ucla.edu> skribis:

Toggle quote (19 lines)
> On 05/26/2013 03:11 PM, Paolo Bonzini wrote:
>> Use the lock module instead.
>
> Adding the lock module should work. But this will require
> some reengineering of Guile, so that Guile uses the lock module
> rather than its own thread packaging. Another possibility, which
> might be a bit simpler, would be for Guile to pretend to
> have the lock module. It could do that by creating a file
> glthread/lock.h that looks something like this:
>
> #include "../libguile/threads.h"
> #define gl_lock_define(class, name) class scm_i_pthread_mutex_t name;
> #define glthread_lock_init scm_i_pthread_mutex_init
> #define glthread_lock_destroy scm_i_pthread_mutex_destroy
> #define glthread_lock_lock scm_i_pthread_mutex_lock
> #define glthread_lock_unlock scm_i_pthread_mutex_lock_unlock
>
> and by putting AC_DEFINE([GNULIB_LOCK]) into configure.ac.

(Stripping Cc list.)

It’s been almost a year, but I’ve finally implemented this suggestion:


Now regex_internal.c does use pthread locks:

Toggle snippet (7 lines)
$ nm lib/.libs/regex.o |grep pthread
U pthread_mutex_destroy
U pthread_mutex_init
U pthread_mutex_lock
U pthread_mutex_unlock

However, the example given at
similar bug, but possibly in Guile land this time:

Toggle snippet (216 lines)
$ while true ; do timeout 2s ./meta/guile regexec-thread.scm ; done
timeout: the monitored command dumped core
Segmentation fault

$ gdb libguile/.libs/guile core

[...]

Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f275c5cee7b in GC_build_fl4 () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
(gdb) thread apply all bt

Thread 5 (Thread 0x7f2759a49700 (LWP 30825)):
#0 0x00007f275c3a574c in __lll_lock_wait () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#1 0x00007f275c3a1417 in _L_lock_913 () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#2 0x00007f275c3a1240 in pthread_mutex_lock () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#3 0x00007f275c5c7e95 in GC_call_with_alloc_lock () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#4 0x00007f275c89ed69 in scm_hash_fn_get_handle_by_hash (table=<optimized out>, raw_hash=raw_hash@entry=5431120,
predicate_fn=predicate_fn@entry=0x7f275c8f5e00 <string_lookup_predicate_fn>, closure=closure@entry=0x7f2759a48860)
at hashtab.c:659
#5 0x00007f275c8f5a91 in lookup_interned_symbol (raw_hash=5431120, name=0x2c22100) at symbols.c:113
#6 scm_i_str2symbol (str=0x2c22100) at symbols.c:210
#7 0x00007f275c90fa3d in vm_regular_engine (vm=<optimized out>, program=0x7f275cba9768 <scm_string_to_symbol.subr_raw_cell>,
argv=<optimized out>, nargs=1) at vm-i-system.c:852
#8 0x00007f275c8f7b80 in really_launch (d=0x7fff4246a800) at threads.c:1005
#9 0x00007f275c87d7aa in c_body (d=0x7f2759a48d70) at continuations.c:517
#10 0x00007f275c90fa28 in vm_regular_engine (vm=<optimized out>, program=0x26d0040, argv=<optimized out>, nargs=2)
at vm-i-system.c:855
#11 0x00007f275c886fe3 in scm_call_4 (proc=0x27d8c30, arg1=arg1@entry=0x404, arg2=<optimized out>, arg3=<optimized out>,
arg4=<optimized out>) at eval.c:507
#12 0x00007f275c8f9999 in scm_catch_with_pre_unwind_handler (key=key@entry=0x404, thunk=<optimized out>, handler=<optimized out>,
pre_unwind_handler=<optimized out>) at throw.c:73
#13 0x00007f275c8f9a9f in scm_c_catch (tag=tag@entry=0x404, body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f2759a48d70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f2759a48d70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>,
pre_unwind_handler_data=pre_unwind_handler_data@entry=0x26d5040) at throw.c:207
#14 0x00007f275c87deef in scm_i_with_continuation_barrier (body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f2759a48d70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f2759a48d70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>, pre_unwind_handler_data=0x26d5040)
at continuations.c:455
#15 0x00007f275c87df85 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:551
#16 0x00007f275c8f738c in with_guile_and_parent (base=0x7f2759a48dd0, data=0x7f2759a48e00) at threads.c:906
#17 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#18 0x00007f275c8f6d4c in scm_i_with_guile_and_parent (parent=<optimized out>, data=0x7fff4246a800,
func=0x7f275c8f7b00 <really_launch>) at threads.c:949
#19 launch_thread (d=0x7fff4246a800) at threads.c:1017
#20 0x00007f275c5d2ec3 in GC_inner_start_routine () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#21 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#22 0x00007f275c39f052 in start_thread () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#23 0x00007f275add3b7d in clone () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libc.so.6

Thread 4 (Thread 0x7f275cdcf740 (LWP 30798)):
#0 0x00007f275ad6ad0c in malloc () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libc.so.6
#1 0x00007f275c921eb8 in re_node_set_alloc (size=0, set=0x2ce6f80) at regex_internal.c:976
#2 register_state (dfa=0x2cdf8e0, newstate=newstate@entry=0x2ce6f60, hash=hash@entry=23) at regex_internal.c:1575
#3 0x00007f275c9252f3 in create_cd_newstate (hash=<optimized out>, context=1, nodes=0x2ce6f60, dfa=0x2) at regex_internal.c:1734
#4 re_acquire_state_context (err=err@entry=0x7fff4246a730, dfa=dfa@entry=0x2cdf8e0, nodes=nodes@entry=0x7fff4246a740,
context=context@entry=1) at regex_internal.c:1554
#5 0x00007f275c92d8a3 in create_initial_state (dfa=0x2cdf8e0) at regcomp.c:1084
#6 re_compile_internal (preg=preg@entry=0x29b0540, pattern=pattern@entry=0x2cddf80 "^http://([^/]+)/(.*)$",
length=<optimized out>, syntax=syntax@entry=242428) at regcomp.c:837
#7 0x00007f275c92e350 in rpl_regcomp (preg=preg@entry=0x29b0540, pattern=pattern@entry=0x2cddf80 "^http://([^/]+)/(.*)$",
cflags=cflags@entry=1) at regcomp.c:506
#8 0x00007f275c91b2cf in scm_make_regexp (pat=0x28c5120, flags=<optimized out>) at regex-posix.c:166
#9 0x00007f275c90fa28 in vm_regular_engine (vm=<optimized out>, program=0x7f275cbac590 <scm_make_regexp.subr_raw_cell>,
argv=<optimized out>, nargs=2) at vm-i-system.c:855
#10 0x00007f275c90fa3d in vm_regular_engine (vm=<optimized out>, program=0x26c64c0, argv=<optimized out>, nargs=1)
at vm-i-system.c:852
#11 0x00007f275c8874a3 in scm_primitive_eval (exp=exp@entry=0x28bbbb0) at eval.c:692
#12 0x00007f275c887503 in scm_eval (exp=0x28bbbb0, module_or_state=module_or_state@entry=0x2890c60) at eval.c:726
#13 0x00007f275c8d662d in scm_shell (argc=2, argv=0x7fff4246b1c8) at script.c:439
#14 0x00007f275c8a398d in invoke_main_func (body_data=0x7fff4246b090) at init.c:336
#15 0x00007f275c87d7aa in c_body (d=0x7fff4246afd0) at continuations.c:517
#16 0x00007f275c90fa28 in vm_regular_engine (vm=<optimized out>, program=0x26d0040, argv=<optimized out>, nargs=2)
at vm-i-system.c:855
#17 0x00007f275c886fe3 in scm_call_4 (proc=0x27d8c30, arg1=arg1@entry=0x404, arg2=<optimized out>, arg3=<optimized out>,
arg4=<optimized out>) at eval.c:507
#18 0x00007f275c8f9999 in scm_catch_with_pre_unwind_handler (key=key@entry=0x404, thunk=<optimized out>, handler=<optimized out>,
pre_unwind_handler=<optimized out>) at throw.c:73
#19 0x00007f275c8f9a9f in scm_c_catch (tag=tag@entry=0x404, body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7fff4246afd0, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7fff4246afd0,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>,
pre_unwind_handler_data=pre_unwind_handler_data@entry=0x26d5040) at throw.c:207
#20 0x00007f275c87deef in scm_i_with_continuation_barrier (body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7fff4246afd0, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7fff4246afd0,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>, pre_unwind_handler_data=0x26d5040)
at continuations.c:455
#21 0x00007f275c87df85 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:551
#22 0x00007f275c8f738c in with_guile_and_parent (base=0x7fff4246b030, data=0x7fff4246b060) at threads.c:906
#23 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#24 0x00007f275c8f7748 in scm_i_with_guile_and_parent (parent=<optimized out>, data=data@entry=0x7fff4246b060,
func=func@entry=0x7f275c8a3970 <invoke_main_func>) at threads.c:949
#25 scm_with_guile (func=func@entry=0x7f275c8a3970 <invoke_main_func>, data=data@entry=0x7fff4246b090) at threads.c:955
#26 0x00007f275c8a3b25 in scm_boot_guile (argc=argc@entry=2, argv=argv@entry=0x7fff4246b1c8,
main_func=main_func@entry=0x400ff0 <inner_main>, closure=closure@entry=0x0) at init.c:319
#27 0x0000000000400eb4 in main (argc=2, argv=0x7fff4246b1c8) at guile.c:108

Thread 3 (Thread 0x7f275aaeb700 (LWP 30823)):
#0 0x00007f275c3a574c in __lll_lock_wait () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#1 0x00007f275c3a1417 in _L_lock_913 () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#2 0x00007f275c3a1240 in pthread_mutex_lock () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#3 0x00007f275c8f5a78 in lookup_interned_symbol (raw_hash=5431120, name=0x2c34e40) at symbols.c:112
#4 scm_i_str2symbol (str=0x2c34e40) at symbols.c:210
#5 0x00007f275c90fa3d in vm_regular_engine (vm=<optimized out>, program=0x7f275cba9768 <scm_string_to_symbol.subr_raw_cell>,
argv=<optimized out>, nargs=1) at vm-i-system.c:852
#6 0x00007f275c8f7b80 in really_launch (d=0x7fff4246a800) at threads.c:1005
#7 0x00007f275c87d7aa in c_body (d=0x7f275aaead70) at continuations.c:517
#8 0x00007f275c90fa28 in vm_regular_engine (vm=<optimized out>, program=0x26d0040, argv=<optimized out>, nargs=2)
at vm-i-system.c:855
#9 0x00007f275c886fe3 in scm_call_4 (proc=0x27d8c30, arg1=arg1@entry=0x404, arg2=<optimized out>, arg3=<optimized out>,
arg4=<optimized out>) at eval.c:507
#10 0x00007f275c8f9999 in scm_catch_with_pre_unwind_handler (key=key@entry=0x404, thunk=<optimized out>, handler=<optimized out>,
pre_unwind_handler=<optimized out>) at throw.c:73
#11 0x00007f275c8f9a9f in scm_c_catch (tag=tag@entry=0x404, body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f275aaead70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f275aaead70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>,
pre_unwind_handler_data=pre_unwind_handler_data@entry=0x26d5040) at throw.c:207
#12 0x00007f275c87deef in scm_i_with_continuation_barrier (body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f275aaead70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f275aaead70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>, pre_unwind_handler_data=0x26d5040)
at continuations.c:455
#13 0x00007f275c87df85 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:551
#14 0x00007f275c8f738c in with_guile_and_parent (base=0x7f275aaeadd0, data=0x7f275aaeae00) at threads.c:906
#15 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#16 0x00007f275c8f6d4c in scm_i_with_guile_and_parent (parent=<optimized out>, data=0x7fff4246a800,
func=0x7f275c8f7b00 <really_launch>) at threads.c:949
#17 launch_thread (d=0x7fff4246a800) at threads.c:1017
#18 0x00007f275c5d2ec3 in GC_inner_start_routine () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#19 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#20 0x00007f275c39f052 in start_thread () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#21 0x00007f275add3b7d in clone () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libc.so.6

Thread 2 (Thread 0x7f275a29a700 (LWP 30824)):
#0 re_node_set_insert (set=0x7f275a299500, elem=18) at regex_internal.c:1284
#1 0x00007f275c928e53 in build_sifted_states (cur_dest=0x7f275a299500, str_idx=30, sctx=0x7f275a299640, mctx=0x7f275a299680)
at regexec.c:1733
#2 sift_states_backward (mctx=mctx@entry=0x7f275a299680, sctx=sctx@entry=0x7f275a299640) at regexec.c:1662
#3 0x00007f275c929c6f in prune_impossible_nodes (mctx=0x7f275a299680) at regexec.c:1036
#4 re_search_internal (preg=preg@entry=0x29b0e40,
string=0x7f274c0f6f80 "http://64109hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.485412",
length=length@entry=77, start=start@entry=0, last_start=0, last_start@entry=77, stop=stop@entry=77, nmatch=9,
pmatch=0x7f274c0f7ac0, eflags=0) at regexec.c:873
#5 0x00007f275c92e556 in rpl_regexec (preg=0x29b0e40,
string=string@entry=0x7f274c0f6f80 "http://64109hydra.gnu.org/nar/0did57blsaaspj49cl3q8nnydm5pr1qg-cflow-1.485412",
nmatch=nmatch@entry=9, pmatch=pmatch@entry=0x7f274c0f7ac0, eflags=0) at regexec.c:252
#6 0x00007f275c91b473 in scm_regexp_exec (rx=0x29c8a50, str=0x2c36fa0, start=<optimized out>, flags=0x2) at regex-posix.c:288
#7 0x00007f275c90f9f2 in vm_regular_engine (vm=<optimized out>, program=0x7f275cbac570 <scm_regexp_exec.subr_raw_cell>,
argv=<optimized out>, nargs=4) at vm-i-system.c:861
#8 0x00007f275c8f7b80 in really_launch (d=0x7fff4246a800) at threads.c:1005
#9 0x00007f275c87d7aa in c_body (d=0x7f275a299d70) at continuations.c:517
#10 0x00007f275c90fa28 in vm_regular_engine (vm=<optimized out>, program=0x26d0040, argv=<optimized out>, nargs=2)
at vm-i-system.c:855
#11 0x00007f275c886fe3 in scm_call_4 (proc=0x27d8c30, arg1=arg1@entry=0x404, arg2=<optimized out>, arg3=<optimized out>,
arg4=<optimized out>) at eval.c:507
#12 0x00007f275c8f9999 in scm_catch_with_pre_unwind_handler (key=key@entry=0x404, thunk=<optimized out>, handler=<optimized out>,
pre_unwind_handler=<optimized out>) at throw.c:73
#13 0x00007f275c8f9a9f in scm_c_catch (tag=tag@entry=0x404, body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f275a299d70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f275a299d70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>,
pre_unwind_handler_data=pre_unwind_handler_data@entry=0x26d5040) at throw.c:207
#14 0x00007f275c87deef in scm_i_with_continuation_barrier (body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f275a299d70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f275a299d70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>, pre_unwind_handler_data=0x26d5040)
at continuations.c:455
#15 0x00007f275c87df85 in scm_c_with_continuation_barrier (func=<optimized out>, data=<optimized out>) at continuations.c:551
#16 0x00007f275c8f738c in with_guile_and_parent (base=0x7f275a299dd0, data=0x7f275a299e00) at threads.c:906
#17 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#18 0x00007f275c8f6d4c in scm_i_with_guile_and_parent (parent=<optimized out>, data=0x7fff4246a800,
func=0x7f275c8f7b00 <really_launch>) at threads.c:949
#19 launch_thread (d=0x7fff4246a800) at threads.c:1017
#20 0x00007f275c5d2ec3 in GC_inner_start_routine () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#21 0x00007f275c5ce172 in GC_call_with_stack_base () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#22 0x00007f275c39f052 in start_thread () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libpthread.so.0
#23 0x00007f275add3b7d in clone () from /nix/store/jwd1hc3i3pmnsxf2347r4k2c77nbr9vw-glibc-2.18/lib/libc.so.6

Thread 1 (Thread 0x7f27591f8700 (LWP 30826)):
#0 0x00007f275c5cee7b in GC_build_fl4 () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#1 0x00007f275c5cf085 in GC_new_hblk () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#2 0x00007f275c5c4882 in GC_allocobj () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#3 0x00007f275c5c9320 in GC_generic_malloc_inner () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#4 0x00007f275c5c93fd in GC_generic_malloc () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#5 0x00007f275c5c9689 in GC_core_malloc_atomic () from /nix/store/f072ihgps3078d9l71w6c7fz8vway2wy-libgc-7.2d/lib/libgc.so.1
#6 0x00007f275c8ee3c4 in make_stringbuf (len=4) at strings.c:129
#7 0x00007f275c8efbf5 in scm_i_string_start_writing (orig_str=0x2c25360) at strings.c:573
#8 0x00007f275c8e4ccf in string_downcase_x (v=<optimized out>, start=start@entry=0, end=end@entry=4) at srfi-13.c:2169
#9 0x00007f275c8e50d8 in string_downcase_x (end=4, start=0, v=<optimized out>) at srfi-13.c:2167
#10 scm_substring_downcase (str=0x2c25380, start=<optimized out>, end=<optimized out>) at srfi-13.c:2218
#11 0x00007f275c90fa0f in vm_regular_engine (vm=<optimized out>, program=0x7f275cb9ef60 <scm_substring_downcase.subr_raw_cell>,
argv=<optimized out>, nargs=3) at vm-i-system.c:858
#12 0x00007f275c8f7b80 in really_launch (d=0x7fff4246a800) at threads.c:1005
#13 0x00007f275c87d7aa in c_body (d=0x7f27591f7d70) at continuations.c:517
#14 0x00007f275c90fa28 in vm_regular_engine (vm=<optimized out>, program=0x26d0040, argv=<optimized out>, nargs=2)
at vm-i-system.c:855
#15 0x00007f275c886fe3 in scm_call_4 (proc=0x27d8c30, arg1=arg1@entry=0x404, arg2=<optimized out>, arg3=<optimized out>,
arg4=<optimized out>) at eval.c:507
#16 0x00007f275c8f9999 in scm_catch_with_pre_unwind_handler (key=key@entry=0x404, thunk=<optimized out>, handler=<optimized out>,
pre_unwind_handler=<optimized out>) at throw.c:73
#17 0x00007f275c8f9a9f in scm_c_catch (tag=tag@entry=0x404, body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f27591f7d70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f27591f7d70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>,
pre_unwind_handler_data=pre_unwind_handler_data@entry=0x26d5040) at throw.c:207
#18 0x00007f275c87deef in scm_i_with_continuation_barrier (body=body@entry=0x7f275c87d7a0 <c_body>,
body_data=body_data@entry=0x7f27591f7d70, handler=handler@entry=0x7f275c87db80 <c_handler>,
handler_data=handler_data@entry=0x7f27591f7d70,
pre_unwind_handler=pre_unwind_handler@entry=0x7f275c87d930 <pre_unwind_handler>, pre_unwind_handler_data=0x26d5040)
at continuations.c
This message was truncated. Download the full message here.
?