Euphoria Ticket #462: MinGW crashes when using normal callc

This was previously discovered before the RC1 release. Something is wrong with the callc code and MinGW that is causing it to crash whenever a C routine is called with call_c().

This is worked around by using the C-only version of call_c() in RC1 and later when eu.a is compiled with MinGW. As a result, c_func/c_proc now works under MinGW, and this is not an urgent bug (and can be safely postponed past 4.1.0 if necessary). Still, someone at somepoint should look into why this broke.

Details

Type: Bug Report Severity: Minor Category: Library Routine
Assigned To: eumario Status: Fixed Reported Release:
Fixed in SVN #: 4523, 4552 View VCS: 4523, 4552 Milestone: 4.1.0

1. Comment by mattlewis Nov 30, 2010

The next debugging step is to try running objdump on be_runtime.c to look at the ASM of the callback routines.

2. Comment by jimcbrown Nov 30, 2010

As of svn:3870 the callback code was working perfectly on MinGW ... has it since broke?

It's funny, that the more obscure callback code worked but the simpler asm-based call_c() is broke on MinGW.

3. Comment by jimcbrown Dec 01, 2010

Assigning to eumario.

4. Comment by eumario Dec 04, 2010

Do we have a test for this issue, that I can run and check to see if it is working or not?

5. Comment by jimcbrown Dec 04, 2010

Line 83 of be_callc.c, change "#ifndef EMINGW" to "#if 1" or something, then rebuild mingw and run the callc.ex demo.

Or, t_dep.e and t_legacy_callback.e will expose the bug also.

6. Comment by eumario Dec 05, 2010

Confirmed Fixed in Revision 4523, asm based call_c() is now properly working.

7. Comment by jimcbrown Dec 05, 2010

I wonder what changed between svn:3810 and svn:4523 that fixed it.

8. Comment by ne1uno Dec 06, 2010

I noticed a problem when the minGW built eui r4523+ will exit silently if you don't add a '+' in the function signature for calls to a routine in a compiled dll.

not sure what the correct behavior is here, but it seems wrong that eui would just exit w/o error.

I've uploaded some sample code with prebuilt dll's gcc4.5
ccheckdll.zip

to rebuild you would need qmake, available on many systems. or from http://qt.nokia.com as part of Qt GUI toolkit.

9. Comment by jimcbrown Dec 06, 2010

Reopening, based on ne1uno's bug report.

10. Comment by SDPringle Jun 29, 2011

I have been doing some research on this. I found out about GCC using a different calling convention than what is normal for Windows: CDECL and STDCALL, respectively. What happens if you open a mingw library? Does MINGW follow Windows calling conventions?

What if you actually need to use STDCALL on UNIX? You cannot.

The supplied test seems to work 100% no matter how many times I run it. Perhaps this was since fixed again or perhaps this is a problem in the main-trunk only?

11. Comment by SDPringle Jun 29, 2011

This is working in eui version 77e6b084b433 (4.1 ARM branch)

12. Comment by mattlewis Jun 30, 2011

I've never heard of gcc using a different calling convention on x86. Watcom and MSVC++ both have their own conventions (fastcall and thiscall, respectively, that I'm aware of). On Unix x86, there is only cdecl. x86-64 has its own convention that appears to be the same across windows and unix.

13. Comment by SDPringle Jun 30, 2011

Don't misconstrue what I said. I said gcc's convention is different from what is normal on Windows.

14. Comment by mattlewis Jun 30, 2011

The default convention on windows compilers is not actually STDCALL, which is why all of the windows headers have to declare it everywhere. For watcom, it's their fastcall, and for MSVC, it's CDECL. Outside of Pascal, I'm not aware of compilers that default to STDCALL.

15. Comment by SDPringle Jun 30, 2011

For this ticket, the relevant to this ticket is the calling convention used in shared libraries.

CDECL : LUNIX and LINUX like OS libraries 
STDCALL : WINDOWS 

So, this code has the variables named badly.

 
ifdef WINDOWS then 
	constant libdll = open_dll("ccheckdll.dll") 
	constant libwrap = open_dll("ccheckwrap.dll") 
 	--constant stdcall = "+" 
	constant stdcall = "" 
elsifdef UNIX then 
	constant libdll = open_dll("ccheckdll.so") 
	constant libwrap = open_dll("ccheckwrap.so") 
	constant stdcall = "" 
elsedef 
	puts(2, "OS not supported yet\n") 
	abort(1) 
end ifdef 

It should read:

ifdef WINDOWS then 
	constant libdll = open_dll("ccheckdll.dll") 
	constant libwrap = open_dll("ccheckwrap.dll") 
 	constant cdecl = "+" 
	constant stdcall = "" 
	constant default_convention = stdcall 
elsifdef UNIX then 
	constant libdll = open_dll("ccheckdll.so") 
	constant libwrap = open_dll("ccheckwrap.so") 
	constant cdecl = "" 
	constant default_convention = cdecl 
elsedef 
	puts(2, "OS not supported yet\n") 
	abort(1) 
end ifdef 
 
constant convention = default_convention 

And then prefix 'convention' with everything instead of 'stdcall' or not at all.

16. Comment by mattlewis Jun 30, 2011

The calling convention is determined by the author of the library. The author of the Win32 API decided long ago to use STDCALL. That does not prevent (nor has it!) anyone on windows to release libraries with different conventions. How he does so is compiler specific.

There are plenty of libraries for Windows that use cdecl. Watcom is a little weird. I think that it does some extra work to restore the stack after a call, so you can actually mess up the calling convention at times and have things work. So, likely, it was a bug that was there the whole time, but was being hidden by a quirk in Watcom.

17. Comment by ne1uno Jul 01, 2011

thanks Shawn for the corrected code, I admit to being confused as to which convention requires '+' there are examples both ways in various forum posts and in previous docs. compounded by the fact that watcom works either way. before this ticket and gcc 4.5 so did minGW.

I believe eumario reverted the change which is why everything still worked in 4.0 and 4.1, for me anyway. not sure there are tests to expose the exact bug I was seeing.

Search



Quick Links

User menu

Not signed in.

Misc Menu