Bug 30146

Summary: stack imbalance in DllImport with CallingConvention.StdCall
Product: [Mono] Runtime Reporter: remirpan
Component: GeneralAssignee: Zoltan Varga <vargaz>
Status: RESOLVED NOT_REPRODUCIBLE    
Severity: normal CC: jonathan.purdy, ludovic, madewokherd, mono-bugs+mono, mono-bugs+runtime, vargaz
Priority: ---    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows   
Tags: Is this bug a regression?: ---
Last known good build:
Attachments: test case

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).
Comment 3 Ludovic Henry 2017-11-10 21:23:58 UTC
Hi, can you still reproduce with Mono 5.4.1.7 (2017-06/e66d9abbb27) (https://dl.xamarin.com/MonoFrameworkMDK/Macx86/MonoFramework-MDK-5.4.1.7.macos10.xamarin.universal.pkg)? I tried on macOS and couldn't reproduce it, so it might be a Windows specific bug.
Comment 4 Vincent Povirk 2017-11-13 20:27:29 UTC
I'm not able to reproduce this on current Mono. I tried 5.4.1.6, which was the latest build on the website, and my own build from the master branch.
Comment 5 Ludovic Henry 2017-11-15 15:06:24 UTC
Please reopen if you can reproduce with a later Mono version than 5.4. Thank you