delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2012/03/12/15:51:31

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=0.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_WEB,SPF_HELO_PASS
X-Spam-Check-By: sourceware.org
From: "James Johnston" <JamesJ AT motionview3d DOT com>
To: <cygwin AT cygwin DOT com>
Subject: Re: 1.7.10/1.7.11: .Net programs started from a cygwin console may fail.
Date: Mon, 12 Mar 2012 19:51:03 -0000
Message-ID: <00d601cd0089$75fce540$61f6afc0$@motionview3d.com>
MIME-Version: 1.0
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id q2CJpRck024136

I have also noticed this issue; again it was with the XML serialization functions like Andres Martinelli originally noted.  The root of the problem is that Windows environment variables are not case sensitive, while they *are* in a Unix environment.  Cygwin passes an environment block with duplicate identically-named variables (if case insensitive; unique if case sensitive), and this will make some Windows programs go boom, because they assume the block is maintained in a case-insensitive manner.

Here's a full stack trace:

Unhandled Exception: System.ArgumentException: Item has already been added. Key in dictionary: 'tmp'  Key being added: 'tmp'
   <cut>
   at System.Collections.Specialized.StringDictionary.Add(String key, String value)
   at System.CodeDom.Compiler.Executor.ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, String cmd, String currentDir, TempFileCollection tempFiles, String& outputName, String& errorName, String trueCmdLine)
   <cut>
   at Microsoft.CSharp.CSharpCodeGenerator.Compile(CompilerParameters options, String compilerDirectory, String compilerExe, String arguments, String& outputFile, Int32& nativeReturnValue, String trueArgs)
   <cut>
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)

You can see that the XML serializer needs to invoke the C# compiler to dynamically compile some code.  The compiler needs to place all environment variables in a case-insensitive dictionary (since that's how things are done on Windows!).  Decompiling System.CodeDom.Compiler.Executor.ExecWaitWithCaptureUnimpersonated gives this:

        StringDictionary sd = new StringDictionary();
        foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
        {
            sd.Add((string) entry.Key, (string) entry.Value);
        }

Note that StringDictionary is case insensitive, according to the docs: "The key is handled in a case-insensitive manner; it is translated to lowercase before it is used with the string dictionary."  So that's why it crashes.

The big problem as I see it is that Cygwin, out-of-the-box, creates an environment block that violates a basic assumption of Windows programs - that the environment block is not case sensitive.  I don't know what the solution should be, but it's not this.

From /etc/profile:

tmp=$(cygpath -w "$ORIGINAL_TMP" 2> /dev/null)
temp=$(cygpath -w "$ORIGINAL_TEMP" 2> /dev/null)
TMP="/tmp"
TEMP="/tmp"

This code is what causes the crash, by creating these "duplicate" (from a Windows perspective) keys.

I would guess that any Windows program that tries to do case-insensitive lookups in the environment is liable to crash.  At the very least, it won't necessarily give you the answer you expect (if both "TEMP" and "temp" store different values and you do a case insensitive lookup of "TeMp", which is going to be returned if you don't crash?)

James

--- Original message ---

Hi Cygwin, 

Many .Net programs that use to run correctly from a cygwin 1.7.9 console 
started throwing exceptions after updating to versions 1.7.10/1.7.11. I 
have noticed this problem on machines running Windows XP and Vista (32bits). 

I attach a very small example that triggers the bug. The example is 
written in C#, and requires the .Net framework versions 2.0 or 3.5. 

How to reproduce: 

1) Compile the example with 
         csc bug.cs 

     The c# compiler (csc), can be usually found in 
         C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe 
     or C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe 

2) Run the resulting bug.exe from a cygwin 1.7.10/1.7.11 console. It 
throws an exception. 

3) Run bug.exe from a native windows console (or a cygwin 1.7.9 
console). It runs without producing any output, and without throwing any 
exceptions. 

Be aware that the bug is not triggered if the example is compiled with 
the .Net framework 4.0. 

Best regards, 
Andrés Martinelli 


using System.Xml; 
using System.Xml.Schema; 
using System.Xml.Serialization; 

class Program { 
  static void Main(string[] args) { 
    XmlSerializer serializer = new XmlSerializer(typeof(Simple)); 
  } 
} 

public class Simple : IXmlSerializable { 
  #region IXmlSerializable Members 
  public XmlSchema GetSchema() { return null; } 
  public void ReadXml(XmlReader reader) { } 
  public void WriteXml(XmlWriter writer) { } 
  #endregion 
}


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019