Just recently my app has been inconsistently throwing a variety of exceptions like these:
Unable to cast object of type 'System.Threading.Thread' to type 'System.Transactions.SafeIUnknown'.
Unable to cast object of type 'System.Diagnostics.Process' to type 'System.Transactions.SafeIUnknown'.
Unable to cast object of type 'System.Drawing.SolidBrush' to type 'System.Transactions.SafeIUnknown'.
Unable to cast object of type 'System.Threading.Thread' to type 'System.Xml.Linq.XNamespace'.
(the last one might be a secondary effect of the others)
Stack traces of some of these are pasted below but note that all of them have these 3 final steps:
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
Observations - these exceptions:
Occur frequently, but not all the time (50%?)
Don't always produce the same exception when they do occur
Have no obvious connection to the code in my app which leads to them
Are reproducible on various PCs
Can't be found exactly in any searches I've done
The app is a set of C# DLLs called via COM from older VB6 code. However that has been in place for years, and we haven't changed anything about how that is done recently.
It is not a multi-threaded app, so the casts involving System.Threading.Thread seem out of place. There was one third party module that used threads, but we took it out as an experiment: doing so did not resolve the problem but seemed to reduce the frequency of errors. This leads me to think its some kind of resource clobbering problem.
I am looking for advice such as:
If you've actually seen this pattern of exceptions before, what was the cause?
Recommendations for how to go about debugging the root issue
Example stack traces:
Unable to cast object of type 'System.Threading.Thread' to type 'System.Transactions.SafeIUnknown'.
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
at System.Data.SQLite.SQLiteConnection.Open()
at Company.ABC.WrappedDbConnection.Open()
at Company.ABC.Program.DoSomething()
and
Unable to cast object of type 'System.Threading.Thread' to type 'System.Transactions.SafeIUnknown'.
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
at System.Data.Common.ADP.IsSysTxEqualSysEsTransaction()
at System.Data.Common.ADP.NeedManualEnlistment()
at System.Data.OleDb.OleDbConnection.Open()
at Company.ABC.WrappedDbConnection.Open()
at Company.ABC.Program.DoSomething()
and
System.InvalidCastException: Unable to cast object of type 'System.Drawing.SolidBrush' to type 'System.Transactions.SafeIUnknown'.
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
at System.Data.Common.ADP.IsSysTxEqualSysEsTransaction()
at System.Data.Common.ADP.NeedManualEnlistment()
at System.Data.OleDb.OleDbConnection.Open()
at Company.ABC.WrappedDbConnection.Open()
at Company.ABC.Program.DoSomething()
EDIT:
I tried looking into this using windbg (with SOS extensions for managed code).
It was able to break on the exception. Here is the stack trace from that point:
0:000> !DumpStack
OS Thread Id: 0x2d44 (0)
Current frame: KERNELBASE!RaiseException+0x62
ChildEBP RetAddr Caller, Callee
0019b658 750325f2 KERNELBASE!RaiseException+0x62, calling ntdll!RtlRaiseException
0019b688 774a7310 ntdll!RtlFreeHeap+0x1e0, calling ntdll!RtlFreeHeap+0x560
0019b69c 70a9f09f clr+0xf09f, calling KERNEL32!TlsGetValue
0019b6ac 70b928f1 clr!GetMetaDataPublicInterfaceFromInternal+0x9741, calling KERNELBASE!RaiseException
0019b6ec 70aae56d clr!LogHelp_NoGuiOnAssert+0x2add, calling clr!LogHelp_NoGuiOnAssert+0x2a92
0019b6f8 70aae50f clr!LogHelp_NoGuiOnAssert+0x2a7f
0019b748 70bfc1a2 clr!CreateApplicationContext+0x1c2d2, calling clr!GetMetaDataPublicInterfaceFromInternal+0x95b6
0019b77c 70e3d369 clr!CreateHistoryReader+0x72069, calling clr!CreateApplicationContext+0x1c279
0019b7dc 70bc6a59 clr!PreBindAssemblyEx+0x10959, calling clr+0xf7b0
0019b80c 09364844 (MethodDesc 08e0d5b4 +0x4c System.Transactions.Transaction.JitSafeGetContextTransaction(System.Transactions.ContextData)), calling clr!LogHelp_TerminateOnAssert+0x7f00
0019b83c 09362f2f (MethodDesc 08e0d5e4 +0x9f System.Transactions.Transaction.FastGetTransaction(System.Transactions.TransactionScope, System.Transactions.ContextData, System.Transactions.Transaction ByRef)), calling (MethodDesc 08e0d5b4 +0 System.Transactions.Transaction.JitSafeGetContextTransaction(System.Transactions.ContextData))
0019b850 09362510 (MethodDesc 08e0d5fc +0x78 System.Transactions.Transaction.get_Current()), calling (MethodDesc 08e0d5e4 +0 System.Transactions.Transaction.FastGetTransaction(System.Transactions.TransactionScope, System.Transactions.ContextData, System.Transactions.Transaction ByRef))
0019b86c 08ddf67a (MethodDesc 08e04c6c +0x14b2 System.Data.SQLite.SQLiteConnection.Open()), calling (MethodDesc 08e0d5fc +0 System.Transactions.Transaction.get_Current())
0019ba70 08ddd8ea (MethodDesc 08e058b0 +0x22 Company.ABC.WrappedDbConnection.Open()), calling 0dfce43a
This syncs with the CLR exception stacks that are above.
The thing I was mainly looking to ascertain is whether there is heap "corruption". But apparently not:
0:000> !VerifyHeap
No heap corruption detected.
So I think that rules out any of our native code (or 3rd party) simply wreaking havoc. But still no actual understanding of this problem. It looks more like a bug in the database layer to me.
This has been submitted as an issue here: https://developercommunity2.visualstudio.com/t/Unable-to-cast-object-of-type-varies/1241378
I don't think this is a perfect "root cause" answer; but it is the workaround which seems to have succeeded in avoiding the exceptions.
The code in question is used to create DB connection, execute a query, then teardown the connection.
The exact change was to go from:
public class DatabaseAccessXYZ
{
IDbConnection connection;
void Execute<T>(string sql, T item)
{
using (connection = ConnectionManagerXYZ.GetConnection(Filespec))
{
connection.Open();
connection.Execute(sql, item);
}
...
to this instead:
public class DatabaseAccessXYZ
{
void Execute<T>(string sql, T item)
{
using (var connection = ConnectionManagerXYZ.GetConnection(Filespec))
{
connection.Open();
connection.Execute(sql, item);
}
...
So the scope of the connection variable was changed. It was only used in this one place anyway, it did not need to be a class-level field. Now the exception no longer occurs.
As far as I understand it, this change just means that the CLR will probably garbage collect the object sooner. But it didn’t affect anything else – for instance, the connection is still closed at the same time (right after Execute is called when the using completes and the connection is disposed) which I confirmed in the debugger.
As noted in the question since there is no heap corruption I suspect that the underlying issue is a bug, maybe in System.Transactions. Databases of different types were in use (SQLite and MS Access / Jet) so I don't think the issue could be in the actual connection objects, which would have had to differ.
Related
I'm trying to get the value of a property via reflection, but end up getting the following exception:
System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.'
Inner Exception:
InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Kinect.Interop.INuiColorCameraSettings'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{00A4B392-E315-470C-90B7-F7B4C3CE00C4}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
My code looks like the following, where src is an istance of Microsoft.Kinect.ColorCameraSettings, and propName = "Brightness":
var prop = src.GetType().GetProperty(propName);
if (prop != null)
{
return prop.GetValue(src, null);
}
I've also tried the supposedly more COM-friendly method, but with the same issue:
return src.GetType().InvokeMember(propName, System.Reflection.BindingFlags.GetProperty, null, src, null);
Most interestingly, there is nothing to suggest that src is a COM object:
src.GetType().IsCOMObject returns false
But it seems from the inner exception stack trace that the src object internally interacts with a COM object.
at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
at Microsoft.Kinect.Interop.INuiColorCameraSettings.GetBrightness(Double& pBrightness)
at Microsoft.Kinect.NuiColorCameraSettings.GetBrightness()
at Microsoft.Kinect.ColorCameraSettings.get_Brightness()
How can I get the value of this property via reflection at runtime?
Edit: Here is what the Threads window looks like when the exception is thrown
EDIT: Been meaning to update this. Solution here is to run the code on the correct thread, which in this case is a worker from the thread pool. Simply wrapping the call with a Task.Run() works well. The exception (for me at least) isn't very clear about the underlying cause.
Been meaning to update this. Solution here is to run the code on the correct thread, which in this case is a worker from the thread pool. Simply wrapping the call with a Task.Run() works well. The exception (for me at least) isn't very clear about the underlying cause.
I was struggling with getting the property values of a System.__ComObject too.
Initially, the ComObject was a java object with a few properties.
The GetType() solution didn't work for me, so I searched more and found TypeDescriptor as very useful and comfortable.
According to your setup, I think it would be:
if(TypeDescriptor.GetProperties(src).Find(propName, false) != null)
{
propval = TypeDescriptor.GetProperties(src).Find(propName, false).GetValue(src).ToString();
}
Hopefully, it will help someone.
I have a COM object SerInterface objCANinterface; which is created in VC++ 6.0 ATL
which i was able to successfully call the methods from my C# GUI.(ThreadingModel is Both when checked in registry)
But i have created a thread which has to use this object opened inside this thread to continues the process.
so i have added the following statements in my constructor class as
public MyClass()
{
// Start the thread with a ParameterizedThreadStart.
ParameterizedThreadStart start = new ParameterizedThreadStart(callBackLoad);
threadFlash = new Thread(start);
threadFlash.SetApartmentState(ApartmentState.STA);
...
}
void myFun()
{
threadFlash.Start(objCANinterface);
threadFlash.Join(); //Wai
}
[STAThread]
public void callBackLoad(object refinterface)
{
//I am not able to access objCANinterface inside my thread so i have passed the object as a parameter and trying to cast
SerInterface objSrinterface = (SerInterface)refinterface;
}
This is not successful Could you please let us know how do i solve this issue. I am getting the following error
An unhandled exception of type 'System.InvalidCastException' occurred in MyClass.exe
Additional information: Unable to cast COM object of type 'System.__ComObject' to interface type 'MYINTERFACELib.SerInterface'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{37C34F3C-0082-46F5-9974-37CEB2E1C2EE}' failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).
Please let me know how to solve this issue. Thanks in advance.
# oberfreak.........
have you tried it by using "as" as well? Wen you step down with a debugger, which type is it, is it the expected type? Are your interops included in the assembly or in a seperate file?
# oberfreak, how do i use "As", could you please let me know how to use that. My interops are included along with my exe. I was able to perfectly work out of the thread.
# Hans Passant:
You forgot to register the type library in your .rgs script and you also didn't create the proxy/stub project. A threading model of Both still requires an object to be marshaled when it was created on an STA thread and used on another STA thread. Which tends to make it pointless to create a new thread. Get ahead by creating the object on the worker thread instead.
# Hans Passant : I have registered my type library and interop also created in the C# which is making me to use inside my C# code.I cannot create a new object as I need to use the same object to continue the CAN sequence commands. Could you please provide any sample for better marshalling inside a thread.
I have unregistered/removed the reference from the Exe and have registered and added the reference back to the tool. Then it worked with the parameter thread passing which made as STA thread. Thanks for the answers proposed.
I'm write XML AJAX Service with OPC server. XML AJAX Service based on this example.
And I made my service with single attribute:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
And next step I'm create class destructor:
~BoilerService()
{
try
{
ReadTimer.Dispose();
group.ReadCompleted -= new ReadCompleteEventHandler(group_ReadCompleted);
group.Remove(true);
server.Disconnect();
}
catch (Exception e)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("log.txt", true);
sw.WriteLine(DateTime.Now.ToString() +e.Message+ " "+ e.Source+" "+e.StackTrace + " destructor called.");
sw.Close();
sw.Dispose();
}
}
But when I rebuild my solution in VS (files replaced in app path) I get wp3.exe unhandled exception error window (Windows 7). And in Windows event log I see folowing text:
Exception: System.Runtime.InteropServices.InvalidComObjectException
Message: COM object that has been separated from its underlying RCW cannot be used.
StackTrace: at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, Boolean& pfNeedsRelease)
at OPC.Data.Interface.IOPCServer.RemoveGroup(Int32 hServerGroup, Boolean bForce)
at OPC.Data.OpcGroup.Remove(Boolean bForce)
at OPC.Data.OpcGroup.Finalize()
What did I do wrong?
And VS 2010 give warnings:
1. 'System.Runtime.InteropServices.UCOMIEnumString' is obsolete: 'Use System.Runtime.InteropServices.ComTypes.IEnumString instead. http://go.microsoft.com/fwlink/?linkid=14202'.
2. 'System.Runtime.InteropServices.UCOMIConnectionPointContainer' is obsolete: 'Use System.Runtime.InteropServices.ComTypes.IConnectionPointContainer instead. http://go.microsoft.com/fwlink/?linkid=14202'
May be this error appear because of for this warnings?
According to the MSDN documentation
The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already finalized when the finalizer of Object A starts.
What this means is that if group is elegible for collection at the same time as your OpcGroup instance (which seems very likely) it may well be that group has already been finalised which could easily be the cause of your failure.
It looks like you are coming from a C++ background, in which case you should be aware that finalisers work differently in C# - its very rare that you ever need to implement a finaliser. I would recommend that instead of doing this clean up in your finaliser you instead implement IDisposable and do this work when the object is disposed.
Also you don't normally need to un-hook event handlers (unless the event may still be fired and could cause an exception after an object has ben disposed). This sort of clean up is handled for you.
im using the following pattern for translating win32 exceptions into .NET exceptions.
var result = A_KERNEL32_PINVOKE_CALL();
if (result == 0)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
For completeness the pinvoke call is one of the following: LoadLibrary, GetProcAddress, SetWindowsHookEx.
This works well most of the time, throwing exceptions like this one:
System.ArgumentException: Argument out of range.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
But sometimes I get the following exception:
System.NotSupportedException: This Stream does not support seek operations.
at System.Net.ConnectStream.get_Position()
at System.Net.WebClient.WebClientWriteStream.get_Position()
at System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64 offset, Int32 origin)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
I can't think of a reason for this exception. Please note that the stack trace doesn't start with ThrowExceptionForHRInternal like the first exception. Hence I think this might be a exception of the ThrowExceptionForHR method itself.
EDIT: Please note that I'm not calling any Stream methods directly. However the code is executed in a thread pool thread, so there might be other code in the same thread using Stream methods.
Any suggestions how to solve this issue?
UPDATE: I just found out, that the stack trace
at System.Net.ConnectStream.get_Position()
at System.Net.WebClient.WebClientWriteStream.get_Position()
at System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64 offset, Int32 origin)
belongs to a call to Image.Save(Stream, Format). There a the NotSupportedException is caught. These code peaces are completely independant, but maybe they are executed on the same thread pool thread.
So why does this exception influence my code in another method?
By now I think, that I misused the Marshal.ThrowExceptionForHR() method. I suppose that it's not intended to be used with a Win32 call. My interpretation of the behavior is, that the function uses context information of the current thread to gather more details about the exception. See this blog for a similar problem.
In my case the issue can be solved by creating my own ThrowExceptionForWin32ErrorCode(errorCode) method.
Please keep answering, if you got a better solution.
I don't know why ThrowExceptionForHRInternal tries to manipulate some stream.
While call stack looks strange, consider not passing stream directly from Web response to drawing functions which seem to cause exception in your case but copy data to memory stream first. This will likely allow you to see what original problem is (as ThrowExceptionForHRInternal will no longer fail trying to manipulate a stream).
I have an unusual case where I have a very simple Exception getting thrown and caught in the same method. It isn’t re-thrown (the usual kind of problem naïve programmers have). And yet its StackFrame contains only one the current method. Here’s what it looks like:
at (my class).MyMethod() in C:\(my file path and line)
In reality there are probably 30 methods leading up to this in the VS2010 debugger's call stack, going across half a dozen different assemblies. It seems impossible for all that to have been optimized out. Moreover, this code is built in debug mode, without optimizations, for .NET 4. I even have (based on http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini files (including one named [app].vshost.ini) in the same folder containing:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Also, the method calls are not at the end of methods, so tail-recursion optimization seems further unlikely.
As to how it is called: there are no uses of reflection on the call stack, no Invoke() or BeginInvoke() of any kind. This is just a long chain of calls from a button click. The click handler is about 10 calls down the call stack. Beneath that you have the usual WndProc, NativeWindow.Callback, native/managed transitions, and message loop. This is ultimately inside a ShowDialog() call which is run from a C# EXE assembly.
Now, I found that I can construct instances of the StackTrace class in my catch handler, and if I pass the Exception object, the call stack is also short. If instead I just call new StackTrace() with no arguments, it yields a complete call stack.
I’ve used Reflector in an attempt to debug into the internals of the Exception class getting thrown and its call stack constructed, but I couldn’t set breakpoints in Exception or in StackTrace. I could set them in Environment.GetStackTrace() and this method (which Exception calls) does not appear to get called during the construction and throwing process, but I don’t know if the debugger is really working properly. (This method does get triggered for some other things though, so I'm not sure what to make of it.)
Here’s an excerpt of the method:
private void MyMethod()
{
...
try
{
throw new ApplicationException("Test failure");
}
catch (Exception e)
{
StackTrace stackTrace1 = new StackTrace(e);
StackTrace stackTrace2 = new StackTrace(e, false);
StackTrace stackTrace3 = new StackTrace(e, true);
StackTrace stackTrace4 = new StackTrace();
string STs = stackTrace1.ToString() + "\n---\n"
+ stackTrace2.ToString() + "\n---\n"
+ stackTrace3.ToString() + "\n---\n"
+ stackTrace4.ToString();
Log(EventSeverity.Debug, STs);
...
}
}
It’s really pretty simple: Throw exception, catch and log it.
I get the same results either in the debugger or when running standalone—a one-line call stack. And I know I have seen this problem elsewhere in our code base. Previously I had assumed it was due to re-throwing exceptions, but in a lot of cases it we log right inside the initial catch block. I’m quite baffled and all the web searching I’ve done hasn’t produce anything.
This is a little too much to add as a comment to the answer provided, but here's some more information:
I now see that this behavior is discussed at
http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/ and that it is actually described at http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx (though I think one could easily miss what they're saying there).
So I guess my "solution" will be a little hit-or-miss. We have a central method we usually call to format exceptions. Inside that method, I'll create a new StackTrace() both with and without the Exception object. Then I'll look for the method that is at the bottom of the Exception's stack trace, and display everything beneath that in the new StackTrace(), indicating it was called by that series of calls.
The down side of course is that if this method isn't used, the information won't be there. But I had to expect some kind of code change somewhere.
When an exception is thrown, only a partial stack trace will be used in the Exception.StackTrace property. The stack only shows calls up until the method that is catching the exception. To get the full stack (as you have noted) you should create a new StackTrace() object.
I can't find any links on it at the moment but I believe the stack trace is built by walking up the stack while throwing the exception. Once the exception reaches a catch block, the stack stops being compiled. Therefore, you only get a partial stack.
Typically, a catch block is not concerned with who called it, but where the exception is originating from.