Thursday, 27 October 2011

64 bits

I used to be a hardware freak back in time, with some good knowledge of processor architectures and so on. As time went on I preferred to focus just on programming, and at the same time, programming has been going higher and higher level to such extent that for most programming tasks coders do not need to be much aware of the details of the hardware on which their software runs.

That said, when this week we experienced some problems with an Asp.Net MVC application running on a 64 bits server failing to load a 32 bits COM component, I felt (as the rest of the team) a bit lost. Hopefully, this issue has turned into a rather fast and interesting learning experience.

First of all, some definitions:
  • IA32, x86-32, i386 or just x86 refer to the 32 bits architecture that was common on most computers until 3 years ago. Intel, AMD...
  • x86-64 is the 64 bits evolution of the former architecture. AMD, Intel...
  • IA64 has nothing with the above, it was a completely new 64 bits architecture developed by intel and that had little success.
  • WOW64 is the technology used by MS to run 32 bits applications on a 64 bit system (Operating System and Processor).
and some tips:
  • When on a 64 bits system, we can check whether a given Native process is 32 or 64 bits by launching ProcessExplorer and checking whether it has the wow64.dll loaded
  • We can check if a .dll is 32 or 64 bits by means of the binary dumper that comes with Visual Studio. Open the Visual Studio Command Prompt and type:
    dumpbin /headers myDll.dll |find "machine"
    you'll get: 14C machine (x32) 8664 machine (x64) My first idea was to check the 32-64 bits using the almighty PEBrowser, but oddly enough I couldn't find where to check this.
  • We can check under what option (x86, x64, Any CPU...) (more on this 2 paragraphs below) an assembly was compiled by using the corflags tool provided with the SDK

One of the first things I found is that you can't load a 32 bits dll in a 64 bits process. WOW64 only works at a whole process level, but not for independent dlls. I mean, if you're running a 64 bits process and you try to load a 32 bits dll there (or COM object) WOW64 won't get into play, you either compile the process to 32 bits or the dll to 64 bits, of course, if you don't have the source code, you're fucked.

Another interesting point, I used to think of .Net assemblies as unrelated to the processor details, just a bunch of bytecodes that get compiled to 32 or 64 native instructions by the JIT compiler, just as would happen with Python, Javascript or so... This is not completely true, and we get a hint if we notice that the CSC compiler allows us to compile our assemblies as x86, x64 or Any CPU... As explained here what those actions do is to indicate the JIT compiler how it should compile our bytecodes, 32 bits, 64 bits or "as the process on which I'm being loaded". The reason why we could need this level of control is because .Net allows us to go rather low level using unsafe code and calling into Native Code (PInvoke...).

That said, if you intend to use a 32 bits native dll from your .Net application, you'll need to compile your app with the x86 option. That means that if running on a 64 bits system the WOW64 system will be loaded and everything should be fine.

When working with Asp.Net there's something else you need to take into account. Your Web application (a bunch of dll's, not a .exe) gest hosted by the w3wp.exe process spawned by IIS. There's a w3wp.exe process for each IIS Application Pool (this means each application pool is independent from each other, thanks to that we can run Asp.Net 2, Asp.Net 4... apps on the same machine, they just need to run on different App Pools so that each pool loads the corresponding Framework version). By default, w3wp.exe is launched as a 64 bits process, so, how do I load my 32 bits assemblies + Native dll there?

Hopefully, the solution is damn easy, we just need to mark the Application Pool where we plan to load our Web Application as a 32 bits (IIS -> Advanced Properties of the Application Pool -> set Enable 32 bits applications to true)

3 comments:

  1. Hello: first of all, I'd like to point out that I am an outsider I guess... What I mean is that I am not a software developer, I don't know anything about programming and yet I am interested in all this sort of stuff and I find this blog interesting. I guess I'm just a freak.
    It is possible you find my question too naive (so to say: too silly) to fit this blog, in which case I will accept it can not even be shown as a comment. But in case you don't, here it is the question:
    Which programming language would you recommend for a beginner to learn? I mean: no formal education at all (I'm too old and busy for that) but non-formal education.

    Regards¡

    ReplyDelete
  2. Hi Anonymous.
    Thanks for your comment/question, it's really welcome.
    I would say the best language now for learning is JavaScript.
    One can start to work with it in a rather basic form, just using functions, and overtime start to use more advanced concepts.
    You can install Firefox and the Firebug extension, go to the console and start to try things there, but I would recommend learning a bit of html so that you can add some JavaScript to it and start to understand how some of "the magic" on the Web happens.
    Go to:
    http://www.w3schools.com/
    and try the Learn Html, Learn CSS and Learn JavaScript tutorials on the left.
    Happy programming!

    ReplyDelete
  3. Thanks for your answear, I will¡

    ReplyDelete