32 bit vs 64 bit Cygwin, followup

Corinna Vinschen corinna-cygwin@cygwin.com
Sat Feb 2 17:05:00 GMT 2019


On Feb  2 09:42, Sam Habiel wrote:
> On Sat, Feb 2, 2019 at 9:39 AM Sam Habiel <sam.habiel@gmail.com> wrote:
> >
> > On Thu, Nov 29, 2018 at 11:33 AM Corinna Vinschen
> > <corinna-cygwin@cygwin.com> wrote:
> > >[...]
> > > One way is to create a SYSV wrapper for each C function called from
> > > assembler.  Assuming this simple scenario:
> > > [...]
> > I and a colleague started the work to migrate the Linux x64 version to
> > Cygwin. The results have been very promising; but I think we found a
> > bug in gcc when dealing with va_start in sysv_abi compiled code. I
> > have a simple test case. Can somebody confirm? It works fine without
> > the attribute on PrintFloats.
> >
> > /* va_start example */
> > #include <stdio.h>      /* printf */
> > #include <stdarg.h>     /* va_list, va_start, va_arg, va_end */
> >
> > void __attribute__ ((sysv_abi)) PrintFloats (int n, ...)
> > {
> >   int i;
> >   double val;
> >   printf ("Printing floats:");
> >   va_list vl;
> >   va_start(vl,n);
> >   for (i=0;i<n;i++)
> >   {
> >     val=va_arg(vl,double);
> >     printf (" [%.2f]",val);
> >   }
> >   va_end(vl);
> >   printf ("\n");
> > }
> >
> > int main ()
> > {
> >   PrintFloats (3,3.14159,2.71828,1.41421);
> >   return 0;
> > }
> 
> Sorry. Should say what the error is:
> 
> Hp@memphis ~/fis-gtm/build
> $ gdb a.exe
> [...]
> (gdb) r
> Starting program: /home/Hp/fis-gtm/build/a.exe
> [New Thread 11672.0xdd0]
> [New Thread 11672.0x1230]
> [New Thread 11672.0x20ac]
> [New Thread 11672.0x43f4]
> 
> Thread 1 "a" hit Breakpoint 1, main () at test.c:23
> 23        PrintFloats (3,3.14159,2.71828,1.41421);
> (gdb) s
> PrintFloats (n=1) at test.c:6
> 6       {
> (gdb) s
> 9         printf ("Printing floats:");
> (gdb) s
> 11        va_start(vl,n);
> (gdb) s
> 12        for (i=0;i<n;i++)
> (gdb) p vl
> $1 = (va_list) 0x3000000008 <error: Cannot access memory at address
> 0x3000000008>
> (gdb) s
> [New Thread 11672.0x3f9c]
> 14          val=va_arg(vl,double);
> (gdb) s
> 
> Thread 1 "a" received signal SIGSEGV, Segmentation fault.
> 0x000000010040112f in PrintFloats (n=3) at test.c:14
> 
> PS: Running this outside GDB causes Cygwin x64 to hang--and I don't
> know how to make it unhang.

That's not GCC fault.  You're running varargs, written for the standard
stack layout of the MSABI target from a function with a stack laid out
in SYSV ABI.  That can't work.

If you *have to* use varargs from SYSV ABI functions, you have to define
your own version of them.

But there's another problem with no easy hackaround, the hang you're
observing after the SEGV.

Keep in mind that *Windows* runs the exception handling in the first
place, not Cygwin.  Cygwin only installs a structured exception handler,
but that requires that windows can *find* the exception handler.

To do this, Windows needs to unwind the stack until it finds the
exception handler.  However, you're running a function using the SYSV
stack layout the Windows stack unwinder doesn't know about.  As a
result, this goes nowhere.  The stack unwinder runs wild or, if you're
lucky, just stops in the outermost structured exception handler or some
vectored exception handler.

I'm not sure there is a solution to that.  What you could try is to
install a structured exception handler inside the SYSV call.  You may
have to do this inside each and every SYSV function which *may* crash to
keep the Windows stack unwinder having to unwind to the calling function
at all.


Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20190202/7ff5a451/attachment.sig>


More information about the Cygwin mailing list