ironpython2 icon indicating copy to clipboard operation
ironpython2 copied to clipboard

gen_update_targets use for updateAndExecute leads to unbounded loop for typo at command prompt

Open markmi opened this issue 6 years ago • 1 comments

The code structure below, from inside generate_dynsites.py, sets up an unbounded loop when no match is found when the generated code is executed: The same failed BindCore call can be attempted over and over, with no way to return and no own-activity-generated exception as a way out.

//
// Miss on Level 0, 1 and 2 caches. Create new rule
//

rule = null;
var args = new object[] { %(argelems)s };

for (; ; ) {
    @this.Target = originalRule;
    rule = @this.Target = @this.Binder.BindCore(@this, args);

    //
    // Execute the rule on the matchmaker site
    //

    try {
        %(setResult)s rule(site%(args)s);
        if (CallSiteOps.GetMatch(site)) {
            %(returnResult)s;
        }
    } finally {
        if (CallSiteOps.GetMatch(site)) {
            //
            // The rule worked. Add it to level 1 cache.
            //
            CallSiteOps.AddRule(@this, rule);
        }
    }

    // Rule we got back didn't work, try another one
    CallSiteOps.ClearMatch(site);
}

This has been observed to loop indefinitely, using up a CPU core, for an interactively-made typo of the likes of:

> > > interfaceInstance.MisTypedMethodName()

where the interfaceInstance was from a use of (suggestive summary of the .NET C# code that produced the instance):

ChannelFactory<Interface>(binding,endpoint).CreateChannel()

[.net (WCF)]. A correctly typed Interface method name works fine. The repeated use of BindCore has been observed from the debugger and the routine with the loop does not return to its caller.

Looking around suggests that IronPython3's materials have the same structure and issue.

markmi avatar Mar 22 '18 20:03 markmi

The generate_dynsites.py generated code was actually part of Microsoft.Scripting.Core which was integrated to the .NET framework. The generator script is basically dead code.

Here's some repro code for the issue:

import clr
clr.AddReference("System.ServiceModel")
from System.ServiceModel import *

binding = BasicHttpBinding()
address = EndpointAddress("http://localhost:8000/ChannelApp")
factory = ChannelFactory[Channels.IRequestChannel](binding, address)
channel = factory.CreateChannel()
channel.MisTypedMethodName()

slozier avatar Jun 18 '18 14:06 slozier