Scott Hanselman

ASP.NET Compiler Error 128 and Microsoft Support

July 27, '04 Comments [3] Posted in ASP.NET | XML | Bugs
Sponsored By

I'm having a heck of a problem with a particular box and a dev site that's running ASP.NET.  We're getting:

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: The compiler failed with error code 128.

This, along with a lovely compilation dump that shows the source of the Global.asax (the text file, not the Global.asax.cs code-behind.)

I've been working with Microsoft Premier Support but I'm getting pretty frustrated as the general message is "ya, this is obscure, it rarely happens and noone knows why."

Here's what I've collected about the problem so that it may help folks in the future.

Error Code 128 is a core Windows Error ERROR_WAIT_NO_CHILDREN that can happen when a CreateProcess() call fails - like starting the compiler to dynamically compile a page.  This error is mentioned in KB articles 155011 and 156464, as well as 184802 which implies it's a problem that happens running out of desktop heap.

Folks that have "fixed" this for themselves have done one or more of the following:

  • It's been said, but not conclusively that it's been fixed by applying the 821156 ASP.NET June 2003 Rollup Hotfix
  • It has also been said that running your Windows 2003 IIS 6.0 process in IIS 5.0 Isolation Mode fixes it.
  • It has been said that removing the Web App's folder(s) from the scrutiny of your Virus Scanner fixes it.

I've found cases of this happening on Windows 2000 and IIS5 with .NET Framework 1.0, as well as many on newer configurations.

I'd be interested to hear what someone on the ASP.NET team has to say about this problem, as I've found documentation of it happening on and off over the last three years.  Certainly there must be an ASP.NET team member who can say, "Oh! Ya, that.  You need to flip the bizzle and restart the universal kishkey..." or something.

Anyone else ever see this issue and solve it?  Personally, in ~3.5 years of messing with ASP.NET this is a first for me.

UPDATE - SOLVED: It was a funky ISAPI Filter that was sitting ahead of the ASP.NET ISAPI Extension. There is a slight architecture difference for ISAPI filters with IIS 6.0. 

UPDATE #2 - MORE INFO: From the Support KB 327611 "IIS 6.0: ISAPI Filters for Earlier Versions of IIS May Not Load" - I wonder if this was involved?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Use of Posters and Flow Charts in Lieu of Prose for Documentation - Is a Visio is Worth a Thousand Words?

July 22, '04 Comments [0] Posted in XML | Web Services | Tools
Sponsored By

We've got fairly powerful (but some say, complicated) Code Generation process that uses XML Schema along with (with thing) an interesting use of WSDL with an alternate binding.  Voyager is our flagship snazzy eFinance Server and using standard modelling tools (XMLSpy, VS.NET, etc) one (business person, computer wonk, whoever) can sit down and model all their Domain Objects, Request and Response Messages in XSD (nouns) and associate them with actual Voyager Operations (verbs) in WSDL.  Then rather than using a SOAP binding (if they were to talk to a Web Service with these messages) they can use a Voyager Binding in WSDL.  Then we run a Code Generation process on the WSDL/XSD and generate all the C# objects, messages, proxy layers, Word Documentation, yada yada yada. 

All this is built into our Continuous Integration Process so when one checks in an XSD into the Version Control System those artifacts are automatically built and made available to others.

Since this is a fairly complex experience to the non-XML initiated, a lot of prose has been written and a lot of hand waving happens to explain this process.

Some users though felt the prose was, well, too prose-y, and wanted a quicker way to grok the material. 

So, I spent two days in Visio creating a 44" by 34" poster (FOUR 11" by 17" pages or one big Plotter plot) that has the source of the XSDs, the source of the generated objects and stacks, as well as diagrams describing the relationships between objects when they exist in a running process. 

People can look at the code generation progression as well as the composition of elements:

  • Declarative XSDs (multiple ones, lots of imports, namespaces and custom attributes)
  • Generated C# code
  • Assembly names, class names, .NET namespace names
  • Resulting compiled assemblies
  • How those final build artifacts exist in a running system

I've finished the first draft (this screen shot is to give you an idea of the scope and size of this poster) and will share it with the team tomorrow. 

How often do you or your groups create one large diagram instead of writing one or more large documents?  When are architecture & design posters useful and when are just trouble?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Computer Back - Pain and the Programmer

July 19, '04 Comments [31] Posted in Programming
Sponsored By

I'm on my butt today.  More specifically, on my back.  This weekend my lower back seized up - just one muscle it seems, as the back turns into butt.  It's amazing how a little stabilizer muscle can go nuts suddenly and mess up your whole system. 

I call it "Programmer Back" as there are a handful of other folks that sit in front of a machine all day that have had this problem. 

It seems the symptoms are nearly universal:

  • Everything is fine, often for months.
  • A seizing happens and you drop to your knees.
  • Often you can't stand without help, or if you do, you're bent over like an old person.
  • If you don't move, you're OK, but bending over, or rolling out of the bed become impossible.
  • It lasts for as little as 3 days or a much as a week and a half.

Some say ice, some say heat, some say massage.  Still others advocate chiropractic.

Have you had Programmers Back?  How do you deal with it?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Validating that XmlSchemas and their Imports are Valid and All Good with an XmlResolver.

July 15, '04 Comments [1] Posted in XML | Bugs
Sponsored By

The very awesome Oleg Tkachenko commented in a recent post of mine (as did Patrick Cauldwell, in person) that what I was doing could have been accomplished with a custom XmlResolver.  Both are absolutely right.

I did my little hack because it was quick but Oleg's right, it would have been "more correct" to do something like this:

public class XmlCustomResolver : XmlUrlResolver
{
  override public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
  {
     //Here, mess with absoluteUri.AbsolutePath and return an XPathNavigator or Stream or whatever
 
}
}

So what happens is that you pass in the Resolver into the call to .Compile like:

foreach(XmlSchema x in w.Schemas)
{
  
x.Compile(new ValidationEventHandler(OnValidationEvent), new XmlBaseDirectoryResolver());
}

However, my problem was a smidge more subtle than it initially appeared.

The problem was, for me, that I want to resolve the schemaLocations (which look like "banking/someDomainObject.xsd") relative to the path that the WSDL is in, like "C:\dev\whatever\wsdl\".  However, by the time we get into the Resolver (when .Compile calls back to GetEntity()) the propery absoluteUrl.AbsolutePath already contains "C:\dev\MyTestConsole\bin\debug\someDomain\banking\someDomainObject.xsd."  See?  It's already "pre-resolved" the path relative to AppDomain.CurrentDomain.CurrentDirectory

At this point, I have no way (that I can see) to know what was the original relative path.  I want the schemaLocation to be "C:\dev\whatever\wsdl\banking\someDomainObject.xsd."  I could have passed the directory of the WSDL file into the constructor call to the Resolver.  So we add:

foreach(XmlSchema x in w.Schemas)
{
   x.Compile(new ValidationEventHandler(OnValidationEvent), new XmlBaseDirectoryResolver(wsdlFile.DirectoryName));
}

Note that the AbsolutePath has the Directory Separators as "/", so I have to fix those as well.  Here's the final "XmlBaseDirectoryResolver."  It's more lines of code, but it's also reusable.

public class XmlBaseDirectoryResolver : XmlUrlResolver
{
 
private string baseDir = String.Empty;
  public XmlBaseDirectoryResolver(string baseDirectory) : base()
 
{
   
baseDir = baseDirectory;
 
}

 
override public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
 
{
   
if (absoluteUri.IsFile == true)
    
{
      
//Change the directory characters to the same ones that AppDomain.CurrentDomain.BaseDirectory uses
      
string newFileName = absoluteUri.AbsolutePath.Replace('/',Path.DirectorySeparatorChar);
      
//Now, yank the automatically added portion...
      
newFileName = newFileName.Replace(AppDomain.CurrentDomain.BaseDirectory,String.Empty);
      
//Add our Base Directory...
      
newFileName = Path.Combine(baseDir, newFileName);
      
//Return the file...
      
return new FileStream(newFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
    }
    return base.GetEntity(absoluteUri, role, ofObjectToReturn);
  }
}

The big problem with this particular result?  It doesn't work with relative paths that use the dotdotslash "../../whatever/this.xsd."  At this point - the point of resolution - too much has been already resolved for me. :)  The only way I could fix that would be to work backwards to figure out how many ../..'s were removed for me, and put them back.  Not worth it.

Oleg has a great article up on his blog on how to Create your Own XmlResolver.  His actually retrieves the schema (stored) in a SQL Server. 

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Using the Server (rather than Workstation) Garbage Collector with the .NET Framework (CLR)

July 15, '04 Comments [2] Posted in ASP.NET | XML | Tools
Sponsored By

We run a big .NET Application Server, often on multi-proc machines, so we care about performance and, consequently, garbage collection.  I've collected a few resources around the two kinds of Garbage Collectors available in .NET, the Workstation GC and the Server GC.

From the MSDN Help:

Two different Garbage Collectors are available for the CLR: a Workstation GC and a Server GC. Console and Windows Forms applications host the Workstation GC, and ASP.NET hosts the Server GC. The Server GC is optimized for throughput and multi-processor scalability. The server GC pauses all threads running managed code for the entire duration of a collection, including both the Mark and Sweep Phases, and GC happens in parallel on all CPU's available to the process on dedicated high-priority CPU-affinitized threads. If threads are running native code during a GC then those threads are paused only when the native call returns. If you are building a server application that is going to run on multiprocessor machines then it is highly recommended that you use the Server GC. If your application in not hosted by ASP.NET, then you are going to have to write a native application that explicitly hosts the CLR.

HINT:   If you are building scalable server applications, host the Server GC. See Implement a Custom Common Language Runtime Host for Your Managed App.
  • Hosting the CLR in a generic service and Hosting the Server GC: "To load the svr GC, we created a generic Windows service that loads the svr GC, creates an AppDomain, and runs our application."
     CComPtr spRuntimeHost;
     HRESULT hr = CorBindToRuntimeEx(NULL, 
       //Retrieve latest version by default
      L"svr",
     
       //Request a Server (svr) or WorkStation (wks) build of the CLR
      STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN, 
      CLSID_CorRuntimeHost,
      IID_ICorRuntimeHost,
      (void**)&spRuntimeHost);
  • Using the Server Garbage Collector:  
    1. Create the system environment variable COMPLUS_BUILDFLAVOR to SVR
    2. SET COMPLUS_BUILDFLAVOR = SVR
    3. Generate this key in the windows registry: HKLM/Software/Microsoft/COMPlus with a single string value BuildFlavor with value "svr"
    SDH Note: This is fully unsupported my Microsoft.
  • Improvements in .NET 1.0 SP3 and .NET 1.1 SP1 and How to enable CLR Server GC?
     <Configuration>
        <runtime>
            <gcServer enabled=“true“ />
        </runtime>
    </Configuration> 

From Chris Kinsman: Here’s a way to do it that’s not a hack – right-click on My Computer in .NET Configuration in Administrative Tools. UPDATE: In fact, this is NOT so, details on this setting at OdeToCode.com

 

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.