I've come across what I think is an interesting bug in iOS 5.0 (this code works perfectly in 5.1). After ages of narrowing it down using lots of Console.Write()'s, I narrowed the crash to:
nsUrl.ToString();
This is either in the MonoTouch library or iOS.
Anybody else come across this? It's annoying, as we obviously want to support the minimum iOS version possible.
In MonoTouch the default ToString implementation, for NSObject subclasses, is to call the description selector.
In some cases (and yes it varies with iOS versions) calling description can fail (or even crash the process). That generally occurs when the native object is a bad state (e.g. mis-initialized, invalid value...).
MonoTouch tries to handle such cases (when possible and known) by using a different ToString implementation (e.g. with extra checks or by falling back to the default ToString, which returns the type name).
Note: If you find such behaviour please report them in bug reports and we'll see if they can be handled differently.
Related
I have a C# assembly that uses "$(FrameworkSDKDir)\Bin\NETFX 4.0 Tools\tlbexp.exe" "$(OutDir)My.dll" /out:"$(TLBDir)My.tlb" so that I can call it from native components
I am looking at
.tlh generated on 2 machines is different and it appears to be a similar problem, but my difference is in visual2010 the tlh is generated using one case, and in 2012, it is generated using a different case.
Even more interesting this just happened a day ago. I have a build from the 18th that worked just fine, and the code has not changed in either solutions for many days.
Any thoughts before i continue down the /Names option?
I cannot easily tell you what to do to solve this problem, just highlight why this is happening. It doesn't have much to do with Tlbexp.exe, it is generic behavior implemented in the type library support built into Windows.
It has a tricky problem to solve, it cannot make any assumptions about the kind of language that was used to generate the types. The troublemakers are languages that are case-insensitive, Visual Basic being the prime example. Also the original language for which type libraries were invented. The issue is that it may emit names that can have different casing in different declarations but identify the same type. If the type library would use the same casing then it could only ever be consumed by a language-insensitive compiler.
So it does something about it, the algorithm it uses can at best be described as crude however. It looks at any name, regardless of what part of a declaration it is used, then forces the casing of any subsequent same name it encounters to the same casing. The usual big surprises are caused by names of function arguments. They can change the name of a function if it happens to match. So an "item" argument, pretty common, can spoil the name of an "Item" property. Or the other way around.
The wild-card here is order, I suppose that could be half an explanation.
Best way to address the problem is to change the name so there is no longer a collision. You have no trouble finding them, it is the one that changed casing. You may have to iterate a few times to find them all. Given that it is usually the name of an argument that causes this, feel free to change the argument name. Just put an underscore after it for example, it doesn't break binary compatibility nor the client code.
In my own program I'm trying to use this code here to add tooltip balloon windows to my application: http://www.codeproject.com/Articles/4991/Balloon-Tips-Galore (Source code available here)
I tried compiling the demo program and it works fine on 32-bit Windows 7, but when I try to use it on 64-bit Windows 7 the program crashes. If I try to debug the crash in VS2010 I get this message:
The debugger is in some area where the source code isn't available and it says Call stack location: ntdll.dll!0000000076fe40f2()
How can I fix this so it won't crash on 64-bit?
I can't make the C# demo crash on Windows Server 2003 x64 (which is the only 64-bit environment I have handy at the moment), but the code is faulty so it makes sense that you're seeing unexpected behavior.
Edit: Reproduced the crash in Windows Server 2008 R2 x64 using the original code, and verified the efficacy of the fix.
As Christian.K points out, the problem has been noted before. When calling the Marshal.StructureToPtr method, you should pass true for the third fDeleteOld parameter only when the specified memory block does not contain valid data. This is called out pretty explicitly in the documentation, so I'm not sure how the original writer got it wrong.
In this case, since the data was just allocated the line before by calling Marshal.AllocHGlobal, it does not contain valid data and should not be deleted/freed. The change is simple: change the third parameter true to false. Unfortunately, because the interop code is scattered across three different classes in the sample project, you'll have to make the change multiple places. The pattern you're looking for is this:
IntPtr ptrStruct = Marshal.AllocHGlobal(Marshal.SizeOf(ti));
Marshal.StructureToPtr(ti, ptrStruct, false /* <-- change this from true to false */);
Just as a general observation: the code tries to handle a lot of the interop stuff manually (by using methods of the Marshal class) rather than just letting the CLR handle it automatically. I much prefer the latter method. Even though I fully understand how to do all of the interop manually, letting the system manage it for me keeps down the number of mistakes I make and resulting heap corruption.
RhysW says he's never encountered heap corruption before, but it becomes very common when you start doing interop between .NET code and the Win32 API. The .NET Framework is no longer protecting you.
For an example of what I mean, notice that the FMSBalloonTip.SetToolTip method uses the Marshal.StringToHGlobalAuto method to marshal the string containing the tooltip's title as a pointer. While that certainly works (and the author was thankfully careful to free the pointer after they're finished), it would be much easier and less error-prone to declare an overload of the SendMessage function that accepts a string object as the fourth parameter. That way, the framework will handle all of the necessary interop stuff for you transparently.
The real question, of course, is why you need this code at all. It's way easier to just use the built-in ToolTip class, which has been available since the beginning. I'm not sure if you just didn't mention some feature you need that ToolTip doesn't provide or you just don't know about it, but I strongly recommend reconsidering your design so that you can make use of the built-in class and let the Microsoft programmers handle all of the interop stuff.
If it's the balloon part you're looking for, make sure to set the IsBalloon property of the ToolTip class. That wasn't introduced until .NET 2.0, but that's the same version the sample project is targeting.
I am using the MonoTouch build of Service Stack from https://github.com/ServiceStack/ServiceStack/tree/master/release/latest/MonoTouch
When run on a iPad, I get a JIT error. I thought MonoTouch took care of that in the build?
Attempting to JIT compile method
'ServiceStack.Text.Json.JsonReader`1<Common.AppCategoryEnum>:GetParseFn ()' while running
with --aot-only.
I use the DLLS:
ServiceStack.Common.dll
ServiceStack.Interface.dll
ServiceStack.Text.dll
And only this single call:
new JsonServiceClient ().GetAsync<MyResponse> (url, Success, Failure);
I am using the MonoTouch build of Service Stack from
Those .dll are more than 3 months old and a similar issue was found and fixed one month ago.
I get a JIT error. I thought MonoTouch took care of that in the build?
Yes. When building for MonoTouch the AOT (ahead of time) compiler is used. It compiles everything it knows it will require at runtime.
However sometimes the AOT compiler cannot know everything (e.g. generic virtual methods) or compile every possible variations (e.g. value types). See the section generic limitations in the documentation web site. In such case it AOT compiler might need help (a signature that will ensure the right code will be compiled, e.g. something like this).
It can also be a bug - where a required method was not AOT'ed for some reason. When this is discovered, at runtime, an exception will occurs because the code is missing and the JIT cannot be used to provide it.
I know it has been a long time this thread was created but I somewhat find here and there a workaround
just call var dummy = new JsonSerializer() in the AppDelegate in the FinishedLaunching method.
I've written a multi-threaded windows service in C#. For some reason, csc.exe is being launched each time a thread is spawned. I doubt it's related to threading per se, but the fact that it is occurring on a per-thread basis, and that these threads are short-lived, makes the problem very visible: lots of csc.exe processes constantly starting and stopping.
Performance is still pretty good, but I expect it would improve if I could eliminate this. However, what concerns me even more is that McAfee is attempting to scan the csc.exe instances and eventually kills the service, apparently when one the instances exits in mid-scan. I need to deploy this service commercially, so changing McAfee settings is not a solution.
I assume that something in my code is triggering dynamic compilation, but I'm not sure what. Anyone else encounter this problem? Any ideas for resolving it?
Update 1:
After further research based on the suggestion and links from #sixlettervariables, the problem appears to stem from the implementation of XML serialization, as indicated in Microsoft's documentation on XmlSerializer:
To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types.
Microsoft notes an optimization further on in the same doc:
The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
which appears to indicate that the codegen and compilation would occur only once, at first use, as long as one of the two specified constructors are used. However, I don't benefit from this optimization because I am using another form of the constructor, specifically:
public XmlSerializer(Type type, Type[] extraTypes)
Reading a bit further, it turns out that this also happens to be a likely explanation for a memory leak that I have been observing when my code executes. Again, from the same doc:
If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable.
The two workarounds that Microsoft suggests above are a last resort for me. Going to another form of the constructor is not preferred (I am using the "extratypes" form for serialization of derived classes, which is a supported use per Microsoft's docs), and I'm not sure I like the idea of managing a cache of assemblies for use across multiple threads.
So, I have sgen'd, and see the resulting assembly of serializers for my types produced as expected, but when my code executes the sgen-produced assembly is not loaded (per observation in the fusion log viewer and process monitor). I'm currently exploring why this is the case.
Update 2:
The sgen'd assembly loads fine when I use one of the two "friendlier" XmlSerializer constructors (see Update 1, above). When I use XmlSerializer(Type), for example, the sgen'd assembly loads and no run-time codegen/compilation is performed. However, when I use XmlSerializer(Type, Type[]), the assembly does not load. Can't find any reasonable explanation for this.
So I'm reverting to using one of the supported constructors and sgen'ing. This combination eliminates my original problem (the launching of csc.exe), plus one other related problem (the XmlSerializer-induced memory leak mentioned in Update 1 above). It does mean, however, that I have to revert to a less optimal form of of serialization for derived types (the use of XmlInclude on the base type) until something changes in the framework to address this situation.
Psychic debugging:
Your Windows Service does XML serialization/deserialization
To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types.
If this is the case you can build these XML Serializer Assemblies a-priori.
Strange question but my boss is a touch old school and has insisted in our coding standards that we do not use C# shorthands for system types, he likes us to use the full system name. He likes things to be verbose and I happily comply with the standard.
However, something which after several months has started to grate on me is the fact that visual studio does not like to comply with the standard when completing code. So if I type:
KeyValuePair<Int32, Object> MyValue = new
Visual studio will finish the rest with:
KeyValuePair<int,object>
This is even worse when implementing an interface or abstract class.
This is a minor inconveniance but one none the less and I was wondering whether in the plethora of VS options there was one to force using the full System type names.
I believe that this can be solved use something like Re-Sharper but unfortunately there's no way I'm getting a license.
EDIT
Yes he despises the use of the var keyword. I should have stated his actual reasoning, it's because we mostly develop in C# but there is a high probability of needing to write in C and objective C so he does not want us to become too reliant upon CLR shorthands and he also says it would cause less pain when porting code which to a degree makes sense to me. His main aim with this is to avoid type mis matches with types such as Int16, Int32 & Int64 but as we are following a standard he prefers String over string. In all fairness, he is a very good coder if not a touch old school but his knowledge of things under the hood is vastly greater than mine and 90% of devs that I know, coming from a gaming background I guess makes you appreciate the finer points a touch more. I've always been spoilt with a nice managed .NET framework.
Many Thanks
Paul
My research indicates this is not possible. Maybe in a future version of Visual Studio...