Bug 6346

Summary: Mono does not support vararg pinvoke methods
Product: [Mono] Runtime Reporter: Brian Stone <direwolf1973>
Component: JITAssignee: Bugzilla <bugzilla>
Status: CONFIRMED ---    
Severity: enhancement CC: aaron.f.oneal, bberry, brubo2, kumpera, masafa, miguel, mono-bugs+mono, mono-bugs+runtime
Priority: Normal    
Version: unspecified   
Target Milestone: Future Cycle (TBD)   
Hardware: PC   
OS: Windows   
Tags: Is this bug a regression?: ---
Last known good build:

Description Brian Stone 2012-08-01 01:50:37 UTC
Runtime fails with an InvalidProgramException after calling into an unmanaged DLL. Tested this with Mono 2.10.8.

e:\Program Files (x86)\Mono-2.10.8\bin>more dlltest.cs

// dlltest.cs
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;

public class DllTest
    [DllImport("msvcrt", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    static extern int sprintf(StringBuilder buffer, string format, __arglist);
    static public void Main()
        StringBuilder str = new StringBuilder();
        DllTest.sprintf(str, "Hello %s", __arglist("World"));

e:\Program Files (x86)\Mono-2.10.8\bin>gmcs dlltest.cs

e:\Program Files (x86)\Mono-2.10.8\bin>mono dlltest.exe

Unhandled Exception: System.InvalidProgramException: Invalid IL code in DllTest:Main (): IL_0017: ret
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidProgramException: Invalid IL code in DllTest:Main (): IL_0017: ret

e:\Program Files (x86)\Mono-2.10.8\bin>monodis dlltest.exe --output=dlltestIL.txt

e:\Program Files (x86)\Mono-2.10.8\bin>view dlltestIL.txt
'view' is not recognized as an internal or external command,
operable program or batch file.

e:\Program Files (x86)\Mono-2.10.8\bin>more dlltestIL.txt

.assembly extern mscorlib
  .ver 2:0:0:0
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.assembly 'dlltest'
  .custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::'.ctor'() =  (
                01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01       ) // ceptionThrows.

  .hash algorithm 0x00008004
  .ver  0:0:0:0
.module dlltest.exe // GUID = {80996749-6E58-498A-A2DA-7372ADD10FE0}

.module extern 'msvcrt'

  .class public auto ansi beforefieldinit DllTest
        extends [mscorlib]System.Object

    // method line 1
    .method public hidebysig specialname rtspecialname
           instance default void '.ctor' ()  cil managed
        // Method begins at RVA 0x20ec
        // Code size 7 (0x7)
        .maxstack 8
        IL_0000:  ldarg.0
        IL_0001:  call instance void object::'.ctor'()
        IL_0006:  ret
    } // end of method DllTest::.ctor

    // method line 2
    .method private static hidebysig pinvokeimpl ("msvcrt" as "sprintf" ansi cdecl )
           vararg int32 sprintf (class [mscorlib]System.Text.StringBuilder buffer, string format)  cil managed preservesig
        // Method begins at RVA 0x0
    } // end of method DllTest::sprintf

    // method line 3
    .method public static hidebysig
           default void Main ()  cil managed
        // Method begins at RVA 0x20f4
        // Code size 24 (0x18)
        .maxstack 4
        .locals init (
                class [mscorlib]System.Text.StringBuilder       V_0)
        IL_0000:  newobj instance void class [mscorlib]System.Text.StringBuilder::'.ctor'()
        IL_0005:  stloc.0
        IL_0006:  ldloc.0
        IL_0007:  ldstr "Hello %s"
        IL_000c:  ldstr "World"
        IL_0011:  call vararg int32 class DllTest::sprintf(class [mscorlib]System.Text.StringBuilder, string, ..., string)
        IL_0016:  pop
        IL_0017:  ret  <----------- Invalid IL Code???
    } // end of method DllTest::Main

  } // end of class DllTest
Comment 1 Marek Safar 2012-08-02 12:12:18 UTC
The program is valid and verifies on .net

Mono JIT fails to compile it and Mono verifier fails as well.
Comment 2 Zoltan Varga 2012-08-07 16:56:11 UTC
varargs pinvoke methods are currently not supported by mono.
Comment 3 Aaron Oneal 2012-11-17 02:14:52 UTC
This would be useful for some marshaling code I'm writing. Is there any additional information available regarding why this isn't supported?
Comment 4 Zoltan Varga 2012-11-17 03:38:09 UTC
Its just a lot of work to implement.
Comment 5 Brian Berry 2015-02-08 12:32:43 UTC
FWIW, I just tripped on this one as well.

Ideally, if it's valid code, mono should handle it.

Less ideally (but better than nothing) would at least be a compile-time warning/error so that the first consequence isn't an obscure JIT failure at runtime.
Comment 6 Ruben Buniatyan 2016-11-04 19:37:57 UTC
Possible solution: http://stackoverflow.com/a/26307937/4301806