test-out-of-memory 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/bin/sh
  2. guild compile "$0"
  3. exec guile -q -s "$0" "$@"
  4. !#
  5. (unless (defined? 'setrlimit)
  6. ;; Without an rlimit, this test can take down your system, as it
  7. ;; consumes all of your memory. That doesn't seem like something we
  8. ;; should run as part of an automated test suite.
  9. (exit 0))
  10. (when (string-ci= "darwin" (vector-ref (uname) 0))
  11. ;; setrlimits are ignored in OS X (tested on 10.9 and 10.10). Proceeding
  12. ;; with the test would fill all available memory and probably end in a crash.
  13. ;; See also test-stack-overflow.
  14. (exit 77)) ; unresolved
  15. (when (string-ci= "GNU" (vector-ref (uname) 0))
  16. ;; setrlimits are not yet implemented on GNU/Hurd systems. Proceeding
  17. ;; with the test would end in a crash. See
  18. ;; <https://lists.gnu.org/archive/html/bug-hurd/2017-05/msg00013.html>
  19. (exit 77)) ; unresolved
  20. (when (string-contains-ci (vector-ref (uname) 0) "CYGWIN_NT")
  21. ;; attempting to use setrlimits for memory RLIMIT_AS will always
  22. ;; produce an invalid argument error on Cygwin (tested on
  23. ;; CYGWIN_NT-10.0 DLL v2.7.0). Proceeding with the test would fill
  24. ;; all available memory and probably end in a crash. See also
  25. ;; test-stack-overflow.
  26. (exit 77)) ; unresolved
  27. (catch #t
  28. ;; Silence GC warnings.
  29. (lambda ()
  30. (current-warning-port (open-output-file "/dev/null")))
  31. (lambda (k . args)
  32. (print-exception (current-error-port) #f k args)
  33. (write "Skipping test.\n" (current-error-port))
  34. (exit 77))) ; unresolved
  35. ;; 50 MB.
  36. (define *limit* (* 50 1024 1024))
  37. (call-with-values (lambda () (getrlimit 'as))
  38. (lambda (soft hard)
  39. (unless (and soft (< soft *limit*))
  40. (setrlimit 'as (if hard (min *limit* hard) *limit*) hard))))
  41. (define (test thunk)
  42. (catch 'out-of-memory
  43. (lambda ()
  44. (thunk)
  45. (error "should not be reached"))
  46. (lambda _
  47. #t)))
  48. ;; Prevent `test' from being inlined, which might cause an unused
  49. ;; allocation to be omitted.
  50. (set! test test)
  51. (use-modules (rnrs bytevectors))
  52. (test (lambda ()
  53. ;; Unhappily, on 32-bit systems, vectors are limited to 16M
  54. ;; elements. Boo. Anyway, a vector with 16M elements takes 64
  55. ;; MB, which doesn't fit into 50 MB.
  56. (make-vector (1- (ash 1 24)))))
  57. (test (lambda ()
  58. ;; Likewise for a bytevector. This is different from the above,
  59. ;; as the elements of a bytevector are not traced by GC.
  60. (make-bytevector #e1e9)))
  61. (test (lambda ()
  62. ;; This one is the kicker -- we allocate pairs until the heap
  63. ;; can't expand. This is the hardest test to deal with because
  64. ;; the error-handling machinery has no memory in which to work.
  65. (iota #e1e8)))
  66. (test (lambda ()
  67. ;; The same, but also causing allocating during the unwind
  68. ;; (ouch!)
  69. (dynamic-wind
  70. (lambda () #t)
  71. (lambda () (iota #e1e8))
  72. (lambda () (iota #e1e8)))))
  73. ;; Local Variables:
  74. ;; mode: scheme
  75. ;; End: