ashinn / chibi-scheme

Official chibi-scheme repository
Other
1.21k stars 141 forks source link

`make test-all` will fail at `tests/ffi/ffi-tests.scm` on Cygwin #302

Closed okuoku closed 8 years ago

okuoku commented 8 years ago

make test-all won't pass on Cygwin

34 out of 34 (100.0%) subgroups passed.
LD_LIBRARY_PATH=".:" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme.exe tests/ffi/ffi-tests.scm
tests/ffi/basic.c:1:0: warning: -fPIC ignored for target (all code is position independent)
 /* Automatically generated by chibi-ffi; version: 0.3 */
 ^
ffi: ....      0 [main] chibi-scheme 311940 child_info_fork::abort: unable to map C:\cygwin64\home\oku\repos2\chibi-scheme\tests\ffi\basic.dll, Win32 error 126
......ERROR in delete-file: couldn't delete file
  called from <anonymous> on line 29 of file tests/ffi/ffi-tests.scm
  called from <anonymous> on line 1039 of file lib/init-7.scm
  called from <anonymous> on line 542 of file lib/init-7.scm
  called from <anonymous> on line 622 of file lib/init-7.scm
Makefile:223: recipe for target 'test-ffi' failed
make: *** [test-ffi] Error 70

This is because the test code deletes .dll file which is still mapped on the parent process here:

diff --git a/tests/ffi/ffi-tests.scm b/tests/ffi/ffi-tests.scm
index e01509b..982f1f6 100644
--- a/tests/ffi/ffi-tests.scm
+++ b/tests/ffi/ffi-tests.scm
@@ -34,7 +34,8 @@
               ((= orig-failures (test-failure-count))
                (delete-file stub-file)
                (delete-file c-file)))
-             (delete-file lib-file)))
+             ;(delete-file lib-file)
+             ))
           (else
            (test-assert (string-append "couldn't compile " name)
              #f))))))))

Unfortunately, on Cygwin, fork() require every loaded DLL files exist on the system since Win32 have no true fork() on their subsystem and Cygwin will emulate it by creating brand new process..

Hmm, I'm not sure whether or not switching to posix_spawn() or system() would solve the problem.. Perhaps, just defer removing lib-files on test completion is enough here..

okuoku commented 8 years ago

Tested at https://github.com/ashinn/chibi-scheme/tree/557b31e1dd1c8d99d1ddf6b71c7123eca2deb4dd

CYGWIN_NT-6.3 spring 2.3.1(0.291/5/3) 2015-11-14 12:44 x86_64 Cygwin

It seems lib/chibi/process.scm does not check fork() return value were a valid pid (a positive integer). Since POSIX APIs such as kill() would accept -1 as wild-card, pid values should always be validated...

okuoku commented 8 years ago

Hi, @ashinn thanks for patching but it won't solve the problem on Cygwin... You still have to defer deletion for any dlopened files on Cygwin because Cygwin won't allow you to fork() again if any dlopened shared object absent.

This patch will make the test pass on Cygwin64(I haven't tested Cygwin32 yet): https://github.com/okuoku/chibi-scheme/commit/42b808dbc0e67b4e7683b74d0b2ef93a26331014

In tests/ffi/ffi-test.scm,

  1. system procedure do fork to generate basic.dll
  2. dlopen basic.dll
  3. delete basic.dll

Then, it will try to fork again to generate the next test item(integers) but it fails because basic.dll is absent so it cannot reproduce its parent's address space. This is why the message

0 [main] chibi-scheme 311940 child_info_fork::abort: unable to map C:\cygwin64\home\oku\repos2\chibi-scheme\tests\ffi\basic.dll, Win32 error 126

appeared in the failure log.

... yep, it's weird behaviour but this is one of few things Cygwin can't be a real POSIX..

ashinn commented 8 years ago

Thanks, applied!