[Mono-list] Thread 802600 has exited with leftover thread-specific data after 4 destructor iterations exception

Andrus Moor kobruleht2 at hot.ee
Mon May 18 14:14:03 EDT 2009


 Robert,

 Thank you very much for reply.

> It's a FreeBSD error message which occurs when a thread was dying.
> This makes me think that your stacktrace is not genuine:
>
>> System.ApplicationException: 0:0 Thread 802600 has exited with leftover
>> thread-specific data after 4 destructor iterations
>>   at csscript.CSExecutor.Compile (System.String scriptFileName) [0x00000]
>
> ... because "0:0 Thread 802600 has exited ..." is emitted by
> the FreeBSD kernel to the console.

 This is the stack trace.
 csscript.CSExecutor.Compile() source code inspection shows that it 
re-throws
 exceptions as ApplicationException in several places.
 Compile() method uses .NET 3.5 standard class to compile.
 So probably mono captures this kernel message somehow.

> Do you want an honest answer? Use a system supported by Novell ;)
> I really admire your inclination to exotic systems.

 I havent found any Linux/mod_mono ISP hosting provider in my country.
 So I'm forced to use FreeBSD/mod_mono ISP provider.

> But the solution is probably rather trivial: your script compiler
> is not able to find csc/mcs/gmcs to compile its stuff.

 If I call this web service repeatedly, sometimes it succeeds. So it
 certainly can compile scripts sometimes.
 Maybe this is some timing isse.
 How to fix it ?
 I included whole Compile() method code in the end of this message.

>> Assemblies are created in VWDExpress 2008 and are running under FreeBSD
>> with
>> mod_mono  + mono 2.4
>> How to enable line numbers in stack trace ?
>
> Add  `MonoDebug true' to your mod_mono config.

 This line is present in mod_mono.config.

 cat /usr/local/etc/apache2/Includes/mod_mono.conf

 # mod_mono.conf
 <IfModule !mod_mono.c>
    LoadModule mono_module /usr/local/libexec/apache2/mod_mono.so
 </IfModule>

 AddType application/x-asp-net .aspx
 AddType application/x-asp-net .asmx
 AddType application/x-asp-net .ashx
 AddType application/x-asp-net .asax
 AddType application/x-asp-net .ascx
 AddType application/x-asp-net .soap
 AddType application/x-asp-net .rem
 AddType application/x-asp-net .axd
 AddType application/x-asp-net .cs
 AddType application/x-asp-net .vb
 AddType application/x-asp-net .master
 AddType application/x-asp-net .sitemap
 AddType application/x-asp-net .resources
 AddType application/x-asp-net .skin
 AddType application/x-asp-net .browser
 AddType application/x-asp-net .webinfo
 AddType application/x-asp-net .resx
 AddType application/x-asp-net .licx
 AddType application/x-asp-net .csproj
 AddType application/x-asp-net .vbproj
 AddType application/x-asp-net .config
 AddType application/x-asp-net .Config
 AddType application/x-asp-net .dll
 DirectoryIndex index.aspx
 DirectoryIndex Default.aspx
 DirectoryIndex default.aspx

 MonoDebug true


 Andrus.

 Compile() method code:

 class CSExecutor
    {

        /// <summary>
        /// Compiles C# script file.
        /// </summary>
        private string Compile(string scriptFileName)
        {
            UniqueAssemblyLocations requestedRefAsms = new
UniqueAssemblyLocations();

            bool generateExe = options.buildExecutable;
            string scriptDir = Path.GetDirectoryName(scriptFileName);
            string assemblyFileName = "";
            string tempDir = Path.GetDirectoryName(GetScriptTempFile());

            //options may be uninitialized in case we are compiling from
CSScriptLibrary
            if (options.searchDirs.Length == 0)
                options.searchDirs = new string[] { scriptDir };

            //parse source file in order to find all referenced assemblies
            //ASSUMPTION: assembly name is the same as namespace + ".dll"
            //if script doesn't follow this assumption user will need to
            //specify assemblies explicitly
            ScriptParser parser = new ScriptParser(scriptFileName,
options.searchDirs);

            ICodeCompiler compiler;
            if (options.altCompiler == "")
            {
                IDictionary<string, string> providerOptions = new
Dictionary<string, string>();
                providerOptions["CompilerVersion"] = "v3.5";
                compiler = new
CSharpCodeProvider(providerOptions).CreateCompiler();
            }
            else
            {
                try
                {
                    //Assembly asm =
Assembly.LoadFrom(Path.IsPathRooted(options.altCompiler) ?
options.altCompiler :
Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),
options.altCompiler));
                    Assembly asm;
                    if (Path.IsPathRooted(options.altCompiler))
                    {
                        //absolut path
                        asm = Assembly.LoadFrom(options.altCompiler);
                    }
                    else
                    {
                        //look in the following folders
                        // 1. Executable location
                        // 2. Executable location + "Lib"
                        // 3. CSScriptLibrary.dll location
                        string probingDir =
Path.GetDirectoryName(Application.ExecutablePath);
                        string altCompilerFile = Path.Combine(probingDir,
options.altCompiler);
                        if (File.Exists(altCompilerFile))
                        {
                            asm = Assembly.LoadFrom(altCompilerFile);
                        }
                        else
                        {
                            probingDir = Path.Combine(probingDir, "Lib");
                            altCompilerFile = Path.Combine(probingDir,
options.altCompiler);
                            if (File.Exists(altCompilerFile))
                            {
                                asm = Assembly.LoadFrom(altCompilerFile);
                            }
                            else
                            {
                                //in case of CSScriptLibrary.dll "this" is
not defined in the main executable
                                probingDir =
Path.GetDirectoryName(this.GetType().Assembly.Location);
                                altCompilerFile = Path.Combine(probingDir,
options.altCompiler);
                                if (File.Exists(altCompilerFile))
                                {
                                    asm =
Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),
options.altCompiler));
                                }
                                else
                                    throw new ApplicationException("Cannot
find alternative compiler \"" + options.altCompiler + "\"");
                            }
                        }
                    }
                    Type[] types =
asm.GetModules()[0].FindTypes(Module.FilterTypeName, "CSSCodeProvider");
                    MethodInfo method =
types[0].GetMethod("CreateCompiler");
                    compiler = (ICodeCompiler)method.Invoke(null, new
object[] { scriptFileName });
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Cannot use alternative
compiler", ex);
                }
            }

            CompilerParameters compilerParams = new CompilerParameters();

            if (options.DBG)
                AddCompilerOptions(compilerParams, "/d:DEBUG /d:TRACE");

            if (options.compilerOptions != string.Empty)
                AddCompilerOptions(compilerParams, options.compilerOptions);

            compilerParams.IncludeDebugInformation = options.DBG;
            compilerParams.GenerateExecutable = generateExe;
            //compileParams.GenerateExecutable = true;
            compilerParams.GenerateInMemory = false;

            List<string> refAssemblies = new List<string>();
            if (options.shareHostRefAssemblies)
                foreach (Assembly asm in
AppDomain.CurrentDomain.GetAssemblies())
                {
                    try
                    {
                        if
(Myapp.Business.ScriptManager.IsScriptAssembly(asm))
                            continue;

                        requestedRefAsms.AddAssembly(asm.Location);
                    }
                    catch (NotSupportedException)
                    {
                        //under ASP.NET some assemblies doe not have
location (e.g. dynamivcally built/emitted assemblies)
                    }
                }

            //add assemblies were referenced from command line
            foreach (string asmName in options.refAssemblies)
            {
                string nameSpace = asmName;
                if (asmName.ToLower().EndsWith(".dll"))
                    nameSpace = asmName.Substring(0, asmName.Length - 4);

                foreach (string asm in
AssemblyResolver.FindAssembly(nameSpace, options.searchDirs))
                    requestedRefAsms.AddAssembly(asm);
            }

            AssemblyResolver.ignoreFileName =
Path.GetFileNameWithoutExtension(scriptFileName) + ".dll";

            //add local and global assemblies (if found) that have the same
assembly name as a namespace
            foreach (string nmSpace in parser.ReferencedNamespaces)
            {
                bool ignore = false; //user may nominate namespaces to be
excluded fro namespace-to-asm rosolving
                foreach (string ignoreNamespace in parser.IgnoreNamespaces)
                    if (ignoreNamespace == nmSpace)
                        ignore = true;

                if (!ignore)
                    foreach (string asm in
AssemblyResolver.FindAssembly(nmSpace, options.searchDirs))
                        requestedRefAsms.AddAssembly(asm);
            }

            //add assemblies referenced from code
            foreach (string asmName in parser.ReferencedAssemblies)
                if (asmName.StartsWith("\"") && asmName.EndsWith("\""))
//absolute path
                {
                    //not-searchable assemblies
                    string asm = asmName.Replace("\"", "");
                    requestedRefAsms.AddAssembly(asm);
                }
                else
                {
                    string nameSpace = asmName;
                    if (asmName.ToLower().EndsWith(".dll"))
                        nameSpace = asmName.Substring(0, asmName.Length -
4);

                    foreach (string asm in
AssemblyResolver.FindAssembly(nameSpace, options.searchDirs))
                        requestedRefAsms.AddAssembly(asm);
                }

            compilerParams.ReferencedAssemblies.AddRange((string[])requestedRefAsms);

            //add resources referenced from code
            foreach (string resFile in parser.ReferencedResources)
            {
                string file = null;
                foreach (string dir in options.searchDirs)
                {
                    file = Path.IsPathRooted(resFile) ?
Path.GetFullPath(resFile) : Path.Combine(dir, resFile);
                    if (File.Exists(file))
                        break;
                }

                if (file == null)
                    file = resFile;

                AddCompilerOptions(compilerParams, "\"/res:" + file + "\"");
//eg. /res:C:\\Scripting.Form1.resources";
            }


            if (options.forceOutputAssembly != "")
            {
                assemblyFileName = options.forceOutputAssembly;
            }
            else
            {
                if (generateExe)
                    assemblyFileName = Path.Combine(scriptDir,
Path.GetFileNameWithoutExtension(scriptFileName) + ".exe");
                else if (options.useCompiled || options.DLLExtension)
                {
                    if (options.DLLExtension)
                        assemblyFileName = Path.Combine(scriptDir,
Path.GetFileNameWithoutExtension(scriptFileName) + ".dll");
                    else if (options.hideTemp !=
Settings.HideOptions.DoNotHide)
                        assemblyFileName =
Path.Combine(CSExecutor.ScriptCacheDir, Path.GetFileName(scriptFileName) +
"c");
                    else
                        assemblyFileName = scriptFileName + "c";
                }
                else
                {
                    string tempFile = Path.GetTempFileName();
                    if (File.Exists(tempFile))
                        File.Delete(tempFile);
                    assemblyFileName = Path.Combine(tempDir,
Path.GetFileNameWithoutExtension(tempFile) + ".dll");
                }
            }

            if (generateExe && options.buildWinExecutable)
                AddCompilerOptions(compilerParams, "/target:winexe");

            if (File.Exists(assemblyFileName))
                File.Delete(assemblyFileName);

            compilerParams.OutputAssembly = assemblyFileName;

            CompilerResults results;
            if (generateExe)
            {
                results =
compiler.CompileAssemblyFromFileBatch(compilerParams,
parser.FilesToCompile);
            }
            else
            {
                string originalExtension =
Path.GetExtension(compilerParams.OutputAssembly);
                if (originalExtension != ".dll")
                {
                    //Despite the usage of .dll file name is not required
for MS C# compiler we need to do this because
                    //some compilers (Mono, VB) accept only dll or exe file
extensions.
                    compilerParams.OutputAssembly =
Path.ChangeExtension(compilerParams.OutputAssembly, ".dll");

                    if (File.Exists(compilerParams.OutputAssembly))
                        File.Delete(compilerParams.OutputAssembly);

                    results =
compiler.CompileAssemblyFromFileBatch(compilerParams,
parser.FilesToCompile);

                    if (File.Exists(compilerParams.OutputAssembly))
                    {
                        int attempts = 0;
                        while (true)
                        {
                            //There were reports of MS C# compiler (csc.exe)
not releasing OutputAssembly file
                            //after compilation finished. Thus wait a
little...
                            //BTW. on Mono 1.2.4 it happens all the time
                            try
                            {
                                attempts++;

                                File.Move(compilerParams.OutputAssembly,
Path.ChangeExtension(compilerParams.OutputAssembly, originalExtension));

                                break;
                            }
                            catch
                            {
                                if (attempts > 2)
                                {
                                    //yep we can get here as Mono 1.2.4 on
Windows never ever releases the assembly
                                    File.Copy(compilerParams.OutputAssembly,
Path.ChangeExtension(compilerParams.OutputAssembly, originalExtension),
true);
                                    break;
                                }
                                else
                                    Thread.Sleep(100);
                            }
                        }
                    }
                }
                else
                {
                    if (File.Exists(compilerParams.OutputAssembly))
                        File.Delete(compilerParams.OutputAssembly);
                    results =
compiler.CompileAssemblyFromFileBatch(compilerParams,
parser.FilesToCompile);
                }
            }

            if (results.Errors.Count != 0)
            {
                StringBuilder compileErr = new StringBuilder();
                foreach (CompilerError err in results.Errors)
                {
                    if (err.IsWarning && options.hideCompilerWarnings)
                        continue;
                    compileErr.AppendFormat(@"{0}:{1} {2}", err.Line,
err.Column, err.ErrorText);
                    compileErr.Append(Environment.NewLine);
                }
                throw new ApplicationException(compileErr.ToString());
            }
            else
            {
                if (!options.DBG) //.pdb and imported files might be needed
for the debugger
                {
                    parser.DeleteImportedFiles();
                    string pdbFile =
Path.Combine(Path.GetDirectoryName(assemblyFileName),
Path.GetFileNameWithoutExtension(assemblyFileName) + ".pdb");
                    if (File.Exists(pdbFile))
                        File.Delete(pdbFile);
                }

                if (options.useCompiled)
                {
                    if (options.useSmartCaching)
                    {
                        MetaDataItems depInfo = new MetaDataItems();

                        //save imported scripts info
                        depInfo.AddItems(parser.ImportedFiles, false,
options.searchDirs);

                        //save referenced local assemblies info
                        string[] newProbingDirs =
depInfo.AddItems(compilerParams.ReferencedAssemblies, true,
options.searchDirs);
                        foreach (string dir in newProbingDirs)
                            options.AddSearchDir(dir); //needed to be added
at Compilation for further resolving during the Invoking stage


                        depInfo.StampFile(assemblyFileName);
                    }

                    FileInfo scriptFile = new FileInfo(scriptFileName);
                    FileInfo asmFile = new FileInfo(assemblyFileName);

                    if (scriptFile != null && asmFile != null)
                    {
                        asmFile.LastWriteTimeUtc =
scriptFile.LastWriteTimeUtc;
                    }
                }
            }
            return assemblyFileName;
        }



More information about the Mono-list mailing list