动态语言运行时与IIS 7.5结合使用的Bug [英] Bug in the dynamic language runtime in combination with IIS 7.5

查看:224
本文介绍了动态语言运行时与IIS 7.5结合使用的Bug的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于这个问题,我很抱歉,但我认为你会发现它值得。在我开始之前,让我说,我真的试图制作一个独立的控制台应用程序,但遗憾的是,这被证明是不可能的。该错误不会发生在控制台应用程序中。它不会发生在一个自包含的ASP.NET应用程序。只有在Windows 7的IIS 7.5中运行时才会发生。



错误似乎与动态语言运行时相关,因为它涉及到一个 __ TransparentProxy (通过WCF)和一个动态变量(一个int)。产生问题的一行是调用一个静态方法(恰好不包含方法体),同时传递代理和动态int。



一旦方法被调用,w3wp.exe进程占用了整个CPU,并开始快速增加内存(对我来说,每秒钟大约有100个百分比,尽管它可能是由于GC而造成的)。要重现此错误,请在Visual Studio(New|ProjectC#|Web|ASP)中创建一个新的ASP.NET网站。 NET Web应用程序)。然后在IIS中创建一个新的站点,其主目录是您的新项目。 (还可以让Everyone对该文件夹进行完整的读/写访问,并确保应用程序池正在使用.NET 4.0)为新站点提供一个特定的端口,如7080.最后将此代码粘贴到Global.asax.cs中:

  public class Global:System.Web.HttpApplication 
{
void Application_Start(object sender,EventArgs e )
{
dynamic dynamicId = 5;

var serviceUrl =http:// localhost:7182 / FooServices.svc;
ChannelFactory factory = new ChannelFactory< IFooServices>(new WSHttpBinding(),新EndpointAddress(serviceUrl));
factory.Open();
IFooServices fooServices =((ChannelFactory< IFooServices>)工厂).CreateChannel();

BlowUpTheProgram(fooServices,dynamicId); //这行挂起
}

[ServiceContract]
public interface IFooServices
{
[OperationContract]
void Bar();
}

public static void BlowUpTheProgram(IFooServices eventServices,int authorMailboxId)
{
}
}

现在通过 http:// localhost:7080 (或任何端口)访问浏览器中的网站你选择)。准备任务管理器,因为在确认报告的症状后,您将要杀死w3wp.exe进程。



要确认代理和动态协同工作来解决此错误,请更改以下行:

  dynamic dynamicId = 5; 

To:

 code> int dynamicId = 5; 

重试,你会注意到问题已经消失,页面加载。现在将其更改回动态,然后更改此行:

  IFooServices fooServices =((ChannelFactory< IFooServices>)工厂).CreateChannel(); 

To:

 code> IFooServices fooServices = null; 

重试,你会再次注意到这个问题在这种情况下也消失了。



最后,如果我附加调试器并将其全部删除,我可以看到它在这个方法调用中停留了什么。它似乎总是显示如下:


mscorlib.dll!System.RuntimeMethodHandle.GetDeclaringType(System.IRuntimeMethodInfo方法)+ 0x2f bytes

mscorlib.dll!System.Reflection.Emit.DynamicResolver.ParentToken(int token)+ 0x1f3 bytes

[本机到托管转换]

[管理到本机过渡]

mscorlib.dll!System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type delegateType,object target)+ 0x29 bytes

System.Core.dll!System.Linq。 Expressions.Expression> .Compile()+ 0xbb bytes

System.Core.dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> site,object [] args) + 0x10a bytes

System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite site = {System.Runtime.CompilerServices.CallSite>},WebApplication1.Global arg0 = { ASP.global_asax},WebApplication1.Global.IFooServices arg1 = {System.Runtime.Remoting.Proxies .__ TransparentProxy},对象arg2 = 5)+ 0x3f0字节

WebApplication1.dll!WebApplication1.Global.Application_Start(object sender = {System.Web.HttpApplicationFactory}, System.EventArgs e = {System.EventArgs})行19 + 0x1b8字节C#


对于记录,我已经尝试了三台不同的机器,只能在Windows7 / IIS7.5盒子上进行修改。在Windows Server 2008 / IIS7框中没有问题。



问题是,如何解决这个问题并成功调用方法?另外,为什么会这样呢?我会讨厌调用使用DLR的东西,因为它会使IIS崩溃。

解决方案

我无法回答为什么会发生这种情况,但是当传递参数将会起作用时,将动态对象转换为 int

  DontBlowUpTheProgram(fooServices,(int)dynamicId); 

也许有更多知情内幕的人会进行更全面的探索。


I apologize for this question length, but I think you'll all find it worth it. Before I begin, let me say that I was really trying to produce an isolated console application, but sadly that proved impossible. The bug does not happen in a console app. It doesn't happen in a self-contained ASP.NET app. It only happens when run within IIS 7.5 on Windows 7.

The error seems related to the dynamic language runtime as it involves the combination of a __TransparentProxy (via WCF) and a dynamic variable (an int). The line that produces the problem is the invocation of a static method (that happens to contain no method body) passing in both the proxy and the dynamic int.

Once the method is invoked, the w3wp.exe process takes up the entire CPU and starts increasing memory very rapidly (for me about 100 megs per second, though it tapers off presumably due to GC'ing).

To reproduce this error, create a new ASP.NET web site in Visual Studio ("New" | "Project" "C#" | "Web" | "ASP.NET Web Application"). Then create a new site in IIS whose home directory is your new project. (also, give "Everyone" full read/write access to that folder and make sure the app pool is using .NET 4.0) Give the new site a specific port, like 7080. Finally, paste this code into Global.asax.cs:

public class Global : System.Web.HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        dynamic dynamicId = 5;

        var serviceUrl = "http://localhost:7182/FooServices.svc";
        ChannelFactory factory = new ChannelFactory<IFooServices>(new WSHttpBinding(), new EndpointAddress(serviceUrl));
        factory.Open();
        IFooServices fooServices = ((ChannelFactory<IFooServices>)factory).CreateChannel();

        BlowUpTheProgram(fooServices, dynamicId);  // This line hangs
    }

    [ServiceContract]
    public interface IFooServices
    {
        [OperationContract]
        void Bar();
    }

    public static void BlowUpTheProgram(IFooServices eventServices, int authorMailboxId)
    {
    }
}

Now access the site in your browser via http://localhost:7080 (or whatever port you chose). Have task manager ready because you'll want to kill the w3wp.exe process after confirming the reported symptoms.

To confirm that the proxy and dynamic are working together to surface this bug, change this line:

dynamic dynamicId = 5;

To:

int dynamicId = 5;

Retry, and you'll notice the problem has gone away and the page loads. Now change it back to dynamic and then change this line:

IFooServices fooServices = ((ChannelFactory<IFooServices>)factory).CreateChannel();

To:

IFooServices fooServices = null;

Retry, and you'll again notice the problem is gone in this scenario too.

Finally, if I attach the debugger and break all, I can see what it's doing while stuck in this method call. It seems to always show something like:

mscorlib.dll!System.RuntimeMethodHandle.GetDeclaringType(System.IRuntimeMethodInfo method) + 0x2f bytes
mscorlib.dll!System.Reflection.Emit.DynamicResolver.ParentToken(int token) + 0x1f3 bytes
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type delegateType, object target) + 0x29 bytes
System.Core.dll!System.Linq.Expressions.Expression>.Compile() + 0xbb bytes
System.Core.dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> site, object[] args) + 0x10a bytes
System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite site = {System.Runtime.CompilerServices.CallSite>}, WebApplication1.Global arg0 = {ASP.global_asax}, WebApplication1.Global.IFooServices arg1 = {System.Runtime.Remoting.Proxies.__TransparentProxy}, object arg2 = 5) + 0x3f0 bytes
WebApplication1.dll!WebApplication1.Global.Application_Start(object sender = {System.Web.HttpApplicationFactory}, System.EventArgs e = {System.EventArgs}) Line 19 + 0x1b8 bytes C#

For the record, I've tried it on three different machines and was able to repro only on the Windows7/IIS7.5 boxes. On the Windows Server 2008 / IIS7 box there was no problem.

The question is, how do I solve this problem and successfully invoke the method? Also, why is this happening? I'd hate to have to be overly careful about invoking things that will use the DLR because it will make IIS crash.

解决方案

I'm not able to answer Why this happens however casting your dynamic object to int when passing the parameter will work.

DontBlowUpTheProgram(fooServices, (int)dynamicId); 

Perhaps someone with more knowlege of the internals will wade in with a fuller explination.

这篇关于动态语言运行时与IIS 7.5结合使用的Bug的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆