caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] mingw dll hell
@ 2004-02-22 23:04 Jeff Henrikson
  0 siblings, 0 replies; 4+ messages in thread
From: Jeff Henrikson @ 2004-02-22 23:04 UTC (permalink / raw)
  To: caml-list; +Cc: jefhen


-- 
Hello, during the caml-list outage of the last couple of weeks, it appears that I've been the false positive of some spam filter (two possible reasons being that I have an annoying company not-reconfigurable all-caps email address, and that there were some weird characters in my debugging output below), or else gotten lost in the mail interruption.  Here are two messages I sent last week.  Please cc replys to both this yahoo address and my work address jefhen@safeco.com.  Thank you.


Jeff Henrikson


--------------- message #1
Subject: mingw dll hell

Hello,

I had a several module mixed ocaml / C code working on a windows machine. It mysteriously stopped working today. In fact, every module which does any C DLL linking stopped working! If I link anything against C code now I get a nonfunctioning exe. I havenr modules, and I changed only my PATH variable to contain and then to not contain the current directory. The behavior to be precise is that native EXEs seg fault before running any code that I can tell about, and bytecode EXEs fail silently.

I admit that I had been playing around with the ocaml compiler and building it with some modifications, trying to get the backtracing behavior to improve on my example. I installed it over my binary ocaml distro a couple of times. But I was modifying my main project code at the same time. Now when stuff started breaking, I completely uninstalled ocaml (mingw-3.07p2), reinstalled from the binary installer, made clean all the projects, and everything is still broken. Even all the subprojects break now. I did not change the mingw tools at all to my knowledge.

I can however link with the dll files in the ocaml binary distribution. Hmm. I can't think of any other dll hell possibilities floating around. /usr/bin/cygwin1.dll is the only copy on the system.

Is this obvious to anyone? Sorry for being such an idiot. Some experiments follow. 

Thanks, 

Jeff Henrikson 

Here's the output of gdb on an example native EXE linked to a dll, again the corresponding bytecode program fails silently. The behavior of a "hello world" pcre program is the same.

Program received signal SIGSEGV, Segmentation fault. 
0x00335f9e in alloc_small () from /cygdrive/c/ocaml/bin/ocamlrun.dll 
(gdb) bt 
#0 0x00335f9e in alloc_small () from /cygdrive/c/ocaml/bin/ocamlrun.dll 
#1 0x100014d4 in _fu5__local_roots () at ocamole.cpp:229 
#2 0x10002e16 in guid_null (_=1) at ocamole.cpp:838 
#3 0x00407023 in Ocamole__entry () 
#4 0x00000001 in ?? () 
#5 0x00401355 in startup__code_begin () 
#6 0x00413dd2 in caml_start_program () 
(gdb) 
The build command of this example: 
ocamlopt -ccopt dllocamole.dll -ccopt -g -o olegen.exe ocamole.ml olegen.ml 
The build commands of the dll: 
gcc -I /cygdrive/c/ocaml/lib -I /usr/include/w32api -c ocamole.cpp 
gcc -shared -L /cygdrive/c/ocaml/lib -o dllocamole.dll -Wl,--out-implib,libocamo 
le.a ocamole.o -lole32 -loleaut32 -luuid -lkernel32 /cygdrive/c/ocaml/lib/ocamlr 
un.a -lstdc++ 
chmod 777 dllocamole.dll 


--------------- message #2
Subject: mingw dll hell

Per my post of yesterday, I'm having strange dynamic linking problems on mingw. I'm getting into weird territory here. Current behavior summary:

- Code which worked two days ago no longer works. I am not been able to relate this to any source code / compiler / system changes. Breakage includes compilation of some off the shelf ocaml modules. (eg, pcre-ocaml)

- Upon further inspection, the code which crashes is almost everything containing a ffi dll load. Linking C functions with -custom works fine, but dynlinking does not, in standalone programs or in the toplevel. In most cases, the result of running such a program is silent failure. Printfs at the top of the program sometimes execute but do not print. "flush stdout" typically crashes the VM.

- code which does not involve dynlinking does not crash at all, near as I can tell. The toplevel does not crash. Even doing #load "unix.cma";; ond running open_process doesn't crash.

- I compiled ocamlrun.exe and ocamlrun.dll with debugging information so that I could attach gdb. Tracing through interp.c on test input indicates that a fatal exception is thrown within 10-20 VM calls to C functions with 1 parameter. Typically, the crash is raised by a function having nothing to do with the ffi, like Pervasives.flush. And typically it is raised after the FFI primitive table gets loaded but before any of the FFI primitives get called. I include an example in gory detail below.

I am currently stuck thinking it must be something to do with the way I build dlls, but nothing has changed about that. All the same build scripts worked perfectly on Tuesday. No build tool changes, nothing.

Here's the example. Man it's been a long day. Anybody see anything? This feels like fantasy land. If anybody can say hey stupid and wake me out of my bad dream I would appreciate it.

Jeff Henrikson 


************* msgbox.c 

#include <windows.h> 
#include <caml/mlvalues.h> 
value c_msgbox(value i) 
{ 
MessageBox(NULL,"yay","hello",MB_OK); 
return Val_int(0); 
} 

************* msgbox.ml 

external msgbox : int -> unit = "c_msgbox";; 

************* msgtest.ml 

open Msgbox;; 
sin 0.0;; 
output_string stdout "std awake\n"; flush stdout;; 
sin 0.0;; 
msgbox 17;; 
cos 0.0;; 

************* build.sh 

gcc -I /cygdrive/c/ocaml/lib -I /usr/include/w32api -c msgbox.c 
gcc -shared -Wl,--out-implib,libocamole.a /cygdrive/c/ocaml/lib/ocamlrun.a msgbox.o -o dllmsgbox.dll 
ocamlc -c msgbox.ml 
ocamlc -a -o msgbox.cma -dllib -lmsgbox 
ocamlc -o msgtest.exe msgbox.cma msgtest.ml 

************* gdb session 

- need to -g compile ocamlrun.exe and ocamlrun.dll 

$ gdb ocamlrun.exe 
GNU gdb 2003-09-20-cvs (cygwin-special) 
Copyright 2003 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "i686-pc-cygwin"... 
(gdb) set args msgtest.exe 
(gdb) break main 
Breakpoint 1 at 0x4012d8: file main.c, line 38. 
(gdb) run 
Starting program: /cygdrive/c/src/dlltest/ocamlrun.exe msgtest.exe 
Breakpoint 1, main (argc=2, argv=0x3f40c0) at main.c:38 
38 expand_command_line(&argc, &argv); 
(gdb) break interprete 
Breakpoint 2 at 0x1000119c: file interp.c, line 225. 
(gdb) break interp.c:850 
Breakpoint 3 at 0x100022c0: file interp.c, line 850. 
(gdb) break startup.c:405 
Breakpoint 4 at 0x10003d95: file startup.c, line 405. 
(gdb) continue 
Continuing. 
Breakpoint 2, interprete (prog=0x0, prog_size=0) at interp.c:225 
225 if (prog == NULL) { /* Interpreter is initializing */ 
(gdb) 
Continuing. 
Breakpoint 2, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:225 
225 if (prog == NULL) { /* Interpreter is initializing */ 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) 
Continuing. 
Breakpoint 3, interprete (prog=0x3fcb20, prog_size=6184) at interp.c:850 
850 Setup_for_c_call; 
(gdb) step 
851 accu = Primitive(*pc)(accu); 
(gdb) step 
caml_flush (vchannel=4836348) at io.c:553 
553 struct channel * channel = Channel(vchannel); 
(gdb) step 
555 if (channel->fd == -1) return Val_unit; 
(gdb) 
556 Lock(channel); 
(gdb) 
557 flush(channel); 
(gdb) 
flush (channel=0x4a0f18) at io.c:197 
197 while (! flush_partial(channel)) /*nothing*/; 
(gdb) 
flush_partial (channel=0x4a0f18) at io.c:182 
182 towrite = channel->curr - channel->buff; 
(gdb) 
183 if (towrite > 0) { 
(gdb) 
184 written = do_write(channel->fd, channel->buff, towrite); 
(gdb) 
do_write (fd=1, 
p=0x4a0f40 "std awake\n-----\rd-\rd-\rd54 enter_blocking_section(); 
(gdb) 
enter_blocking_section () at signals.c:125 
125 temp = pending_signal; pending_signal = 0; 
(gdb) 
126 if (temp) execute_signal(temp, 0); 
(gdb) 
127 async_signal_mode = 1; 
(gdb) 
128 if (!pending_signal) break; 
(gdb) 
131 if (enter_blocking_section_hook != NULL) enter_blocking_section_hook() 
; 
(gdb) 
132 } 
(gdb) 
do_write (fd=1, 
p=0x4a0f40 "std awake\n-bbbd-d-d-
rd-+"..., n=10) at io.c:155 
155 retcode = write(fd, p, n); 
(gdb) 
156 leave_blocking_section(); 
(gdb) 
leave_blocking_section () at signals.c:140 
140 if (leave_blocking_section_hook != NULL) leave_blocking_section_hook() 
; 
(gdb) 
147 signal_number = pending_signal; 
(gdb) 
148 pending_signal = 0; 
(gdb) 
149 if (signal_number) execute_signal(signal_number, 1); 
(gdb) 
152 async_signal_mode = 0; 
(gdb) 
153 } 
(gdb) 
do_write (fd=1, 
p=0x4a0f40 "std awake\n-\rd-rd-f (retcode == -1) { 
(gdb) 
158 if (errno == EINTR) goto again; 
(gdb) 
159 if ((errno == EAGAIN || errno == EWOULDBLOCK) && n > 1) { 
(gdb) 
169 if (retcode == -1) sys_error(NO_ARG); 
(gdb) 
sys_error (arg=1) at sys.c:97 
97 CAMLparam1 (arg); 
(gdb) 
99 CAMLlocal1 (str); 
(gdb) 
101 if (errno == EAGAIN || errno == EWOULDBLOCK) { 
(gdb) 
104 err = error_message(); 
(gdb) 
error_message () at sys.c:70 
70 return strerror(errno); 
(gdb) 
71 } 
(gdb) 
sys_error (arg=1) at sys.c:105 
105 if (arg == NO_ARG) { 
(gdb) 
106 str = copy_string(err); 
(gdb) 
copy_string (s=0x3fe9d0 "Bad file descriptor") at alloc.c:100 
100 len = strlen(s); 
(gdb) 
101 res = alloc_string(len); 
(gdb) 
alloc_string (len=19) at alloc.c:74 
74 mlsize_t wosize = (len + sizeof (value)) / sizeof (value); 
(gdb) 
76 if (wosize <= Max_young_wosize) { 
(gdb) 
77 Alloc_small (result, wosize, String_tag); 
(gdb) 
82 Field (result, wosize - 1) = 0; 
(gdb) 
83 offset_index = Bsize_wsize (wosize) - 1; 
(gdb) 
84 Byte (result, offset_index) = offset_index - len; 
(gdb) 
86 } 
(gdb) 
copy_string (s=0x3fe9d0 "Bad file descriptor") at alloc.c:102 
102 memmove(String_val(res), s, len); 
(gdb) 
104 } 
(gdb) 
sys_error (arg=1) at sys.c:115 
115 raise_sys_error(str); 
(gdb) 
raise_sys_error (msg=4585348) at fail.c:107 
107 raise_with_arg(Field(global_data, SYS_ERROR_EXN), msg); 
(gdb) 
raise_with_arg (tag=4837168, arg=4585348) at fail.c:56 
56 CAMLparam2 (tag, arg); 
(gdb) 
57 CAMLlocal1 (bucket); 
(gdb) 
59 bucket = alloc_small (2, 0); 
(gdb) 
alloc_small (wosize=2, tag=0) at alloc.c:61 
61 Alloc_small (result, wosize, tag); 
(gdb) 
63 } 
(gdb) 
raise_with_arg (tag=4837168, arg=4585348) at fail.c:60 
60 Field(bucket, 0) = tag; 
(gdb) 
61 Field(bucket, 1) = arg; 
(gdb) 
62 mlraise(bucket); 
(gdb) 
mlraise (v=4585336) at fail.c:38 
38 Unlock_exn(); 
(gdb) 
39 exn_bucket = v; 
(gdb) 
40 if (external_raise == NULL) fatal_uncaught_exception(v); 
(gdb) 
41 siglongjmp(external_raise->buf, 1); 
(gdb) 
Breakpoint 4, caml_main (argv=0x3f40e8) at startup.c:405 
405 if (Is_exception_result(res)) { 
(gdb) quit 

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [Caml-list] mingw dll hell
@ 2004-02-27 23:57 HENRIKSON, JEFFREY
  0 siblings, 0 replies; 4+ messages in thread
From: HENRIKSON, JEFFREY @ 2004-02-27 23:57 UTC (permalink / raw)
  To: Peter Jolly; +Cc: caml-list

Hmm, thank you I didn't know about cygcheck.  I am accustomed to using
ldd under linux.

$ cygcheck test.exe
Found: .\test.exe
Found: C:\cygwin\bin\test.exe
test.exe
  C:\WINNT\system32\msvcrt.dll
    C:\WINNT\system32\KERNEL32.dll
      C:\WINNT\system32\ntdll.dll

I'd love to observe the crash, but the program doesn't print the first
line and gdb makes the bug go away.


Jeff Henrikson



-----Original Message-----
From: Peter Jolly [mailto:peter@jollys.org] 
Sent: Friday, February 27, 2004 3:42 PM
To: HENRIKSON, JEFFREY
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] mingw dll hell

> One thing I seem to be noticing is that there are fewer errors if I
> do not link to libraries that depend on cygwin1.dll.

While I can't explain why it worked before, in general it's an extremely

bad idea to mix MinGW and Cygwin in the same program.  If you're using 
gcc -mno-cygwin in the build process, you should not be linking to any 
Cygwin libraries at all.

As a simple test, run cygcheck on the generated executable.  If it lists

both cygwin1.dll and MSVCRT*.DLL among the dependencies, you are almost 
certain to have problems.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] mingw dll hell
  2004-02-27 22:50 HENRIKSON, JEFFREY
@ 2004-02-27 23:42 ` Peter Jolly
  0 siblings, 0 replies; 4+ messages in thread
From: Peter Jolly @ 2004-02-27 23:42 UTC (permalink / raw)
  To: HENRIKSON, JEFFREY; +Cc: caml-list

> One thing I seem to be noticing is that there are fewer errors if I
> do not link to libraries that depend on cygwin1.dll.

While I can't explain why it worked before, in general it's an extremely 
bad idea to mix MinGW and Cygwin in the same program.  If you're using 
gcc -mno-cygwin in the build process, you should not be linking to any 
Cygwin libraries at all.

As a simple test, run cygcheck on the generated executable.  If it lists 
both cygwin1.dll and MSVCRT*.DLL among the dependencies, you are almost 
certain to have problems.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Caml-list] mingw dll hell
@ 2004-02-27 22:50 HENRIKSON, JEFFREY
  2004-02-27 23:42 ` Peter Jolly
  0 siblings, 1 reply; 4+ messages in thread
From: HENRIKSON, JEFFREY @ 2004-02-27 22:50 UTC (permalink / raw)
  To: caml-list

This refers to my earlier post about dll trouble.  I am having
inconsistent dll linking behavior, though things are getting better as I
futz with more flags.  Again, three weeks ago all this same code and
build scripts worked perfectly.  One thing I seem to be noticing is that
there are fewer errors if I do not link to libraries that depend on
cygwin1.dll.

Here is one case I do not understand.  Under some builds I can ocamlrun
an exe with success, but running the exe by itself crashes.  (An
exception is probably being thrown, but I can't see it.)  Running under
GDB runs successfully.  How can this be?


Jeff Henrikson


--------------------------------

ocaml: 3.07pl2 mingw
pcre: 4.4
pcre-ocaml: 5.04.3
gcc: 3.3.1
windows: 2000

jefhen@HOXPCXJEFHEN ~/src/pcre-ocaml-5.04.3/lib
$ test

jefhen@HOXPCXJEFHEN ~/src/pcre-ocaml-5.04.3/lib
$ ocamlrun test.exe
hello
this12.3 is 2.78a t3st.
12 3 2 78 3
jefhen@HOXPCXJEFHEN ~/src/pcre-ocaml-5.04.3/lib
$ test.exe

jefhen@HOXPCXJEFHEN ~/src/pcre-ocaml-5.04.3/lib
$ gdb test.exe
GNU gdb 2003-09-20-cvs (cygwin-special)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "i686-pc-cygwin"...(no debugging symbols
found)...
(gdb) run
Starting program: /cygdrive/c/src/pcre-ocaml-5.04.3/lib/test.exe
hello
this12.3 is 2.78a t3st.
12 3 2 78 3
Program exited normally.
(gdb) quit

jefhen@HOXPCXJEFHEN ~/src/pcre-ocaml-5.04.3/lib
$


test.ml:

output_string stdout "hello\n"; flush stdout;

open Printf;;
open Pcre;;

let s = "this12.3 is 2.78a t3st.";;

let r = regexp "([0-9]+)";;

let a = extract_all ~full_match:false ~rex:r s;;

printf "%s\n" s;;

Array.iter (fun e -> printf "%s " e.(0)) a;;

flush stdout;

0;;


build commands:


ocamlc -c pcre.mli -o pcre.cmi
ocamlc -c pcre.ml -o pcre.cmo
gcc -mno-cygwin -D__MINGW32__ -I c:\ocaml\lib -I/usr/include -I
/usr/include/w32api -c pcre_stubs.c
gcc -mno-cygwin -shared -L `ocamlc -where` -o dllpcre_stubs.dll
-Wl,--out-implib,libpcre_stubs.a pcre_stubs.o -L . -lpcre-mingw `ocamlc
-where`/ocamlrun.a
Creating library file: libpcre_stubs.a
Info: resolving _local_roots by linking to __imp__local_roots
(auto-import)
chmod 777 dllpcre_stubs.dll
ocamlc -a -o pcre.cma pcre.cmo -dllib -lpcre_stubs


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-02-27 23:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-02-22 23:04 [Caml-list] mingw dll hell Jeff Henrikson
2004-02-27 22:50 HENRIKSON, JEFFREY
2004-02-27 23:42 ` Peter Jolly
2004-02-27 23:57 HENRIKSON, JEFFREY

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).