Fix abort and import lib search on Windows
authorTamar Christina <tamar@zhox.com>
Sun, 15 Jan 2017 13:07:36 +0000 (13:07 +0000)
committerTamar Christina <tamar@zhox.com>
Sun, 15 Jan 2017 13:07:36 +0000 (13:07 +0000)
Summary:
Apparently `sysErrorBelch` doesn't terminate the program anymore making
previously unreachable code now execute. If a dll is not found the error
message we return needs to be a heap value.

Secondly also allow the pattern `lib<name>` to be allowed for finding an
import library with the name `lib<name>.dll.a`.

Test Plan: ./validate, new tests T13082_good and T13082_fail

Reviewers: austin, RyanGlScott, hvr, erikd, simonmar, bgamari

Reviewed By: RyanGlScott, bgamari

Subscribers: thomie, #ghc_windows_task_force

Differential Revision: https://phabricator.haskell.org/D2941

GHC Trac Issues: #13082

compiler/ghci/Linker.hs
rts/linker/PEi386.c
testsuite/tests/rts/T13082/Makefile [new file with mode: 0644]
testsuite/tests/rts/T13082/T13082_fail.stderr [new file with mode: 0644]
testsuite/tests/rts/T13082/T13082_good.stdout [new file with mode: 0644]
testsuite/tests/rts/T13082/all.T [new file with mode: 0644]
testsuite/tests/rts/T13082/main.hs [new file with mode: 0644]

index b50edca..9252489 100644 (file)
@@ -1351,7 +1351,9 @@ locateLib hsc_env is_hs dirs lib
      loading_profiled_hs_libs = interpreterProfiled dflags
      loading_dynamic_hs_libs  = interpreterDynamic dflags
 
-     import_libs  = [lib <.> "lib", "lib" ++ lib <.> "lib", "lib" ++ lib <.> "dll.a"]
+     import_libs  = [ lib <.> "lib"           , "lib" ++ lib <.> "lib"
+                    , "lib" ++ lib <.> "dll.a", lib <.> "dll.a"
+                    ]
 
      hs_dyn_lib_name = lib ++ '-':programName dflags ++ projectVersion dflags
      hs_dyn_lib_file = mkHsSOName platform hs_dyn_lib_name
index 6cd4861..1d0682b 100644 (file)
@@ -240,10 +240,11 @@ addDLL_PEi386( pathchar *dll_name )
 
 error:
    stgFree(buf);
-   sysErrorBelch("addDLL: %" PATH_FMT " (Win32 error %lu)", dll_name, GetLastError());
 
+   char* errormsg = malloc(sizeof(char) * 80);
+   snprintf(errormsg, 80, "addDLL: %" PATH_FMT " or dependencies not loaded. (Win32 error %lu)", dll_name, GetLastError());
    /* LoadLibrary failed; return a ptr to the error msg. */
-   return "addDLL: could not load DLL";
+   return errormsg;
 }
 
 pathchar* findSystemLibrary_PEi386( pathchar* dll_name )
diff --git a/testsuite/tests/rts/T13082/Makefile b/testsuite/tests/rts/T13082/Makefile
new file mode 100644 (file)
index 0000000..1f023b0
--- /dev/null
@@ -0,0 +1,15 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+.PHONY: T13082_good
+T13082_good:
+       '$(TEST_CC)' -c foo.c -o foo.o
+       '$(AR)' rsc libfoo.a foo.o
+       '$(TEST_HC)' -shared foo_dll.c -o libfoo-1.dll
+       mv libfoo-1.dll.a libfoo.dll.a
+       echo main | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) main.hs -llibfoo -L"$(PWD)"
+
+.PHONY: T13082_fail
+T13082_fail:
+       ! echo main | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) main.hs -ldoesnotexist
diff --git a/testsuite/tests/rts/T13082/T13082_fail.stderr b/testsuite/tests/rts/T13082/T13082_fail.stderr
new file mode 100644 (file)
index 0000000..281e16a
--- /dev/null
@@ -0,0 +1,3 @@
+<command line>: user specified .o/.so/.DLL could not be loaded (addDLL: doesnotexist or dependencies not loaded. (Win32 error 126))
+Whilst trying to load:  (dynamic) doesnotexist
+Additional directories searched: (none)
diff --git a/testsuite/tests/rts/T13082/T13082_good.stdout b/testsuite/tests/rts/T13082/T13082_good.stdout
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/testsuite/tests/rts/T13082/all.T b/testsuite/tests/rts/T13082/all.T
new file mode 100644 (file)
index 0000000..dd94766
--- /dev/null
@@ -0,0 +1,11 @@
+test('T13082_good', [ extra_clean(['libfoo.a', 'libfoo-1.dll', 'foo.o', 'main.o'])
+                  , extra_files(['foo.c', 'main.hs', 'foo_dll.c'])
+                  , unless(opsys('mingw32'), skip)
+                  ],
+                  run_command, ['$MAKE -s --no-print-directory T13082_good'])
+
+test('T13082_fail', [ extra_clean(['main.o'])
+                  , extra_files(['main.hs'])
+                  , unless(opsys('mingw32'), skip)
+                  ],
+                  run_command, ['$MAKE -s --no-print-directory T13082_fail'])
diff --git a/testsuite/tests/rts/T13082/main.hs b/testsuite/tests/rts/T13082/main.hs
new file mode 100644 (file)
index 0000000..fbc8f56
--- /dev/null
@@ -0,0 +1,5 @@
+module Main where
+
+foreign import ccall "foo" c_foo :: Int
+
+main = print c_foo