Red Hat Bugzilla – Bug 1251756
Missing dependency on /usr/lib/libgdiplus.so
Last modified: 2017-08-26 03:50:17 EDT
I received the following exception when trying to start KeePass on a fresh Fedora 23 installation:
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for System.Windows.Forms.XplatUI ---> System.TypeInitializationException: An exception was thrown by the type initializer for System.Drawing.GDIPlus ---> System.DllNotFoundException: libgdiplus.so
at (wrapper managed-to-native) System.Drawing.GDIPlus:GdiplusStartup (ulong&,System.Drawing.GdiplusStartupInput&,System.Drawing.GdiplusStartupOutput&)
at System.Drawing.GDIPlus..cctor () [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Drawing.Graphics.FromHdcInternal (IntPtr hdc) [0x00000] in <filename unknown>:0
at System.Windows.Forms.XplatUIX11.SetDisplay (IntPtr display_handle) [0x00000] in <filename unknown>:0
at System.Windows.Forms.XplatUIX11..ctor () [0x00000] in <filename unknown>:0
at System.Windows.Forms.XplatUIX11.GetInstance () [0x00000] in <filename unknown>:0
at System.Windows.Forms.XplatUI..cctor () [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Windows.Forms.Application.EnableVisualStyles () [0x00000] in <filename unknown>:0
at KeePass.Program.Main (System.String args) [0x00000] in <filename unknown>:0
Indeed, file /usr/lib/libgdiplus.so was not installed. It is provided by package libgdiplus-devel. However, package mono-core depends only on package libgdiplus.
Peter aka mavit, the package maintainer of Keepass, has added a workaround for Keepass to require libgdiplus-devel, thanks!
I wonder if that is not just a workaround, but the solution.
The alternative would be that mono-core requires libgdiplus-devel? would that be right? Any suggestions?
ah, sorry, Peter, you reported the bug :)
I was getting confused :)
Anyway, my question stands at it is...
Well, in previous versions of Fedora, this worked fine without libgdiplus-devel, which makes me think that Mono's behaviour has changed.
OTOH, perhaps this is a bug in package libgdiplus-devel, and file /usr/lib/libgdiplus.so should be moved to package libgdiplus.
I have found the difference: in /etc/mono/config, there was previously (eg. Fedora 21) the line:
<dllmap dll="gdiplus.dll" target="libgdiplus.so.0" os="!windows"/>
In Fedora 23:
<dllmap dll="gdiplus" target="libgdiplus.so" os="!windows"/>
<dllmap dll="gdiplus.dll" target="libgdiplus.so" os="!windows"/>
Now I wonder what the best solution is.
Looking at the libgdiplus packages (behaviour did not change since Fedora 21):
rpm -ql libgdiplus-devel
rpm -ql libgdiplus
ls -la /usr/lib64/libgdiplus.so*
lrwxrwxrwx. 1 root root 19 17. Aug 2014 /usr/lib64/libgdiplus.so -> libgdiplus.so.0.0.0
lrwxrwxrwx. 1 root root 19 17. Aug 2014 /usr/lib64/libgdiplus.so.0 -> libgdiplus.so.0.0.0
-rwxr-xr-x. 1 root root 425880 17. Aug 2014 /usr/lib64/libgdiplus.so.0.0.0
Interestingly, libgdiplus.so is just a symbolic link.
So I wonder if the proper solution would be to change libgdiplus to only deliver the .pc file in the devel package, and libgdiplus.so becomes part of the libgdiplus package?
(In reply to Timotheus Pokorra from comment #4)
> Interestingly, libgdiplus.so is just a symbolic link.
> So I wonder if the proper solution would be to change libgdiplus to only
> deliver the .pc file in the devel package, and libgdiplus.so becomes part of
> the libgdiplus package?
For most, if not all, shared libraries, the lib*.so files are symbolic links to *.so.N. Fedora packages the (run-time) *.so.N files in the "standard" or "-lib" packages, the (compile-time) *.so files in the "-devel" packages.
If the reference in /etc/mono/config were a Mono compiler directive, refering to *.so would be correct (and need to pull in dependencies to "-devel", otherwise *.so.N would need to be refered, as that is what's available on a system.
We need a solution for this.
Someone, please make a decision if
* the libgdiplus package should create a symbolic link called `libgdiplus.so` or if
* the /etc/mono/config file should refer to `libgdiplus.so.0` instead of `libgdiplus.so`.
See https://bugzilla.xamarin.com/show_bug.cgi?id=34314 for my upstream report.
I checked, in Fedora 22 a patch was used to hardcode the reference to libgdiplus.so.0 in the config.in file: http://pkgs.fedoraproject.org/cgit/mono.git/tree/mono-281-libgdiplusconfig.patch?h=f22
So I guess I will do it the same way for Fedora 23 and Rawhide
I have committed this patch to rawhide, so libgdiplus.so.0 is directly referenced, without the need for the libgdiplus-devel package.
mono-4.0.5-3.fc23 has been submitted as an update to Fedora 23. https://bodhi.fedoraproject.org/updates/FEDORA-2016-f2e62e4a3d
Thanks a lot for taking care of this!
mono-4.0.5-3.fc23 has been pushed to the Fedora 23 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2016-f2e62e4a3d
Your patch will probably break on Mac OS X. I will try to submit something more generic upstream. https://github.com/mono/mono/pull/2394
mono-4.0.5-3.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.
I just ran into exactly this issue today with Fedora 26, when trying to play StardewValley (mono based game).
System.Graphics.dll explicit expects libgdiplus.so while the Fedora packages only delivers libgdiplus.so.0 and libgdiplus.so.0.0.0
Please read further here for a bugreport to SMAPI Mod for StardewValley.
I spent a few hours figuring out what's going on.
So if more Mono based games show up on Steam then you can be sure that they all complain about missing libgdiplus.so (explicit naming) and thus end up in throwing exceptions.
please install the fedora package: libgdiplus-devel
does it work then?
(In reply to Timotheus Pokorra from comment #16)
> please install the fedora package: libgdiplus-devel
> does it work then?
It does! But, why do I have to install a *-devel package if I only want to have the runtime work properly ? I mean... Nobody thinks about installing a *-devel package in this case... Imagine the user who want's to play a #Net based or Mono based game which he/she downloads from steam. The only thing delivered are some basic libraries from Mono and one of them explicitly requests libgdiplus.so.
External sources advises the user to install mono-core (on any distribition that ships mono) to satisfy the dependency... Now mono-core only installs libgdiplus and not libgdiplus-devel. Ending in the result that the Mono libraries provided by the game still won't find libgdiplus.so (symlink) to operate properly...
I would therefore argue splitting out the libgdiplus.so symlink from the *-devel package and put it in the 'non'-devel package and keep the pkgconfig file in the *-devel package only.
I had a look at the packaging guidelines:
The versioned file is part of libgdiplus package, the unversioned .so file is part of the devel package.
As far as I understand it, the applications depending on libgdiplus should reference the versioned so file (libgdiplus.so.0), rather than the unversioned file (libgdiplus.so).
What do external sources think about that?
But that doesn't help if games (based on Mono) released on Steam are referencing to libgdiplus.so. These games are widely downloaded by thousands of people and rely that libraries are present to operate properly.
I do understand the idea behind the proper versioning. But that doesn't help, if e.g. SteamOS (Debian based) for example ofers a libgdiplus.deb package which has libgdiplus.so as such referenced (and Fedora not).
For example that's the package list of debian unstable:
and here for wheezy:
From a users perspective I was advised by mutiple sources to install mono (or mono-core) to have missing libraries become present on the system. Infact in reality libgdiplus-devel was required (not installed through dnf install mono). I spent a whole day messing around with this (primarily with the game throwing exceptions) until I realized the issue and set a link to libgdiplus.so manually.
Those different standards makes it really hard to figure out the issue and have it solved... Specially if you are not knowing the issue at all...
(In reply to Timotheus Pokorra from comment #18)
> As far as I understand it, the applications depending on libgdiplus should
> reference the versioned so file (libgdiplus.so.0), rather than the
> unversioned file (libgdiplus.so).
It was not the game referencing to it.. it was "System.Graphics.dll" part of some Mono library.
If I recall correctly...
If you issue "dnf install mono-core" then System.Graphics.dll is part of that installation. System.Graphics.dll, that comes with it also references to libgdiplus.so (rather than a versioned version of it). But mono-core doesn't install libgdiplus-devel, which - if I am not mistaken - will make System.Graphics.dll not operate properly for Texture2D Streams...
It could have been System.Drawing.dll ...
Looking at the stacktrace at https://github.com/LeonBlade/TreeTransplant/issues/1, it does indeed seem to be System.Drawing that is causing the problem.
I am looking at https://github.com/mono/mono/blob/master/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs which has:
[DllImport(GdiPlus)] which is resolved to "gdiplus".
In /etc/mono/config, there is this line:
<dllmap dll="gdiplus" target="libgdiplus.so.0" os="!windows"/>
Could you please check if that line is there for you as well?
Or did you get Mono from another source. Perhaps you have got the Mono packages directly from Xamarin?
I just wonder: we have Keepass, which uses System.Drawing and it works, without libgdiplus-devel. I wonder what the difference is.
The problem is not the "own" installed mono. The problem is the mono packages (runtime) that comes bundles with the games offered by steam.
From what I understand it's as follows:
System.Drawing.dll seems to be operating normally... Only for "certain" API calls it references to libgdiplus.so and if it doesn't find it, it throws exceptions.
But for the "own" mono package which comes delivered with Fedora (this includes maybe the Keepass package) this may all work properly depending on how mono was compiled.
So if the Steam games have been compiled using the mono that comes from debian (or steam) then they may hard reference libgdiplus.so inside System.Drawing.dll because debian offers the entire package including a symlink to libgdiplus.so where on Fedora it doesn't unless you install the devel package.
But this is all speculation...
From a users perspective I only want it to run out of the box without messing around with mono centric config files or having to set up an entire mono development environment only to satisfy missing libraries...
This is too much guessing.
We need a clean test case.
I would need a simple program in C#, with source and with binaries, that shows this behaviour.
(In reply to Timotheus Pokorra from comment #24)
> This is too much guessing.
> We need a clean test case.
> I would need a simple program in C#, with source and with binaries, that
> shows this behaviour.
This is not guessing... I exactly hit that issue otherwhise I wouldn't be commenting here.
1) Download Stardew Valley from Steam and install the game on your system
2) Download and install the SMAPI modding API
3) Here is the testcase. Please install this mod:
The source code exists too and is fully monodevelop compatible. Load the solution, compile and run.
This particular mod uses System.Drawing.dll which is (or comes as) part of the game installation. So it has nothing to do with the mod and modding API at all. It was just the issue that triggered all of this.
The error log complained that System.Drawing.dll can't handle the image format. Later it was figured out that libgdiplus.so was missing. The installation instruction recommends installing mono to solve all kind of needs or dependencies. Even if this is done the same System.Drawing.dll continued throwing exceptions because it required libgdiplus.so (without versioning).
The point I am trying to make here is this: If people bundle mono with their games (as runtime) and expects libgdiplus.so to be present on the running system (even if they ask the user to install mono) then the game should be running and not throwing exceptions.
Now you might argue that you are using "mods" here... Who knows what they've done... and I would clearly agree here... But in this particular case the mod made usage of a game bundles mono dll library, that "operates" but wasn't able to figure the missing libgdiplus.so installation and thus hit exceptions because it couldn't pass graphic or drawing functions to said library.
says: "Purchase Stardew Valley for $14.99 on Steam"
So Stardew Valley is bundling System.Drawing.dll.
I searched all files of TreeTransplant for gdiplus or Drawing, and could not find a hit. So I need the source code of Stardew Valley, which I guess I will not get.
Why don't you talk to the producers of Stardew Valley about not bundling System.Drawing.dll? Or do they bundle even more of Mono?
I still wonder what the content of your /etc/mono/config is, and from which source that file is coming.
I learn that we don't get any further here!
Sorry for bothering you and spamming this bugreport. From what I've learned so far, this subject is something that may be brought up infront of Fesco. I may think about this and decide then. Meanwhile this subject is not important enough to have all my spare time dealing with it.