Angel Hernández

June 2009 - Posts

Memory Mapped Files

Writing code nowadays can be considered as a "cheerful experience", we have a complete set of tools and development environments that make us more productive, helping us in the delivery of high-quality software. 15 years ago it was a hard task to find IDEs with Intellisense support, we used to store our application settings in .INI files and we didn't even have any virtualization environment in order to perform tests before sending out our solution to the customers, that's why it's a new adventure each time we got engaged on a new development project and coding hasn't ever been as enjoyable as it is today. A few years ago I read a book written by Jeffrey Richter called "Advanced Windows" and I learned heaps from this book, as a matter of fact, last year I bought his latest book called "Windows via C/C++" which is a classic and a must have in every Windows developer toolbox, same thing occurs with Charles Petzold's book, however I learned a lot about Windows internal mechanisms by reading Richter's, for instance, how can processes exchange information between them? What's the difference between a Mutex and a Semaphore for threads synchronization? just to mention a few. Windows is a product that has evolved and grown throughout the years, despite of new APIs and functionality that have been included into it we will always need access to the PC's memory, for example we can mention Inter-Process Communication (IPC) and virtual memory access, this post is about it pretty much, how can I get access to the virtual memory so I can address and use a given amount of bytes? I think you know already what I'm talking about. Memory Mapped Files can be defined as "a segment of virtual memory which has been assigned a direct byte-for-byte correlation with some portion of a file or file-like resource. This resource is typically a file that is physically present on-disk, but can also be a device, shared memory object or other resource that the operating system can reference through a file descriptor". They have three main purposes which are:

  • Load and execute .exe files and DLLs
  • Access files on-disk very quickly without using buffers. Windows handles this for us
  • Allow many processes to share information in memory

The following diagram depicts some implementations for memory mapped files

 clip_image002

Once the file is mapped in memory, a view based on that file needs to be created, I mean, a region or space within the file which allows a process to read and write onto it, when creating the view we specify bytes to be mapped, file offset and desired access, this process is shown in the image below

 image

One of the new features bundled in .NET Framework 4.0 besides DLR (Dynamic Language Runtime), parallel processing and support for memory mapped files. The code that accompanies this post demonstrates how to do it using the new MemoryMappedFile class plus my own implementation with .NET 3.5, C# and a little of Interop.

Further reading about this topic can be found at  Virtual Memory and Paging

Regards,

Angel

Format: swf
Duration: 22 min

Archivos Mapeados en Memoria

Hoy en día es ameno “echar código”, pues tenemos herramientas de desarrollo que nos ayudan a ser productivos y aseguramos la calidad del software que hacemos. Hace 15 años atrás era difícil encontrar entornos de desarrollo con Intellisense, guardábamos nuestra configuración en archivos .INI y no disponíamos de virtualización para probar nuestra aplicación antes de enviarla al cliente, por eso en la actualidad cada día es una aventura y programar es más divertido. Hace unos años atrás leí un libro escrito por Jeffrey Richter titulado “Programación avanzada para Windows 95/NT”, aprendí mucho de ese libro  de hecho el año pasado me compré la última edición del mismo titulado “Windows via C/C++”, es un clásico como el libro de Charles Petzold, sin embargo con el libro de Richter aprendí cosas sobre el funcionamiento interno del Sistema Operativo, por ejemplo, ¿cómo los procesos pueden intercambiar información entre sí?, ¿cuál es la diferencia entre un Mutex y un semáforo para sincronizar hilos? y muchas otras cosas más. Windows es un producto que ha madurado y crecido con el paso de los años, a pesar de nuevas APIs y funcionalidad siempre tendremos que tener acceso a la memoria del PC, un ejemplo de esto es la comunicación entre procesos (IPC) y el acceso a la memoria virtual, el siguiente post trata de eso, ¿cómo utilizar la memoria virtual para así direccionar y/o utilizar una cantidad de memoria que yo desee? Me imagino, ya saben a lo que me refiero y es Archivos mapeados en memoria (Memory Mapped Files) que lo podríamos definir como “un segmento de la memoria virtual la cual se le ha asignado una correlación directa byte a byte con alguna porción de un archivo ó algún otro recurso, el cuál típicamente es un archivo en disco pero también puede ser un dispositivo, un objeto compartido de memoria u otro recurso que el sistema operativo pueda referenciar a través de un descriptor de archivo”. Los archivos mapeados en memoria tienen tres propósitos los cuales son:

  • Cargar y ejecutar archivos .exe y bibliotecas de enlace dinámico (DLL)
  • Accesar archivos en disco rápidamente sin necesidad de usar búferes, Windows se encarga de esto por nosotros
  • Permitir a varios procesos compartir la misma información en memoria

El siguiente diagrama muestra alguna de las implementaciones para los archivos mapeados en memoria

 clip_image002

Una vez que el archivo se encuentra mapeado en memoria, es necesario crear una vista basada en el mismo, es decir, una región ó espacio dentro del archivo a la cuál un proceso puede leer y escribir, al momento de crear la vista se especifica desde donde se va a comenzar a manipular el archivo así como el número de bytes a utilizar, este proceso lo podemos ver en la imagen mostrada a continuación

 image

Una de las características nuevas que trae consigo el .NET Framework 4.0 además de DLR (Dynamic Language Runtime), procesamiento paralelo y muchas otras más, es el soporte para archivos mapeados en memoria, el código de este posting demuestra como hacerlo con la nueva clase MemoryMappedFile así como mi propia implementación con .NET 3.5, C# y un poco de Interop.

Si deseas leer un poco más sobre este tema puedes revisar estos links en Wikipedia: Memoria Virtual y Paginación de Memoria

Saludos,

Angel

Format: swf
Duration: 38 Min

Extending the Exception class, getting Win32 error messages plus extension methods

Structured Exception Handling (SEH), it’s one of the top used features by developers, it’s not required any more to be dealing with On Error labels or any other less elegant mechanism to handle error conditions, however .NET Framework is an existing layer between our application and the operating system, even when the Exception class describes an error condition it doesn’t provide the error code and message associated to the operating system, that’s why it’s frustrating sometimes to interpret some “less-descriptive” exceptions and hence recovering any Windows error information can be of great help. Throughout the years Windows API has evolved and grown in size and error messages as well, many of these messages can be found in the SDK and WDK, so I had this idea about extending the Exception class by implementing an extension method. Extension methods enable us to “add” methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. They are a special kind of static method, but they are called as if they were instance methods on the extended type. The most common extension methods are  the LINQ standard query operators that add query functionality to the existing IEnumerable and IEnumerable<T>. 

To retrieve the description for a given error code we use the FormatMessage function, as it’s shown below 

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true,
           CallingConvention = CallingConvention.Winapi)]
public static extern int FormatMessage(int dwFlags, int lpSource, int dwMessageId,
                     int dwLanguageId, out StringBuilder lpBuffer,
                       int nSize, IntPtr va_list);

The extension method used is the following

    public static class ExceptionExtension {
    /// <summary>
    /// Gets the win32 error description.
    /// </summary>
    /// <param name="ex">The ex.</param>
    /// <returns></returns>
    public static Win32Error GetWin32ErrorDescription(this Exception ex) {
        Win32Error retval = Win32Error.Empty;
        StringBuilder pMsgBuf = new StringBuilder();
 
        int lastError = FormatErrorHelper.GetLastError();
 
        FormatErrorHelper.FormatMessage(
               FormatErrorHelper.FORMAT_MESSAGE_ALLOCATE_BUFFER |
               FormatErrorHelper.FORMAT_MESSAGE_FROM_SYSTEM,
               FormatErrorHelper.NULL,   lastError, 
               FormatErrorHelper.MakeLangID(FormatErrorHelper.LANG_NEUTRAL,
               FormatErrorHelper.SUBLANG_DEFAULT), out pMsgBuf, 0, IntPtr.Zero);
 
         retval.ErrorCode = lastError;
         retval.Description = pMsgBuf != null ? pMsgBuf.ToString() : string.Empty;
 
         return retval;
      }
}

So if we catch any exception, besides obtaining the exception object itself we get the error and message code from the operating system

Win32Error osError = Win32Error.Empty;
 
try {
// Some funky exception here...
} catch(Exception ex) {
  osError = ex.GetWin32ErrorDescription();
  Console.WriteLine(string.Format("Code: {0} - Description: {1}", 
            new object[] {osError.ErrorCode, osError.Description}));  
}

If we implement everything we’ve previously mentioned, see the difference between the exception message and the message provided by the operating system

image_thumb[2]

Hope this helps,

Regards,

Angel

Extendiendo la clase Exception, recuperando mensajes de error de Win32 además de los métodos de extensión

El manejo estructurado de excepciones, es una de las características que como desarrolladores utilizamos más a menudo, ya no es necesario estar implementando etiquetas On Error u otro mecanismo poco elegante para manejar condiciones de error, sin embargo el .NET Framework es una capa entre el sistema operativo y nuestra aplicación, aunque la clase Exception describe una condición de error, carece del código de error y descripción asociado al sistema operativo, en muchas ocasiones el interpretar algunas excepciones puede llegar en cierto punto ser algo frustrante porque no es muy descriptivo, por lo que no sería mala idea recuperar la información de error emitida por Windows. Con el paso de los años, el API de Windows ha crecido y así mismo la cantidad de mensajes de error subyacentes, en el SDK de la plataforma se consigue información sobre estos mensajes de error y lo mismo sucede con el WDK, por lo que se me ocurrió la idea de extender la clase Exception a través de un método de extensión. Los métodos de extensión, nos permiten “agregar “métodos a tipos de datos existentes sin la necesidad de crear un tipo derivado, recompilar ó modificar el tipo original. Estos métodos son un tipo especial de método estático que son llamados como si fueran métodos de instancia en el tipo extendido. Su uso más común es con LINQ para así conseguir funcionalidad adicional de los tipos IEnumerable e IEnumerable<T>.

Para recuperar la descripción de un código de error utilizamos la función FormatMessage, como mostramos a continuación

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true,
           CallingConvention = CallingConvention.Winapi)]
public static extern int FormatMessage(int dwFlags, int lpSource, int dwMessageId,
                     int dwLanguageId, out StringBuilder lpBuffer,
                       int nSize, IntPtr va_list);

El método de extensión utilizado con la clase Exception es el siguiente

    public static class ExceptionExtension {
    /// <summary>
    /// Gets the win32 error description.
    /// </summary>
    /// <param name="ex">The ex.</param>
    /// <returns></returns>
    public static Win32Error GetWin32ErrorDescription(this Exception ex) {
        Win32Error retval = Win32Error.Empty;
        StringBuilder pMsgBuf = new StringBuilder();
 
        int lastError = FormatErrorHelper.GetLastError();
 
        FormatErrorHelper.FormatMessage(
               FormatErrorHelper.FORMAT_MESSAGE_ALLOCATE_BUFFER |
               FormatErrorHelper.FORMAT_MESSAGE_FROM_SYSTEM,
               FormatErrorHelper.NULL,   lastError, 
               FormatErrorHelper.MakeLangID(FormatErrorHelper.LANG_NEUTRAL,
               FormatErrorHelper.SUBLANG_DEFAULT), out pMsgBuf, 0, IntPtr.Zero);
 
         retval.ErrorCode = lastError;
         retval.Description = pMsgBuf != null ? pMsgBuf.ToString() : string.Empty;
 
         return retval;
      }
}

Por lo que al atrapar alguna excepción, además de obtener el objeto Exception como tal también obtengo el código y mensaje de error del sistema operativo

Win32Error osError = Win32Error.Empty;
 
try {
// Some funky exception here...
} catch(Exception ex) {
  osError = ex.GetWin32ErrorDescription();
  Console.WriteLine(string.Format("Code: {0} - Description: {1}", 
            new object[] {osError.ErrorCode, osError.Description}));  
}

Si ponemos en práctica todo lo mencionado anteriormente, vean lo diferente que es el mensaje de proporcionado por el .NET Framework al del sistema operativo

image

Espero sea de utilidad,

Saludos,

Angel

Pex (Automated White box Testing for .NET) | Pex (Caja blanca automatizada para pruebas en .NET)

I usually read a lot about technology stuff from Microsoft and other vendors as well. One of my favourite sites to gather information about ongoing projects and things to come is Microsoft Research so today after having lunch I started to browse for some projects and  I found Pex which in my humble opinion seems to be really interesting, why? Because it’s a new tool that helps in understanding the behavior of .NET code, debugging issues, and in creating a test suite that covers all corner cases – fully automatically. Through a context menu in the code editor, the user can invoke Pex to analyze an entire class or a single method. For any method, Pex computes and displays interesting input-output pairs. Pex systematically hunts for bugs – exceptions or assertion failures. As Pex discovers boundary conditions in code, Pex generates new tests that target these conditions. The result is a small test suite with high code coverage. Pex enables Parameterized Unit Testing, an extension of traditional unit testing that reduces test maintenance costs. Pex has been used in Microsoft to test core .NET components. Pex is developed at Microsoft Research and is integrated into Microsoft Visual Studio, so if you’re like me that loves to deliver high quality code then Pex is a must in your toolbox.

Regards,

Angel


Usualmente leo bastante sobre tecnologías Microsoft y otros fabricantes también. Uno de mis sitios favoritos para conseguir información acerca de proyectos en ejecución y cosas por venir es  Microsoft Research así que hoy después de almorzar comencé a navegar por algunos proyectos y encontré Pex, el cual en mi humilde opinión  parece ser realmente interesante, ¿por qué?  Pues porque es una nueva herramienta que ayuda a entender el comportamiento de código .NET, problemas de depuración y en la creación de pruebas para la mayoría de los casos – todo esto de manera automática. A través de un menú contextual en el editor de código, el usuario puede invocar Pex para analizar una clase entera ó un sólo método. Para cualquier método, Pex calcula y muestra las entradas y las salidas. Pex sistemáticamente busca bugs – excepciones ó fallas de aserciones. Mientras Pex descubre las condiciones de límites en el código, a su vez genera nuevas pruebas para dichas condiciones. El resultado es una pequeña suite con alta cobertura de código. Pex permite realizar prueba unitarias parametrizadas, que son una extensión de las pruebas unitarias tradicionales que reducen los costos en el mantenimiento de las pruebas. Pex ha sido utilizado por Microsoft para probar componentes importantes de .NET. Pex es desarrollado en Microsoft Research y está integrado con Microsoft Visual Studio, así que si eres como yo que le encanta entregar código de alta calidad entonces Pex es indispensable en tu caja de herramientas.

Saludos