Where exactly is .NET Runtime (CLR), JIT Compiler located? - c#

This question might look a bit foolish or odd but I have heard a lot of about .NET CLR, JIT compiler and how it works blah blah blah... But now I am wondering where exactly it is located or hosted.
Is it -
Hosted as a part of Windows Operating system when we actually install .NET Framework?
OR
It is a part of some .exe which we can see in task manager
I am looking for the detailed answer on this. Someone might frame this question as "How Windows Operating System triggers/executes .NET Executable inside .NET Runtime?

where exactly it is located or hosted
It is just a plain DLL, you'll find back the x86 version of it in C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll. The x64 version is in the Framework64 directory. The .NET v2 version had a different name, mscorjit.dll, find it back in the v2.0.50727 directories.
It is not "hosted" at all, the operating system is completely unaware that it exists. The CLR knows how to locate and load it. Necessarily so, it is the CLR that decides when to start a program. It simply has the DLL name hard-coded and use LoadLibrary("clrjit.dll") to load it, GetProcAddress("getJit") to get the factory function. Something you can see back in the CoreCLR source code, albeit that the jitter is not a separate DLL anymore in that CLR version.
You can see the CLR with Explorer as well, again just a plain DLL. It is clr.dll in the v4 versions, mscorwks.dll and mscorsvc.dll in the v2 versions. Two different ones back then with different garbage collectors, "wks" is the workstation version, "svc" is the server version. Compare to the <gcServer> config file entry.
Which moves the question to "how does the CLR get loaded?" That's the job of c:\windows\syswow64\mscoree.dll, you'll use c:\windows\system32\mscoree.dll when you target x64 in your EXE project. Every .NET assembly has 5 or 9 bytes of unmanaged code, a jump into that DLL. Either _CorExeMain or _CorDllMain, depending on whether the assembly was built as an exe or a library. mscoree.dll takes a look at the metadata in the assembly and decides what version of the CLR needs to loaded so it can be properly executed.
Lots more shenanigans going on, I just posted the 10,000 feet view you asked for. If this interests you then you probably want to find out more about custom CLR hosting to see the man behind the curtain.

How Windows Operating System triggers/executes .NET Executable Runs
inside .NET Runtime?
Every .NET managed assembly or executable has special CLR headers, which you can see by viewing the assembly in ILDASM. This headers points to the version of the runtime that needs to be loaded. Also, there is the Image Section with the Import Address Table, pointing to what needs to be loaded:
----- Image sections:
Import Address Table
DLL : mscoree.dll
0x00002000 Import Address Table
0x0000a37e Import Name Table
0 Time Date Stamp
0 Index of First Forwarder Reference
0x0000 _CorDllMain
----- CLR Header:
Header size: 0x00000048
Major runtime version: 0x0002
Minor runtime version: 0x0005
0x00003184 [0x00007078] address [size] of Metadata Directory:
Flags: 0x00000001
Entry point token: 0x00000000
0x00000000 [0x00000000] address [size] of Resources Directory:
0x00000000 [0x00000000] address [size] of Strong Name Signature:
0x00000000 [0x00000000] address [size] of CodeManager Table:
0x00000000 [0x00000000] address [size] of VTableFixups Directory:
0x00000000 [0x00000000] address [size] of Export Address Table:
0x00000000 [0x00000000] address [size] of Precompile Header:
When ran by the operating system, mscoree.dll (or The Shim) is loaded, and it is the bootstrapper to clr.dll and clrjit.dll for .NET 4.0 and above, or mscordacwks.dll and mscorjit.dll for .NET 2.0 or below, which are the runtime and the JIT, respectively. You can see that the native dll entry point is instructed to be the _CorDllMain method for a class library, and _CorExeMain for an executable, which is responsible for the loading and jitting of the entry point. They, in turn, will call your applications entry point, in the managed environment.

This is based upon my understanding and will guide you towards you answer, but may not be fully flushed out.
The EXE/DLL files that make up the DotNet Runtime (CLR, etc.) are located in the following locations:
C:\Windows\Microsoft.NET\Framework // for the 32 bit runtime
C:\Windows\Microsoft.NET\Framework64 // for the 64 bit runtime
Within there, you have the different editions such as 2.0.50727, 3.0, 3.5, and 4.0.30319 (versions on my system today).
This is where MSBuild, as well as the files that are registered with IIS are located and run from.
I don't know if this ends up being hosted by Windows at runtime, or if there is an actual EXE you could attach to with a debugger and see in the task manager.
Hopefully this provides some more insight for you.

Related

assembly load error on C# exe which has been modified to export a variable

Working on a C# .NET application for Windows Desktop which does 3D rendering. On laptops with dual video card configs (integrated Intel video and NVidia for example), the problem can arise that the user has not changed the NVidia control panel setting to prefer the NVidia card. As a result the app may pick the integrated video and perform poorly.
Were this unmanaged code, one could do the below to export an integer from the main exe and apparently the NVidia software will detect this and then force the app to run with the NVidia card without the user having to change the control panel setting (requiring them to do this isn't realistic and it results in a bad first impression of application performance).
extern "C" {
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
In order to do the above with a .NET C# executable (it has to be the main exe not a DLL apparently), I'm attempting to use the approach outlined at the below link.
http://lucasmagder.com/blog/2014/05/exporting-data-symbols-in-c-for-nvidia-optimus/
The approach there is to, in post-build, dissassemble the .exe, then modify the IL, inserting the below at the start of a dummy method and then re-assemble the modified IL creating a new exe.
.export [0] as NvOptimusEnablement
Then at runtime there's some more stuff it does to get the value set. But, the issue is that when we try and run we get the following error from assembly loading.
Could not load file or assembly '...' or one of its dependencies. Attempt to load an unverified executable with fixups (IAT with more than 2 sections or a TLS section.) (Exception from HRESULT: 0x80131019
Searching on this error suggests that this is caused by a managed assembly which also contains unmanaged code, which is of course exactly what we're trying to do (Exception with Resolving assemblies: Attempt to load an unverifiable executable with fixups).
Anyone else have experience with this? I'm guessing back when that workaround was created this all worked, but maybe the assembly loading is more strict now? Anyonw know of a workaround?

Could not load file or assembly (custom dll) - works for console but fails for web project (ASP.NET MVC 5) [duplicate]

I have this dll that I created a long time ago and use to connect to the db of a specific software that I develop for. I have had no issues for well over 4 years and countless applications with this dll.
Trying to deploy my latest creation, I get the following error:
System.IO.FileNotFoundException: Could not load file or assembly '***.dll' or one of its dependencies. The specified module could not be found.
So, for every dll I ever wrote, I always made a simple forms application to test that dll just by itself. Running that simple app yielded the same error. The dll doesn't load or use anything else than: System, System.Data, System.XML. So as far as depencies of it go, I don't see anything wrong.
By the way everything works on a dev station. The problem is limited to deployment stations. .Net and the necessary redistributables, since I do everything in C++, are deployed and working.
Running FUSLOGVW.exe showed everything as working fine.
Running depends.exe said: Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
I already tried rewriting the whole thing. Which yielded the same results.
Clues anyone?
EDITS
Here is the total error message:
See the end of this message for details on invoking \"
just-in-time (JIT) debugging instead of this dialog box.\"
************** Exception Text **************\"
System.IO.FileNotFoundException: Could not load file or assembly 'connectionTo.dll' or one of its dependencies. The specified module could not be found.\"
File name: 'connectionToJobboss32.dll'\"
at TESTConnection.Form1.button1_Click(Object sender, EventArgs e)\"
at System.Windows.Forms.Control.OnClick(EventArgs e)\"
at System.Windows.Forms.Button.OnClick(EventArgs e)\"
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)\"
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)\"
at System.Windows.Forms.Control.WndProc(Message& m)\"
at System.Windows.Forms.ButtonBase.WndProc(Message& m)\"
at System.Windows.Forms.Button.WndProc(Message& m)\"
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)\"
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)\"
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\"
\"
************** Loaded Assemblies **************\"
mscorlib\"
Assembly Version: 4.0.0.0\"
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)\"
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll\"
----------------------------------------\"
TESTConnection\"
Assembly Version: 1.0.3996.18980\"
Win32 Version: \"
CodeBase: file:///C:/Program%20Files%20(x86)/conn/TESTConnection.exe\"
----------------------------------------\"
System.Windows.Forms\"
Assembly Version: 4.0.0.0\"
Win32 Version: 4.0.30319.1 built by: RTMRel\"
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll\"
----------------------------------------\"
System.Drawing\"
Assembly Version: 4.0.0.0\"
Win32 Version: 4.0.30319.1 built by: RTMRel\"
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll\"
----------------------------------------\"
System\"
Assembly Version: 4.0.0.0\"
Win32 Version: 4.0.30319.1 built by: RTMRel\"
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll\"
----------------------------------------\"
There is no errors in the event viewer.
or one of its dependencies
That's the usual problem, you cannot see a missing unmanaged DLL with Fuslogvw.exe. Best thing to do is to run SysInternals' ProcMon utility. You'll see it searching for the DLL and not find it. Profile mode in Dependency Walker can show it too.
I had the same issue with a dll yesterday and all it referenced was System, System.Data, and System.Xml. Turns out the build configuration for the Platform type didn't line up. The dll was build for x86 and the program using it was "Any CPU" and since I am running a x64 machine, it ran the program as x64 and had issues with the x86 dll. I don't know if this is your issue or not, just thought that I would mention it as something else to check.
I recently hit this issue, the app would run fine on the developer machines and select others machines but not on recently installed machines. It turned out that the machines it did work on had the Visual C++ 11 Runtime installed while the freshly installed machines didn't. Adding the Visual C++ 11 Runtime redistributable to the app installer fixed the issue...
I had the same problem. For me, it was caused by the default settings in the local IIS server on my machine. So the easy way to fix it, was to use the built in Visual Studio development server instead :)
Newer IIS versions on x64 machines have a setting that doesn't allow 32 bit applications to run by default. To enable 32 bit applications in the local IIS, select the relevant application pool in IIS manager, click "Advanced settings", and change "Enable 32-Bit Applications" from False to True
I ran into this recently. It turned out that the old DLL was compiled with a previous version (Visual Studio 2008) and was referencing that version of the dynamic runtime libraries. I was trying to run it on a system that only had .NET 4.0 on it and I'd never installed any dynamic runtime libraries. The solution? I recompiled the DLL to link the static runtime libraries.
Check your application error log in Event Viewer (EVENTVWR.EXE). It will give you more information on the error and will probably point you at the real cause of the problem.
This answer is totally unrelated to the OP's situation, and is a very unlikely scenario for anyone else too, but just in case it may help someone ...
In my case I was getting "Could not load file or assembly 'System.Windows.Forms, Version=4.0.0.0 ..." because I had disassembled and reassembled the program using ILDAsm.exe and ILAsm.exe from .Net Framework / SDK version 2. Switching to ILDAsm.exe and ILAsm.exe from .Net Framework / SDK version 4 fixed the problem.
(Strangely, even though doing what I did may seem like an obvious error, the resulting EXE file that didn't work did indicate that it targeted .Net 4 when examined with JetBrains dotPeek.)
I had the same issue - a .dll working all the time, then my computer crashed and afterwards I had this problem of 'could not load file or assembly ....dll'
Two possible solutions: when the computer crashed there may be some inconsistent files in
C:\Users\<yourUserName>\AppData\Local\Temp\Temporary ASP.NET Files
Deleting that folder, recompiling and the error was gone.
Once I had also to delete my packages folder (I had read that somewhere else). Allow Visual Studio / nuget to install missing packages (or manually reinstall) and afterwards everything was fine again.
An easier way to determine what dependencies a native DLL has is to use Dependency Walker - http://www.dependencywalker.com/
I analysed the native DLL and discovered that it depended on MSVCR120.DLL and MSVCP120.DLL, both of which were not installed on my staging server in the System32 directory. I installed the C++ runtime on my staging server and the issue was resolved.
Had the same issue and got it resolved by making sure projects in the solution have the same configuration and platform (in my case it was Debug x64). Somehow the VIsual Studio was missing x64 for part of the projects and I edited the .sln file manually (copied the configurations and platforms from correctly built projects to the projects that were missing the settings I needed). This is what it looks like for one of the projects:
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Debug|x64.ActiveCfg = Debug|x64
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Debug|x64.Build.0 = Debug|x64
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Release|Any CPU.Build.0 = Release|Any CPU
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Release|x64.ActiveCfg = Release|x64
{1BA29980-EE5D-4476-AFFC-0F177B6C9865}.Release|x64.Build.0 = Release|x64
But then the same error occurred for a project that had a Java file (*.jar) in the dependencies. I had to edit Environment Variables manually to create a record with this value
C:\Program Files\Java\jre1.8.0_171\bin\server
for Java's path, and put it on top of the Path items.
This fixed the issue until I updated Java on my machine. I had to edit the version number in Environment Variables to match the updated folder name.
C:\Program Files\Java\jre1.8.0_181\bin\server
1) Copy DLLs from "Externals\ffmpeg\bin" to your project's output directory (where executable stays);
2) Make sure your project is built for x86 target (runs in 32-bit mode).
Follow this thread for more

Debugging 32 bit application running in 64 bit environment

I have a 32 bit .Net 4.0 application running in a wow64 environment in a 64 bit machine.
The application encountered an error and I took a dump with 32 bit taskmanager present in C:\Windows\SysWOW64\taskmgr.exe
I am using a 32 bit Windebugger to analyze this dump. I loaded the following dlls.
1).loadby sos CLR
2).load mscordacwks ( from the client machine).
But still I am not able to use SOS commands like !clrstack,!threads etc.
I get the error:
Failed to load data access DLL, 0x80004005
What did I do wrong?
Seems that mscordacwks is not correctly loaded
One way
Try:
.cordll -u -ve -lp <absolute-path-to-directory-where-client-mscordacwks-is-placed>
The correct output should be:
CLRDLL: Loaded DLL <your-path>\mscordacwks.dll
CLR DLL status: Loaded DLL <your-path>\mscordacwks.dll
If you see:
CLR DLL status: No load attempts
rename your mscordacwks to the name suggested by .cordll:
0:000> .cordll
CLR DLL status: ERROR: Unable to load DLL mscordacwks_x86_x86_2.0.50727.3625.dll, Win32 error 0n87
and add the path where renamed mscordacwks resides to symbols:
.sympath+ <your-path>
and try your SOS command.
Other way
Get procdumpext.dll from Andrew Richard's skydrive : http://sdrv.ms/11C7S9c, load it into windbg (.load procdumpext.dll) and execute !loadsos.
Good luck! :)
I had the best results in case I didn't only get mscordacwks.dll but also sos.dll from the client machine. I even had SxS issues with those files, so getting the files from the default .NET framework directory was not helpful either. Therefore I created the mscordacwks collector which gets all possible files for you.
However, you still need to find out which version to use. You can start by looking at the .NET framework version:
lm vm clr; *** .NET CLR 4
lm vm mscorwks; *** .NET CLR 2
lm vm coreclr; *** Silverlight
(In worst case, you have two different version of .NET loaded, in which case you are out of luck).
Once you know the exact version, you can load SOS of that version by full path
.load c:\mypath\SOS_AMD64_AMD64_4.0.30319.18444.dll
Note that the collected versions of SOS.dll will also be renamed to avoid file name conflicts. For more convenience, you can create a copy and just rename it to SOS.dll.
If there are still any mscordacwks.dll issues, you can proceed as proposed by #lowleveldesign. The tool should already have renamed data access files appropriately. If you find any bug, feedback is welcome.

BadImageFormat Exception at Microsoft.CSharp library

I'm having little problem running my C# application after switching to Windows 8.1 from 8.
The problem is that I get this exception from title and there's not much help online. I tried to pinpoint the problem and it seems like my x64 application is trying to call x86 CSharp library. The reference in project leads to a DLL file, that upon calling x64 dumpbin program with /headers parameter outputs:
Dump of file Microsoft.CSharp.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
3 number of sections
4FFA5C64 time date stamp Mon Jul 09 06:21:56 2012
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2022 characteristics
Executable
Application can handle large (>2GB) addresses
DLL
Notice the machine is x86, while the application is running in x64 (checked with Environment.Is64BitProcess). This might be the problem I'm facing, however I can't find way to solve it - there seems to be no x64 .Net libraries installed. The only ones I have found are at: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework. Or maybe I'm completely off and there's some other problem. Anyway the exception occurs at startup in one of constructors and full detail is:
Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
"Could not load file or assembly 'Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The module was expected to contain an assembly manifest."
Edit:
While still panicking, I solved this by downloading CSharp.dll and replacing the dummy 0-byte file in path shown in answer by it.
The module was expected to contain an assembly manifest
You've been looking at a reference assembly, it is not the one that's actually loaded when you run your program. Microsoft.CSharp.dll is stored in the GAC, put there by the .NET installer. You can see the file by navigating to c:\windows\microsoft.net\assembly\gac_msil\microsoft.csharp. Keep clicking until you get to the file.
The exception message is a very unhealthy one, it doesn't recognize the DLL as a .NET assembly. There are few decent explanations for that, other than the file being corrupted. File corruption is always bad news, a strong hint that your hard-disk is failing. You'll need to get it fixed, follow-up if necessary at superuser.com

How can I get the processor architecture of an assembly dll? [duplicate]

This question already has answers here:
How to check programmatically whether a managed assembly is x86, x64 or AnyCPU?
(2 answers)
Closed 4 years ago.
Can I get the processor architecture by loading the dll programmatically in c#?
Is there a class that can do this?
I need to get wether the dll is x86, x64, MSIL etc..
Assuming you are only looking at .net assemblies, you can use CorFlags.exe for look at the header of the image.
This blog post explains the usage to determing how to read the results. Excerpt:
Usage: Corflags.exe Assembly [options]
If no options are specified, the flags for the given image are displayed.
...
Here is what each component of the header means:
Version: Contains the version of .NET Redist with which the binary is
built.
CLR Header: 2.0 indicates a .Net 1.0 or .Net 1.1 (Everett) image while 2.5 indicates a .Net 2.0 (Whidbey) image.
CorFlags: This is computed by OR’g specific flags to indicate whether the
image is ILONLY, its bitness etc. and
is used by the loader. ILONLY: Managed
images are allowed to contain native
code. To be “anycpu” an image shall
only contain IL.
32BIT: Even if you have an image that only contains IL it still might
have platform dependencies, the 32BIT
flag is used to distinguish “x86”
images from “anycpu” images. 64-bit
images are distinguished by the fact
that they have a PE type of PE32+.
The most interesting aspect is the PE and the 32BIT flag of the header.
These combine to specify the assembly
types. Here is how they would look
like for:
anycpu: PE = PE32 and 32BIT = 0
x86: PE = PE32 and 32BIT = 1
64-bit: PE = PE32+ and 32BIT = 0
Trying to find out by loading the assembly is a chicken-and-egg proposition. If you don't get a BadImageFormatException then the arch is appropriate and you no longer care what it is. If you do get the exception then the program's configuration is wrong. Nothing you can do about that in code.
You can also read the assembly file using a FileStream. The format of windows executable files is specified in the Microsoft pe/coff spec. You can read it here:
http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx

Categories