[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