I have developed a web application with ASP.net(C#, .Net Framework 4.0) in some part of the application I am calling an API to get some information. I noticed that some of the calls to API are failed and I got this error:
Index was outside the bounds of the array.
when I checked the stack trace I saw this :
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary2.set_Item(TKey key, TValue
value)
at Navitaire.Ncl.Validation.ValidationManager.getValidationAttributes(MemberInfo mi, Boolean& skip)
at Navitaire.Ncl.Validation.ValidationManager.validate(Object declaringObject, Object value, MemberInfo mi, List1 results)
at Navitaire.Ncl.Validation.ValidationManager.Validate(Object obj)
at Navitaire.Ncl.ServiceModel.ParameterValidationInspector.BeforeCall(String operationName, Object[] inputs)
at Navitaire.Ncl.ServiceModel.Remoting.BoilerplateSinkBase.InvokeBeforeCallInspectors(StateData stateData, RemotingMessage& message)
at Navitaire.Ncl.ServiceModel.Remoting.BoilerplateServerSink.ProcessMessage(IServerChannelSinkStacksinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders&
responseHeaders, Stream& responseStream)
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders&
responseHeaders, Stream& responseStream)
I put a break point on the catch exception part, so every time that I got the error, application will stop and I can read the exception. I noticed that if in this moment I call the API again (move the cursor to the API call line) it works fine. so it means there is no problem with parameter that I am passing to the API.
I tried to run the application on three different environments with totally different network and different internet connection, but still I got the same error.
Can you please someone help me on this case?
Thanks
I suspect this is a problem with the API, rather than your code, especially if it works the second time you make the same call.
I believe the API is doing something with an internal dictionary, that doesn't quite get set up correctly the first time you call it, but by the second time, it has been and works "correctly".
Are you able to view / have access to the code for the API method your calling?
If so, you are best running that in debug alongside your application, placing a breakpoint on the entry to that method and stepping over the lines within it to see what it is doing and why it may be breaking.
If it's your API, or you're allowed to share the code of this method and you can't find the error yourself, please post up the code of the API method and I'll help you find what the cause could be.
If you are not able to view the code, I would suggest contacting the producer of the API if it's a private one, or if it's an open source API, share the link and provide a code sample of what your code looks like (showing how you make the API call) and we can help diagnose it.
I checked with the API developer and I found that there was some thing wrong on their side after they fixed the bug I did not get any error anymore.
Related
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.
We have a .net 3.5 multi-threaded windows forms application. Is is launching 4-5 background workers/ async calls to retrieve data. About 1 in 10 times, one of the threads throws the following error. Sometimes the error is a null exception instead but the same exact call stack. We have tracked the issue down to the thread somehow losing its CultureInfo. Anyone else ran into this?
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Globalization.CultureTableRecord.GetCultureTableRecord(String name, Boolean useUserOverride)
at System.Globalization.CultureTableRecord.GetCultureTableRecord(Int32 cultureId, Boolean useUserOverride)
at System.Globalization.CultureInfo..ctor(Int32 culture, Boolean useUserOverride)
at System.Globalization.CultureInfo.GetCultureByLCIDOrName(Int32 preferLCID, String fallbackToString)
at System.Globalization.CultureInfo.InitUserDefaultUICulture()
at System.Globalization.CultureInfo.get_UserDefaultUICulture()
at System.Threading.Thread.get_CurrentUICulture()
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
at System.Environment.ResourceHelper.GetResourceStringCode(Object userDataIn)
at System.Environment.GetResourceFromDefault(String key)
at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.IO.StreamWriter.Init(Stream stream, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(Stream stream, Encoding encoding, Int32 bufferSize)
at System.Web.Services.Protocols.SoapHttpClientProtocol.GetWriterForMessage(SoapClientMessage message, Int32 bufferSize)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Serialize(SoapClientMessage message)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
Try playing with default culture for entire domain using CultureInfo.DefaultThreadCurrentCulture and/or CultureInfo.DefaultThreadCurrentUICulture and see if that helps. All in all, you'll be able to ensure whether it's related to thread's culture
UPD: that specific exception may be thrown when using sync methods like lock, Monitor, etc on value types, calls to sync methods will box value, creating new one every time. I doubt it could be such serios bug in framework.
Can you check your synchronization code?
UPD2: ok, let's try to debug.
First off, turn on break on every exception thrown
Next, enable .NET Framework debugging that will help you to
locate an error
After that, there is a high chance for a workaround/solution for you problem
From just looking at the call stack, this appears to be a framework bug (of sorts). It seems that the StreamWriter constructor is performing a non-thread-safe operation (accessing GetCultureTableRecord) through a complex series of calls. My recommendation would be to serialize your calls to the StreamWriter constructor:
// Put this somewhere convenient
public static Object swConstructorLock = new Object();
then, when you create your StreamWriters:
// Lock this constructor because it does something that isnt thread-safe as per http://stackoverflow.com/questions/16113366/windows-forms-threads-are-losing-their-culture
StreamWriter myStreamWriter;
lock (swConstructorLock) {
myStreamWriter = new StreamWriter(theStreamToWrite);
}
I found that CultureInfo.ClearCachedData was being called on every web request :/ Removing that fixed the issue. There seems that Culture still needs some sort of lock since thread A calls ClearCachedData and thread B requests the data and it throws a null exception.
I got this exception (once, out of a blue), also in a .NET 3.5 app:
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Globalization.CultureTableRecord.GetCultureTableRecord(String name, Boolean useUserOverride)
at System.Globalization.CultureTableRecord.GetCultureTableRecord(Int32 cultureId, Boolean useUserOverride)
at System.Globalization.CultureInfo..ctor(Int32 culture, Boolean useUserOverride)
at System.Globalization.CultureInfo.GetCultureByLCIDOrName(Int32 preferLCID, String fallbackToString)
at System.Globalization.CultureInfo.InitUserDefaultCulture()
at System.Globalization.CultureInfo.get_UserDefaultCulture()
at System.Threading.Thread.get_CurrentCulture()
at System.Globalization.DateTimeFormatInfo.get_CurrentInfo()
at System.DateTime.ToString(String format)
This happened in a locked section, but the lock was not a value type.
I'm using Transactional NTFS to read and write to files on the filesystem and I've noticed that the application encounters intermittent faults which as only solved by an app restart.
The stack trace for the error is:
System.Runtime.InteropServices.COMException (0xD0190052): Exception from HRESULT: 0xD0190052
at ...KtmTransactionHandle.IKernelTransaction.GetHandle(IntPtr& handle)
at ...KtmTransactionHandle.CreateKtmTransactionHandle(Transaction managedTransaction)
at ...KtmTransactionHandle.CreateKtmTransactionHandle()
at ...TransactedFile.Open(String path, FileMode mode, FileAccess access, FileShare share)
at ...TransactedFile.ReadAllText(String path)
IKernelTransaction is a COM Interface that I get a handle to:
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")]
private interface IKernelTransaction
{
void GetHandle([Out] out IntPtr handle);
}
here
IKernelTransaction tx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current);
My code is very similar to http://msdn.microsoft.com/en-us/library/cc303707.aspx
The problem is that I cannot find any information of this COM error 0xD0190052. Just knowing what this error code is would be hugely helpful.
Thanks
Pure speculation
The HRESULT 0xD0190052 is very similar to STATUS_TRANSACTIONMANAGER_NOT_ONLINE which is 0xC0190052... the difference is in the "N"-Bit which indicates whether the code is a so-called NTSTATUS (see http://msdn.microsoft.com/en-us/library/0642cb2f-2075-4469-918c-4441e69c548a%28PROT.10%29.aspx and http://msdn.microsoft.com/en-us/library/cc231200%28v=PROT.10%29.aspx and http://msdn.microsoft.com/en-us/library/cc704588%28v=PROT.10%29.aspx )...
From what you describe it seems either your application sometimes looses the connection to the transaction manager or the transaction manager is unstable/restarted or similar...
Also definig PreserveSig(true) on your COM import could help getting some HRESULT description...
Hope this makes any sense in your case...
EDIT:
I am not sure that the code you linked to is taking into account all possibilities... in the method TransactedFile.Open there is a call to scope.Complete(); which is good and necessary BUT if some code before this call within the using-block throws some exception it does not get called which is bad according to http://msdn.microsoft.com/en-us/library/ms172152.aspx
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).
On a thread that is processing new data in the system, if the data is invalid I write a message in the event log, containing the Environment.StackTrace information.
Writing in the event log throws an exception with no text message
Message:
CallStack - at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace()
at <my method that writes in the event log>
Any ideas why this happens?
EDIT: I am interested in what can cause the Environment.StackTrace to throw exception in general, so that i can understand what is happening in my case
#anchandra I don't know if you have figured this out since, as this is now 4 years old.
However I would like to add as I just stumbled upon this myself.
So, why does Environment.StackTrace throws an exception?
First the most uninteresting answer:
As you can see in the MSDN reference to the property, it can throw an ArgumentOutOfRangeException if "The requested stack trace information is out of range.", note also that the executing context must have System.Security.Permissions.EnvironmentPermission.
Now what stumped me for a second:
It does NOT throw an exception! Yes, that is what was happening to me, it actually returned me a Stack Trace that started listing the call to Environment.StackTrace like "at System.Environment.get_StackTrace()" then it showed all the other calling methods.
Because I was logging this into an audit log, if you look at it you assume there is an exception occurring at the last frame of the stack, but that's not true, I was just happening to request a Stack Trace at that point and stick it in my error log, very dumb once I realized this.
You need to capture the stacktrace before moving onto a separate thread.
Stacktrace will only show you the frames up to the root of the thread.