How to work around absolute fontconfig path in mono 4 that breaks sandboxed apps RRS feed

  • Question

  • User52795 posted

    So in mono 4 the file /Frameworks/mono.framework/Versions/4.0.0/etc/fonts/fonts.conf contains an absolute path for the fontconfig cache folder like so:


    Whereas previously it was a relative path:


    Problem is that once I've built a sandboxed app and run on a system without mono installed (so that fonts.conf file isn't available) it reverts to that hard-wired path which is outside the sandbox and so as I've discovered if I use anything useful from System.Drawing my app is immediately rejected when it tries to create its font cache path there. Using mono 3.12 this is not a problem.

    There's no way in code I can change that path so either the config baked into the compiled libfontconfig.1.dylib needs to go back to the relative path (which I assume means a change to mono) or I'd need to be able to override that fonts.conf file somehow in the MonoBundle in my app. How can I proceed as if I can't I can never use anything above mono 3.12?

    Tuesday, June 2, 2015 2:28 AM

All replies

  • User35201 posted

    @JohnConners I'm going to forward this to the relevant people to see if we can get you a work around.

    Quick question, is there any reason you couldn't move to something like https://github.com/mono/sysdrawing-coregraphics as an alternative to the System.Drawing in Classic?

    Tuesday, June 2, 2015 6:35 PM
  • User52795 posted

    For the time being I'm sticking with Mono 3.12 so no worries @ChrisHamons

    I did try sysdrawing-coregraphics initially but it was too unstable. While I managed to work around the features that hadn't been implemented I eventually gave up when a random crash kept occurring and I noticed a comment in the code to the effect of "something stamping on memory here, not sure what" and I realised it wasn't solid enough for my needs. It's a shame as it would have been perfect, especially as I'd spent a long time making a custom build to get around XamMac's dependency on the existing System.Drawing at the time. (It's all coming back to me now).

    Tuesday, June 2, 2015 7:27 PM
  • User35201 posted

    I did some searching, this might be the comment in question:


    I'm sure you don't happen to have that work around, but if at some point you run into his, we'd love a bug report so we can fix the problem.

    Unified Mobile and XM 4.5 doesn't include mono's System.Drawing at all, so sysdrawing-coregraphics or using Cocoa directly are the only options under Unified.

    Tuesday, June 2, 2015 7:38 PM
  • User52795 posted

    Good spot, that was the one! I was just digging through the source myself to find it but failed.

    Yeah, wasn't in a rush to switch to Unified on this app for that reason but I would like to get away from System.Drawing since there's about a 2-3 initialisation time on a new machine while the fontconfig cache gets built that I'd love to get away from. I'll certainly give sysdrawing-coregraphics a shot again (without all the other distractions this time) and will for sure report anything I find (and try to fix them myself if I can).

    Tuesday, June 2, 2015 7:45 PM
  • User35201 posted

    If you get a test case, message me the bug #s after you file please

    Tuesday, June 2, 2015 7:47 PM
  • User52795 posted

    Should I create a bug report to change the fonts.config path back to being a relative path @ChrisHamons? There are some fixes to System.Threading.Tasks in Mono 4 from the Microsoft Reference Source port that I need as I'm running into crashes in 3.12.

    Friday, June 12, 2015 2:41 PM
  • User52795 posted

    Worth noting my hopes of a fix going down that route would not be high considering I reported a variation on this exact problem 9 months ago to no avail:


    I'd happily have that bug back rather than what there is now!

    Friday, June 12, 2015 2:46 PM
  • User35201 posted

    You can file a bug, and we'll prioritize it as best we can. I can't promise when we'll get bandwidth to hack on this.

    I'd personally rather fix bugs in sysdrawing-coregraphics and move you to that long term. libgdiplus and friends have been known to inflict pain.

    Sorry for the trouble.

    Friday, June 12, 2015 2:51 PM
  • User52795 posted

    Presumably changing the path in that config file is all that's required when mono is built? (Note I don't know the build process so am speculating). I wouldn't expect some override mechanism, just that config file to be rolled back to how it was when it used a relative path. I don't even want to consider the pain of doing my own build of mono.

    Personally I'd prefer to use sysdrawing-coregraphics on my next project and thrash out any bugs there, then back port at my leisure once I can trust it since my current app already works using libgdiplus. As it is I'm now going to have to throw away my usage of System.Threading.Tasks (since I can't use Mono 4) and roll my own threading code (not ideal) as that's an order of magnitude lower in risk than incorporating an unstable library at the core of my graphics-heavy app. And all because of a single line in a config file. Sigh. Not to worry, nobody said it was meant to be easy!

    Friday, June 12, 2015 3:03 PM
  • User35201 posted

    The problem is that I just can't "revert" the last changes, since who knows who that will break now. Every time we change this, we have to re-test, and then possibly break other use cases. Brittle is a good description, and I'm less than confident in quick fixes.

    I wouldn't want to hack on this until I had time to dig into this code (which I don't even know where it lives) and fix this once and for all.

    Friday, June 12, 2015 3:08 PM
  • User52795 posted

    Understood. I did dig into this in fontconfig 9 months ago and it looks at the cachedir entries in fonts.config:

    <cachedir prefix="xdg">fontconfig</cachedir>

    to decide where to create the cache file if it's not there already. Here's what the docs say:

    <cachedir prefix="default">

    This element contains a directory name that is supposed to be stored or read the cache of font information. If multiple elements are specified in the configuration file, the directory that can be accessed first in the list will be used to store the cache files. If it starts with '~', it refers to a directory in the users home directory. If 'prefix' is set to "xdg", the value in the XDGCACHEHOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details. The default directory is "$XDGCACHEHOME/fontconfig" and it contains the cache files named "-.cache-", where is the font configuration file version number (currently 5).

    This isn't a code issue, it simply seems bad practise to put an absolute path in the fonts.config on an end user's machine.

    Anyway, bug report here: https://bugzilla.xamarin.com/show_bug.cgi?id=31068

    I was rather enjoying being up to date with releases but looks like I'll have to stick with Mono 3.12 / XamMac 1.12 for the foreseeable.

    Friday, June 12, 2015 3:30 PM
  • User52795 posted

    Ok, on further investigation I've figured out what's causing the problem and a workaround that means I can use Mono 4 and stop complaining!

    The Mono build system builds libfontconfig.1.dylib with that absolute path (you can see the output in this build log when you search for "/Users/builder/Library/Caches/com.xamarin.fontconfig" - it's passing the path to install-sh for fontconfig-2.10.2). I couldn't find where that's actually defined in the build process but I realised that it must always have done that so if I replace libfontconfig.1.dylib in my built app with the version from Mono 3.12 then since it was compiled with a relative path instead of absolute I won't fall foul of the sandbox requirements and on testing that is indeed the case. Yay!

    This approach would only fall down if Mono were to start building against a newer version of fontconfig so should that happen before I've switched to sysdrawing-coregraphics I'll start hunting down photos of grumpy cats to post.

    Saturday, June 13, 2015 10:58 AM
  • User52795 posted

    Even better, turns out it's now been fixed:


    Here's the changeset to fontconfig.py - in the build process:


    Now I can definitely shut up! :)

    Monday, June 15, 2015 12:05 PM
  • User35201 posted


    I'm glad it got sorted out, doubly so by somebody who knew that area of code so well. He says it'll make the 3rd service release for cycle 5 (the one AFTER the one that is going to release soon).

    Monday, June 15, 2015 2:11 PM
  • User176021 posted


    Any news on this bugfix, I've been checking the release notes for each release and I can't tell if it's gone into an official release yet.

    The problem comes for us with the delay in building the font cache each time our application is run, even on a clear install El Capitan machine it can take almost a minute, fixing this would be very handy! :)

    Many Thanks, Dave

    Wednesday, November 25, 2015 1:05 PM
  • User35201 posted

    In theory, the latest release (Cycle 6) pulls in mono 4.2. The bug in question (nor the duplicate resolved copies) doesn't mention exactly where the fix was landed. If testing the latest release doesn't show it fixed, feel free to reopen the bug.

    Monday, November 30, 2015 3:25 PM
  • User52795 posted

    I can confirm that this has indeed been fixed in mono 4.2. The fontconfig cache location is relative rather than absolute again. Yay!

    Monday, November 30, 2015 4:42 PM
  • User176021 posted

    Thanks guys, I will give it a spin on 4.2 and fingers crossed the issue is resolved :)

    Many Thanks! Dave

    Monday, December 7, 2015 9:56 AM