This is Xamarin's bug tracking system. For product support, please use the support links listed in your Xamarin Account.
Bug 30146 - stack imbalance in DllImport with CallingConvention.StdCall
Summary: stack imbalance in DllImport with CallingConvention.StdCall
Status: ASSIGNED
Alias: None
Product: Runtime
Classification: Mono
Component: misc (show other bugs)
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Zoltan Varga
URL:
Depends on:
Blocks:
 
Reported: 2015-05-15 15:53 UTC by remirpan
Modified: 2016-09-07 20:37 UTC (History)
5 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
test case (350 bytes, text/plain)
2016-08-01 21:57 UTC, Vincent Povirk
Details

Description remirpan 2015-05-15 15:53:53 UTC
/*

 the difference between FAIL() and PASS2() is CallingConvention.StdCall for FAIL() function.

 mono_arch_emit_epilog function for FAIL(0) uses x86_ret_imm(code, stack_to_pop), which gives "ret 4" and stack imbalance.

 mono_arch_emit_epilog function for PASS2(0) uses x86_ret(code), which gives the "ret".

 "mono\mini\mini-x86.c"
 void mono_arch_emit_epilog (MonoCompile *cfg)
 {
 ....
	if (stack_to_pop) {
		g_assert (need_stack_frame);
		x86_ret_imm (code, stack_to_pop); // when called FAIL(0)
	} else {
		x86_ret (code); // when called PASS2()
	}
 ....
 }

*/

using System;
using System.Runtime.InteropServices;

class Program
{

	static void Main()
	{
#if true // 0xC000005 demo
		for (int i = 0; i < 16; i++)
		{
			FAIL(0);
			//PASS1(0);
			//PASS2(0);
			Console.WriteLine(i);
		}
#else // stack overflow demo
		while (true)
		{
			FAIL(0);
			//PASS2(0);
		}
#endif
	}

	[DllImport("kernel32.dll", EntryPoint = "Sleep", CallingConvention = CallingConvention.StdCall)]
	static extern void FAIL (UInt32 ms);

	[DllImport("kernel32.dll", EntryPoint = "Sleep", CallingConvention = CallingConvention.Winapi)]
	static extern void PASS1 (UInt32 ms);

	[DllImport("kernel32.dll", EntryPoint = "Sleep")]
	static extern void PASS2 (UInt32 ms);

}

//eof
Comment 1 Vincent Povirk 2016-08-01 21:56:08 UTC
I found a version that didn't have this bug, and then bisected it. The first bad commit was:

commit 7968a8df1674a6e2aa8990faaca3c426efc2e279
Author: Zoltan Varga <vargaz@gmail.com>
Date:   Mon Sep 29 13:01:41 2014 -0400

    [x86] Reenable the no pushes code again.
Comment 2 Vincent Povirk 2016-08-01 21:57:27 UTC
Created attachment 16853 [details]
test case

Here's a test case for any x86 platform (not just Windows).

Note You need to log in before you can comment on or make changes to this bug.