Opened 7 years ago

Closed 7 years ago

#981 closed defect (fixed)

entropy-unix from srfi-27 pegs the CPU after /dev/urandom is accessed

Reported by: andyjpb Owned by: Kon Lovett
Priority: major Milestone: someday
Component: unknown Version: 4.8.x
Keywords: Cc:
Estimated difficulty:

Description

cpu-peg.scm:

(use srfi-27 entropy-unix)

(define (make-secret-generator)
  (let ((source (make-entropy-source-urandom-device)))
    (lambda (byte-width)
       (entropy-source-u8vector source byte-width))))

((make-secret-generator) 12)
csi -n cpu-peg.scm &
top

After the above code has been running for a minute or so the csi process will use 99.95 of the CPU.

Compiling the following code with csc and running the subsequent binary has the same effect:

cpu-peg-csc.scm:

(use srfi-27 entropy-unix)

(define (make-secret-generator)
  (let ((source (make-entropy-source-urandom-device)))
    (lambda (byte-width)
       (entropy-source-u8vector source byte-width))))

((make-secret-generator) 12)

(let loop ()
 (thread-sleep! 10)
 (display "x")(newline)
 (loop))

Maybe this has something to do with the following changesets?

Change History (6)

comment:1 in reply to:  description Changed 7 years ago by andyjpb

After the above code has been running for a minute or so the csi process will use 99.95 of the CPU.

99.9%

comment:2 Changed 7 years ago by Kon Lovett

Status: newassigned

I cannot reproduce:
#492 $ csi -n

CHICKEN
(c) 2008-2013, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.8.2 (rev 2967383)
macosx-unix-clang-x86-64 [ 64bit manyargs dload ptables ]
compiled 2013-02-06 on miyajima (Darwin)

#;1> (use srfi-27 entropy-unix)
; loading /usr/local/lib/chicken/7/srfi-27.import.so ...
; loading /usr/local/lib/chicken/7/chicken.import.so ...
; loading /usr/local/lib/chicken/7/data-structures.import.so ...
; loading /usr/local/lib/chicken/7/srfi-4.import.so ...
; loading /usr/local/lib/chicken/7/miscmacros.import.so ...
; loading /usr/local/lib/chicken/7/type-checks.import.so ...
; loading /usr/local/lib/chicken/7/type-errors.import.so ...
; loading /usr/local/lib/chicken/7/foreign.import.so ...
; loading /usr/local/lib/chicken/7/srfi-4-checks.import.so ...
; loading /usr/local/lib/chicken/7/srfi-4-errors.import.so ...
; loading /usr/local/lib/chicken/7/random-source.import.so ...
; loading /usr/local/lib/chicken/7/srfi-1.import.so ...
; loading /usr/local/lib/chicken/7/entropy-source.import.so ...
; loading /usr/local/lib/chicken/7/entropy-clock.import.so ...
; loading /usr/local/lib/chicken/7/entropy-support.import.so ...
; loading /usr/local/lib/chicken/7/extras.import.so ...
; loading /usr/local/lib/chicken/7/lolevel.import.so ...
; loading /usr/local/lib/chicken/7/srfi-27-vector-support.import.so ...
; loading /usr/local/lib/chicken/7/vector-lib.import.so ...
; loading /usr/local/lib/chicken/7/mrg32k3a.import.so ...
; loading /usr/local/lib/chicken/7/numbers.import.so ...
; loading /usr/local/lib/chicken/7/srfi-27-numbers.import.so ...
; loading /usr/local/lib/chicken/7/entropy-unix.import.so ...
; loading /usr/local/lib/chicken/7/entropy-port.import.so ...
; loading /usr/local/lib/chicken/7/timed-resource.import.so ...
; loading /usr/local/lib/chicken/7/srfi-18.import.so ...
; loading /usr/local/lib/chicken/7/synch.import.so ...
; loading /usr/local/lib/chicken/7/thread-utils.import.so ...
; loading /usr/local/lib/chicken/7/thread-reaper.import.so ...
; loading /usr/local/lib/chicken/7/record-variants.import.so ...
; loading /usr/local/lib/chicken/7/srfi-27.so ...
; loading /usr/local/lib/chicken/7/random-source.so ...
; loading /usr/local/lib/chicken/7/type-checks.so ...
; loading /usr/local/lib/chicken/7/type-errors.so ...
; loading /usr/local/lib/chicken/7/entropy-source.so ...
; loading /usr/local/lib/chicken/7/mrg32k3a.so ...
; loading /usr/local/lib/chicken/7/numbers.so ...
; loading /usr/local/lib/chicken/7/srfi-27-numbers.so ...
; loading /usr/local/lib/chicken/7/entropy-clock.so ...
; loading /usr/local/lib/chicken/7/entropy-support.so ...
; loading /usr/local/lib/chicken/7/srfi-27-vector-support.so ...
; loading /usr/local/lib/chicken/7/vector-lib.so ...
; loading /usr/local/lib/chicken/7/srfi-4-checks.so ...
; loading /usr/local/lib/chicken/7/srfi-4-errors.so ...
; loading /usr/local/lib/chicken/7/entropy-unix.so ...
; loading /usr/local/lib/chicken/7/entropy-port.so ...
; loading /usr/local/lib/chicken/7/timed-resource.so ...
; loading /usr/local/lib/chicken/7/synch.so ...
; loading /usr/local/lib/chicken/7/thread-utils.so ...
; loading /usr/local/lib/chicken/7/thread-reaper.so ...
#;2> (define (make-secret-generator)

(let ((source (make-entropy-source-urandom-device)))

(lambda (byte-width)

(entropy-source-u8vector source byte-width))))

#;3> ((make-secret-generator) 12)
#u8(56 118 21 36 202 100 135 10 39 214 15 110)
#;4> ,q

& the compiled cpu-peg-csc.scm just prints 'x'

comment:3 Changed 7 years ago by Moritz Heidkamp

I can reproduce it with 4.8.0.1, too. Kon, did you actually let it run for a while? It seems to start pegging the CPU after pretty exactly 1 minute.

comment:4 Changed 7 years ago by andyjpb

Thanks for looking into this Kon!

How long did you leave csi at the #;4> prompt before quitting? Rough testing suggests that it won't peg the CPU for the first 60 seconds after the random source is first accessed. Leaving it at the prompt for that long is enough to let it trigger. In the compiled version the bug triggers after around six 'x's have appeared. 'x's continue to appear until the process is killed.

When the bug happens, everything responds normally, except CPU utilisation goes up to 99.9% as measured in top. Perhaps it's spinning in a tight loop or something? It causes the fans on my machine to come on.

comment:5 Changed 7 years ago by andyjpb

Peter Bex caught the code spinning on poll() with ktrace.

Setting (define-constant DEFAULT-ENTROPY-PORT-CLOSE-SECONDS #f) in entropy-port.com switches off the port timeout functionality and prevents the bug from occuring.

comment:6 Changed 7 years ago by Kon Lovett

Resolution: fixed
Status: assignedclosed

Use thread-utils:1.0.2

The reaper's use of 'thread-yield!' causes the problem. Switched to 'thread-sleep!'.

Note: See TracTickets for help on using tickets.