none
Attempted to read or write protected memory - Fonts

    Question

  • I am receiving the following error message in a non-reproducable and seemingly random fashion in my ASP.NET, C# application:

    System.AccessViolationException was unhandled
    Message: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

    The only steps I can take to reproduce the error are to run the offending function many times, and at some point, this error occurs.

    The function that I believe to be causing the error is as follows (well, actually I think that GDI+ using this functions output is the cause):

    public static Font GetFont(HttpServerUtility Server, string FontName, int Size, bool Admin)
            {
                //Check if it's in the PrivateFontCollection
                //If not then it is a system font

                PrivateFontCollection pfc = null;

                if (Admin)
                {
                    pfc = IO.GetFonts(Server.MapPath("../Fonts/"));
                }
                else
                {
                    pfc = IO.GetFonts(Server.MapPath("Fonts/"));
                }

                int count = pfc.Families.Length;

                for (int j = 0; j < count; ++j)
                {
                    // Get the font family name.
                    string familyName = pfc.Families[j].Name;

                    if (familyName.ToLower() == FontName.ToLower())
                    {
                        Font fx = new Font(pfc.Families[j], (float)Size);
                        return fx;
                    }
                }

                Font f = new Font(FontName, Size);
                return f;
            }

    The aim of this function is to use a font name, say "Arial" as an example. "Arial" is passed to the function which then cycles through a PrivateFontCollection to determine if it is present in the private collection, or whether the font specified is a system font. The function IO.GetFonts(Server.MapPath("Fonts/")) is as follows:

    public static System.Drawing.Text.PrivateFontCollection GetFonts(string Path)
            {
                string FontFilesLocation = Path;
                System.Drawing.Text.PrivateFontCollection pf;
                string[] ttfs;
                System.Drawing.FontFamily ff;
                pf = new System.Drawing.Text.PrivateFontCollection();
                ttfs = System.IO.Directory.GetFiles(FontFilesLocation, "*.ttf");

                for (int i = 0; i < ttfs.Length; i++)
                {
                    try
                    {
                        pf.AddFontFile(ttfsIdea);
                    }
                    catch (Exception)
                    {
                    }
                }
                return pf;
            }

    This is designed to simply build the PrivateFontCollection from the specified path.

    When the error occurs, two events are written into the event log:

    1.)aspnet_wp.exe  (PID: 2780) stopped unexpectedly.
    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

    and

    2.) Event Type:    Error
    Event Source:    .NET Runtime 2.0 Error Reporting
    Event Category:    None
    Event ID:    1000
    Date:        08/04/2006
    Time:        19:29:52
    User:        N/A
    Computer:    MARTIN
    Description:
    Faulting application aspnet_wp.exe, version 2.0.50727.42, stamp 4333aece, faulting module gdiplus.dll, version 5.1.3102.2180, stamp 4110968b, debug? 0, fault address 0x00046fc6.

    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
    Data:
    0000: 41 00 70 00 70 00 6c 00   A.p.p.l.
    0008: 69 00 63 00 61 00 74 00   i.c.a.t.
    0010: 69 00 6f 00 6e 00 20 00   i.o.n. .
    0018: 46 00 61 00 69 00 6c 00   F.a.i.l.
    0020: 75 00 72 00 65 00 20 00   u.r.e. .
    0028: 20 00 61 00 73 00 70 00    .a.s.p.
    0030: 6e 00 65 00 74 00 5f 00   n.e.t._.
    0038: 77 00 70 00 2e 00 65 00   w.p...e.
    0040: 78 00 65 00 20 00 32 00   x.e. .2.
    0048: 2e 00 30 00 2e 00 35 00   ..0...5.
    0050: 30 00 37 00 32 00 37 00   0.7.2.7.
    0058: 2e 00 34 00 32 00 20 00   ..4.2. .
    0060: 34 00 33 00 33 00 33 00   4.3.3.3.
    0068: 61 00 65 00 63 00 65 00   a.e.c.e.
    0070: 20 00 69 00 6e 00 20 00    .i.n. .
    0078: 67 00 64 00 69 00 70 00   g.d.i.p.
    0080: 6c 00 75 00 73 00 2e 00   l.u.s...
    0088: 64 00 6c 00 6c 00 20 00   d.l.l. .
    0090: 35 00 2e 00 31 00 2e 00   5...1...
    0098: 33 00 31 00 30 00 32 00   3.1.0.2.
    00a0: 2e 00 32 00 31 00 38 00   ..2.1.8.
    00a8: 30 00 20 00 34 00 31 00   0. .4.1.
    00b0: 31 00 30 00 39 00 36 00   1.0.9.6.
    00b8: 38 00 62 00 20 00 66 00   8.b. .f.
    00c0: 44 00 65 00 62 00 75 00   D.e.b.u.
    00c8: 67 00 20 00 30 00 20 00   g. .0. .
    00d0: 61 00 74 00 20 00 6f 00   a.t. .o.
    00d8: 66 00 66 00 73 00 65 00   f.f.s.e.
    00e0: 74 00 20 00 30 00 30 00   t. .0.0.
    00e8: 30 00 34 00 36 00 66 00   0.4.6.f.
    00f0: 63 00 36 00 0d 00 0a 00   c.6.....

    In that stack trace there is a clear reference to gdiplus.dll, which is using the output of the font function in the following way (g is a graphics object - created from a bitmap that was created from a PNG):

    Font f = GetFont(Server, font, int.Parse(size), false);
    g.DrawString(defaultText, f, brush, drawRect, drawFormat);

    So, I am assuming that it is either that DrawString method that is causing the problem, or the Font assignment. This did not happen before I wrote the above two functions. I really need the private font support so any help would be greatly appreciated.
    Sunday, April 9, 2006 8:44 AM

Answers

  • Hi,

    Yes, it is a bug in the Framework itself and occurs when a Font object from a PrivateFontCollection is disposed.

    I believe the hotfix at http://support.microsoft.com/Default.aspx?kbid=901026 may help with the problem, but applying this to my server was not an option and the problem seems to present itself on other OSs than Win XP.

    So, to work around this I loaded all my fonts into a PrivateFontCollection that was global to the application scope - in short it never gets disposed or only gets disposed when the web application has no activity for a long while.

    This does of course present the problem that the fonts are not disposing properly and if run on a web server that never reboots it will eventually lead to severe memory consumption.

    Martin
    Thursday, January 18, 2007 5:31 PM

All replies

  • I can now report with certainty that the error occurs in the following code block:

                int count = pfc.Families.Length;

                for (int j = 0; j < count; ++j)
                {
                    // Get the font family name.
                    string familyName = pfc.Families[j].Name;

                    if (familyName.ToLower() == FontName.ToLower())
                    {
                        Font fx = new Font(pfc.Families[j], (float)Size);
                        return fx;
                    }
                }


    The error occurs approximately 10% of the time.

    It is worth noting that it is not the Font constructor throwing the error as this should never be reached in my tests (I specify a system font not present in the privatefontcollection).

    Martin
    Sunday, April 9, 2006 1:46 PM
  • Hi there,

    I'm having a the same problem with code that is quite similar to yours.

    Did you end up working out the cause of the problem? Any help would be apprechiated.

    Thanks
    Deltoid
    Thursday, January 18, 2007 2:34 PM
  • Hi,

    Yes, it is a bug in the Framework itself and occurs when a Font object from a PrivateFontCollection is disposed.

    I believe the hotfix at http://support.microsoft.com/Default.aspx?kbid=901026 may help with the problem, but applying this to my server was not an option and the problem seems to present itself on other OSs than Win XP.

    So, to work around this I loaded all my fonts into a PrivateFontCollection that was global to the application scope - in short it never gets disposed or only gets disposed when the web application has no activity for a long while.

    This does of course present the problem that the fonts are not disposing properly and if run on a web server that never reboots it will eventually lead to severe memory consumption.

    Martin
    Thursday, January 18, 2007 5:31 PM