GNOME Bugzilla – Bug 604810
Gstreamer Related functions crash when a XMLSerializer has been created
Last modified: 2015-02-27 12:08:55 UTC
Created attachment 149898 [details] Example program showing the problem Hi All I'm experiencing a very weird problem. When I add the following line (or similar lines) "XmlSerializer serializer = new XmlSerializer(typeof(Object));" to a program that uses Gstreamer, the Gstreamer function calls crash. The error message is below: System.ArgumentException: The path is not of a legal form. at System.IO.Path.NormalizePathFast(String path, Boolean fullCheck) at System.IO.Path.NormalizePath(String path, Boolean fullCheck) at System.IO.Path.GetDirectoryName(String path) at Gst.Application.GstTypeResolver(GType gtype, String gtype_name) at GLib.GType.LookupType(IntPtr typeid) at GLib.ObjectManager.GetTypeOrParent(IntPtr obj) at GLib.ObjectManager.CreateObject(IntPtr raw) at GLib.Object.GetObject(IntPtr o, Boolean owned_ref) at Gst.ElementFactory.Make(String factoryname, String name) at ConsoleApplication1.Testing.test() in C:\Users\Dksaarth\Documents\Visual Studio 2008\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 50 If I comment out the XmlSerializer line it works. I have attached a sample program showing this behaviour. I am running on windows with the winbuild version of Gstreamer. I think the bindings and glib-sharp dll's I am using are a bit old, but I have experienced great difficulty in compiling new ones.
Which version of gst-sharp are you using? All GLib related things shouldn't really be there, instead the namespace should be Gst.GLib. Currently gst-sharp has an internal copy of glib-sharp in a different namespace to not require latest SVN trunk of glib-sharp.
Aah great, I didn't know that. Let me change everything to use just the bindings that are available for download, will update shortly.
I downloaded the bindings off of the winbuild site, removed the ones I was using, changed it to use Gst.Glib and I still get the same error. Anything else I can try / add to this report ?
Hi All Some additional information from Maarten "From the stack trace it looks like an old version, because Gst.Application.GstTypeResolver does not exist anymore. The code has been replaced by the following: (in gstreamer-sharp/Application.cs of v0.9.2, downloaded from http://cgit.freedesktop.org/gstreamer/gstreamer-sharp/) private static System.Type GstResolveType (Gst.GLib.GType gtype, string gtype_name) { Assembly[] assemblies = (Assembly[]) AppDomain.CurrentDomain.GetAssemblies ().Clone (); [snip] foreach (Assembly asm in assemblies) { foreach (AssemblyName ref_name in asm.GetReferencedAssemblies ()) { string asm_dir = Path.GetDirectoryName (asm.Location); [...] So this already gives a hint to the source of the problem. Because there is an assembly loaded with an invalid Assembly.Location, perhaps null. Calling XmlSerializer probably triggers loading such an assenbly."
I'm not able to test it right now, but looking through the stacktrace suggests that wrapping the string asm_dir = Path.GetDirectoryName (asm.Location); line in a try{} block would resolve the problem. Not sure though whether that's the correct solution. Some questions I have: - Why are all the assemblies loaded in the first place. - Why does the XmlSerializer (or one of its dependencies) has an invalid Location
To answer my own question (the second). From MSDN, for Assembly.Location: The location of the loaded file that contains the manifest. If the loaded file was shadow-copied, the Location is that of the file after being shadow-copied. If the assembly is loaded from a byte array, such as when using the Load(Byte[]) method, Location is an empty string (""). Exceptions SecurityException The caller does not have the required permission. So the correct solution would be to check for String.Empty and catch SecurityException. The lazy, and perhaps best, way out is of course to extend the try{} block which we already use to also cover the offending line.
Sounds like a good solution IMHO. Do you want to make a patch? :)
Which would be the correct approach to take here ? I don't mind writing up a patch but not sure which one you would prefer I moved the try { one line up so that it is now above string asm_dir = Path.GetDirectoryName(asm.Location); and it fixes my problem. Thanks again :)
Created attachment 149975 [details] [review] Patch to fix bug - checks if location string is empty
Review of attachment 149975 [details] [review]: This patch is better, in that instead of catching the errorring out after a failed Path.GetDirectoryName (asm.Location), it tries to do an Assembly.Load without the path. I'm not sure whether it matter in practice though. Anyway, it solves to problem, please commit
commit 9203ed7c9a921bdbead2f2b9296311452b1b42f9 Author: Richard Spiers <richard.spiers@gmail.com> Date: Fri Dec 18 12:21:03 2009 +0200 Fix crash when assemblies have empty location string Fixes bug #604810.
*** Bug 608959 has been marked as a duplicate of this bug. ***
Hi! I know that it is so long since this bug was marked as resolved but I have an issue related with it and I have not found any other place to ask for. Applying this patch I have achieved to use XmlSerializer and GStreamer inside my project without problems... Thanks! However, I still appreciate an issue about this code. Some exceptions (always the same) are launched during the loading of GStreamer binding assemblies: "System.NotSupportedException: The invoked member is not supported in a dynamic assembly" The exception seems to be thrown at the line: if (asm.Location != String.Empty) {... (I guess the call to "Location" member has the fault) And finally, the (dynamic?) assembly ("asm" variable) that origins everything is: {Microsoft.GeneratedCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null} I know that all the exceptions thrown here are ignored by this code: ... } catch (Exception) { /* Failure to load a referenced assembly is not an error */ } But I would like to better understand the problem and till now I have not found anything out there. Some questions: What is the assembly "Microsoft.GeneratedCode" and which is its relationship with the "XmlSerializer"? Is it a dynamic assembly? A dynamic assembly is the same than a "referenced assembly"? Which is its mission here? Some help would be very appreciated. Thanks a lot in advance. Domingo.