Accessing member of Microsoft.SqlServer.Management.Smo.Server object crashes exactly once - c#

We are trying to access the DefaultFile member of an Microsoft.SqlServer.Management.Smo.Server object. After a lot of debugging, it turns out that accessing the member crashes the first time, but can then be accessed just fine. Looking at the variable in a debug window returns an exception the first time, the correct value the second and all following times.
The first access of either server.DefaultFile or server.DefaultLog throws an exception like this:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Microsoft.SqlServer.Management.Smo.BitStorage.SetBit(Int32 itemIndex, BitIndex bitIndex, Boolean value)
at Microsoft.SqlServer.Management.Smo.PropertyCollection.SetRetrieved(Int32 index, Boolean val)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.AddObjectPropsFromDataReader(IDataReader reader, Boolean skipIfDirty, Int32 startColIdx, Int32 endColIdx)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.ImplInitialize(String[] fields, OrderBy[] orderby)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.Initialize(Boolean allProperties)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.OnPropertyMissing(String propname, Boolean useDefaultValue)
at Microsoft.SqlServer.Management.Smo.PropertyCollection.GetValueWithNullReplacement(String propertyName, Boolean throwOnNullValue, Boolean useDefaultOnMissingValue)
at Microsoft.SqlServer.Management.Smo.Server.get_DefaultFile()
at my function... etc etc
The first-access-crash is very concistent, so doing something terrible like below gets around the problem completely:
using (var sqlConnection = new SqlConnection(sourceDatabaseConnectionString.ConnectionString))
{
var svrConnection = new ServerConnection(sqlConnection);
var server = new Server(svrConnection);
// begin mega hack
try
{
// crashes on first access
var dummy = server.DefaultFile;
}
catch
{
// do absolutely nothing
}
// end mega hack
// business as usual...
var defaultFile = server.DefaultFile;
}
Of course, we don't like code like this (even if it's only in our internal tools) so any ideas of why this might be happening is welcome. Our only clue is that we've recently upgraded some instances of SQL Server 2012 to SQL Server 2014. We can sometimes get around the issue when running the code locally on a machine with SQL Server 2014 installed. The production machine that runs this code does not have an installation at all, but references DLLs. However, we can't find any differences in the versions used when debug printing the assembly versions while running the code.

I've seen similar messages when using an older version of SMO, especially when trying to use 2008R2 SMO to access 2012. Upgrading to the installs from 2008R2 Featurepack SP3 fixed my issues.
Check that there's not a more recent version of the Shared Management Objects + CLR Types + Native client driver that you could use.

Related

SQLite BackupDatabase method is throwing exception after upgrading to version 1.0.111.0

I am upgrading System.Data.SQLite from version 1.0.93.0 to 1.0.111.0
I am having a method which copies the SQLite database on disk to in memory. It is working fine with version 1.0.93.0 and here's the code in VB.Net
Dim sourceConn = CType(_connection, System.Data.SQLite.SQLiteConnection)
Dim destConn = CType(destDBM._connection, System.Data.SQLite.SQLiteConnection)
sourceConn.BackupDatabase(destConn, "main", "main", -1, Nothing, 0)
where path of destination SQLite is in memory by using ":memory:" instead of path.
After upgrading to version 1.0.111.0, it throws the below exception
code = Unknown (-1), message = System.Data.SQLite.SQLiteException (0x80004005): unknown error
failed to initialize backup
at System.Data.SQLite.SQLite3.InitializeBackup(SQLiteConnection destCnn, String destName, String sourceName)
at System.Data.SQLite.SQLiteConnection.BackupDatabase(SQLiteConnection destination, String destinationName, String sourceName, Int32 pages, SQLiteBackupCallback callback, Int32 retryMilliseconds)
Does anyone have any idea that how to get it solved?
I am able to find out the root cause of this issue myself. Actually, I was starting a transaction in destination database before backup. It was working fine in the older version but the behavior is changed in the latest version and exception is not meaningful at all.
To fix it, I have re-ordered the code which was initiating transaction as the next step after taking backup. It's working as expected now and insertions are way too fast in the latest version. Great work by SQLite team!

getting Mono with firebird-embedded working on 64bit Linux environment

I'm trying to get Firebird-embedded 2.5 (64bit) on Linux with firebird .net provider (FirebirdSql.Data.FirebirdClient) working.
The FB embedded setup for my Test assembly is working on WinX86_64 with the Windows Firebird Embedded version.
On Linux I use the coresponding FB embedded Linux version placed files in the assembly directory:
libfbembed.so*
firebird.msg
security2.fdb
libicu*
libib*
Set the "RootDirectory" to assembly directory in the firebird.conf.
Set the shell environment variables LD_LIBRARY_PATH and FIREBIRD to to assembly directory.
FbConnectionStringBuilder conn = new FbConnectionStringBuilder();
conn.Database = #"/home/dev/firebirdTest/1stDB.FDB";
conn.ServerType = FbServerType.Embedded;
conn.UserID = "SYSDBA";
conn.Password = "masterkey";
conn.Charset = "UTF8";
conn.DataSource = "localhost";
conn.ClientLibrary = "libfbembed.so";
string connStr = conn.ConnectionString;
var dbcon = new FbConnection(connStr);
FbConnection.CreateDatabase(connStr, pageSize: 8192, forcedWrites: true, overwrite: false);
dbcon = new FbConnection(connStr);
dbcon.Open();
what I did before:
Redirecting the Firebird Clientlibrary by mono dllmap doesn't work. Solved by explicit setting the ClientLib in C# code.
manually creating a Database with isql on Linux works.
creating a Database by code on Linux works.
the Firebird .NET provider creates in debug mode the FB_{sanitizedName}.dll and DynamicAssembly.dll
the .NET provider is really silent. Debugging was done by starting the assembly with "strace mono {testAssembly.exe}" on linux.
FbConnection.CreateDatabase crashes with I/O error during "open O_CREAT" (calling FbCreateDatabase), if pagesize is not 8192. Setting explicit pagesize to 8192 solves this.
Now, I run in following errors ( and stuck here for days...):
Opening an existing Databasefile (like in the code here), crashes with:
FirebirdSql.Data.FirebirdClient.FbException: invalid database handle (no active connection) ---> invalid database handle (no active connection)
What's going wrong?
I've stuck with this error too.
FirebirdSql.Data.FirebirdClient.FbException: invalid database handle (no active connection)
Tried with FB 2.5.* and 3.0.0 results are the same.
Also tried using debug builds of FB. Logs did not help.
Maybe somebody here knows what the problem is?
It's 3 years since the original post, and I've run into the same problem. I don't have an "answer" but I do have an explanation. It appears the marshalling of SafeHandle objects isn't fully implemented in mono. From their documentation on SafeHandle: "Notice that “ref SafeHandles” pass a pointer to a slot containing zero to P/Invoked methods, and on return the a new SafeHandle is created with the returned value. “ref SafeHandles” do not actually get the original SafeHandle.handle value."
If you look into the FirebirdClient source, in IFbClient, you'll see the P/Invoke declarations look like:
IntPtr isc_detach_database(
[In, Out] IntPtr[] statusVector,
[MarshalAs(UnmanagedType.I4)] ref DatabaseHandle dbHandle);
DatabaseHandle is derived from SafeHandle, so the second argument is a "ref SafeHandle" argument, and suffers from the problem noted above - it will basically pass in a zero rather than the actual handle value.
There is no fix other than to (a) improve the SafeHandle implementation in mono, or (b) rewrite FirebirdClient to avoid the use of SafeHandles.

Visual Studio 2015 has problems communicating using VISA Libraries

I'm having problems with the VISA-Com Libraries to communicate with a Keysight (N6700B) power supply.
I have some C# code I am compiling in Visual Studio 2015, and it does not work. However, if I compile the same code in Visual Studio 2012, then it works.
Basically I am just doing simple communication with the device:
using Ivi.Visa.Interop;
//...
string address = "USB0::2391::2311::MY54002380::0::INSTR";
ResourceManager rm = new ResourceManager();
FormattedIO488 myDmm = (IMessage)rm.Open(address , AccessMode.NO_LOCK, 2000, "");
myDmm.WriteString("*RST"); // reset the device
myDmm.WriteString("*IDN?"); // request the IDN string;
string IDN = myDmm.ReadString(); // This is where it fails, returning: "VI_ERROR_TMO: A timeout occurred"
Also, the power supply has an error state of: "Error -420, Query UNTERMINATED"
The code does not work with VS2015, but it DOES work with VS2012.
(In VS2012 I get no errors at all.)
I have tried downloading the latest drivers from KeySight, and it still does not work (www.keysight.com/find/iosuitedownload).
Does anyone have any idea why it would be breaking with VS2015 but work with VS2012?
I've looked up "Quere Unterminated" and some say that it could be a missing Termination character "\n". I've tried adding the "\n" to both writeStrings, and it still fails.
EDIT: I have also now tried using (in various places):
myDmm.IO.TerminationCharacterEnabled = true; // and = false
myDmm.FlushWrite(); // also tried passing in "true" (default is 'false')
I also tried adding the:
myDmm.IO.TerminationCharacter
to the WriteStrings.
http://download.ni.com/support/softlib//visa/NI-VISA/15.0/Windows/readme.html
Microsoft Visual Studio Support
The following table lists the programming languages and Microsoft Visual Studio versions supported by this version of NI-VISA.
Earlier versions of NI-VISA support other application software and language versions. For more information on Visual Studio compatibility with earlier versions of VISA, refer to ni.com/info and enter the info code NETlegacydrivers. To find and download an earlier version of a driver, refer to ni.com/downloads.
Visual Studio Versions Support by NI-VISA:
Visual C++ MFC1 -------------- 2008
Framework 3.5 Languages (Visual C# and Visual Basic .NET) -- 2008
.NET Framework 4.0 Languages (Visual C# and Visual Basic .NET)-- 2010
.NET Framework 4.5 Languages (Visual C# and Visual Basic .NET)-- 2012
So apparently the drivers don't work with VS2015... (not sure how a newer version doesn't work.. but okay)
EDIT, FOUND ANSWER
Someone from NI-VISTA told me to just add "true" as a second parameter:
myDmm.WriteString("*RST",true); // reset the device
myDmm.WriteString("*IDN?",true); // request the IDN string;
string IDN = myDmm.ReadString(); // now it works.
I'm not sure why "true" wasn't needed in 2012, and why it is needed in 2015... oh well.
I confirm: the method WriteString() (but not only this) needs the bool parameter flushAndEND = true (default value = false) in order to complete the command. Without it, the instrument can't parse the instruction. If you send multiple commands, the instrument can't separate and identify them.
I suggest you to use the Keysight IO monitor for sniffing the communication between your instruments and you controller (PC?) . It's an utility of the IO Libraries Suite (v17.1).
For details, see the attached IFormattedIO488 interface definition, belonging to the reference Ivi.Visa.Interop.
using System.Runtime.InteropServices;
namespace Ivi.Visa.Interop
{
[...]
public interface IFormattedIO488
{
[DispId(1610678274)]
bool InstrumentBigEndian { get; set; }
[DispId(1610678272)]
IMessage IO { get; set; }
void FlushRead();
void FlushWrite(bool sendEND = false);
dynamic ReadIEEEBlock(IEEEBinaryType type, bool seekToBlock = false, bool flushToEND = false);
dynamic ReadList(IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, string listSeperator = ",;");
dynamic ReadNumber(IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, bool flushToEND = false);
string ReadString();
void SetBufferSize(BufferMask mask, int size);
void WriteIEEEBlock(string Command, object data, bool flushAndEND = false);
void WriteList(ref object data, IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, string listSeperator = ",", bool flushAndEND = false);
void WriteNumber(object data, IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, bool flushAndEND = false);
void WriteString(string data, bool flushAndEND = false);
}
}
Have you tried the ReadBytes method? This method reads a fixed amount of bytes from the device. The error you've encountered most probably occurs because the the visa driver tries to read data until a termination character, which you never explicitly set, is received.
Try setting the TerminationCharacter Property to either \n or \r (depending on the instrument) and it should work. Furthermore, you might want to add it to the commands you send as well so the instrument won't bother you with this error (-420) anymore.

Linq 'Index was outside the bounds of the array' problem

In trying to setup a unit test for inserting an item into an SQL Server Express (2008) database using C# Linq I've encountered an error that is causing me some trouble. The Linq code is built using Visual Studio 2008.
The exception is thrown on a system running Windows XP SP2. The Linq works fine and the record is inserted appropriately on a system running Windows 7 Home Premium (64-bit).
I've dropped and re-created the database on the XP system. I've dropped and re-created the DAL and corresponding DBML on the XP system.
Other tables with unit tests for inserts to the same database work just fine.
Inserting a record into the table using a simple insert statement in SQL Server Management Studio works appropriately.
What should I look at to find the source of the problem? What should be done to resolve the problem?
Any insight as to what the error message is really trying to say would be greatly appreciated.
Error Message
System.IndexOutOfRangeException : Index was outside the bounds of the array.
Stack Trace
at
System.Data.Linq.IdentityManager.StandardIdentityManager.MultiKeyManager`3.TryCreateKeyFromValues(Object[] values, MultiKey`2& k)
at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues)
at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues)
at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues)
at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance)
at System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at nUnit.DAL.FacilityTests.AddFacility2() in C:\SVN\SVNRevenue360\Branches\Dev\Code\ProviderAdvantage\nUnit.CoreTests\Tests\DAL\FacilityTests.cs:line 50
Insert Code
[Test]
public void AddFacility2() {
string facilityname = "Test Facility";
try {
using (PA.Database.Revenue360DB db = new PA.Database.Revenue360DB(PA.DAL.DataAccess.ConnectionString)) {
db.Log = Console.Out;
PA.Database.Facility facility = new PA.Database.Facility();
facility.id = Guid.NewGuid();
facility.Name = facilityname;
facility.Street1 = "";
facility.Street2 = "";
facility.Street3 = "";
facility.City = "";
facility.State = "";
facility.Zip = "";
facility.Description = "";
db.Facilities.InsertOnSubmit(facility);
db.SubmitChanges(); // line 50
}
} catch (Exception ex) {
Console.WriteLine(ex.GetType().FullName + ": " + ex.Message);
Console.WriteLine(ex.InnerException == null ?
"No inner exception" :
ex.InnerException.GetType().FullName + ": " + ex.InnerException.Message);
throw;
}
}
I've looked at the following SO questions without insight as to what is causing this particular issue.
https://stackoverflow.com/questions/1087172/why-am-i-getting-index-was-outside-the-bounds-of-the-array
IndexOutOfRangeException on Queryable.Single
Strange LINQ Exception (Index out of bounds)
Take a look at this link.
Here are a few excerpts:
A common cause of this error is
associations pointing in the wrong
direction. (Something that is
extremely easy to do if editing the
model by hand, partly because the
association arrow pointer is in the
opposite end of where it would appear
in an ER diagram)
and
I was having the same problem and it
was due to the fact my primary key was
two columns instead of the traditional
one. (both guids). When I added a
third column that was the sole primary
key column, it worked.
UPDATE: Did some more poking around and found this SO post. Looks like it might have something to do with your DBML...
If the code is working on one machine and not working on another the problem should be somewhere outside. Please check if the .NET Framework version on Windows XP is the same as on Windows 7. Secondly, if its XP SP2 then the Operating System might be the cause because Microsoft has changed a lot in SP3. Also check if the database has same tables. Try to reproduce the problem on the same db, i.e. take backup from Win7 and restore it on the XP (of cause backup your data first). What else? Security permissions and connection string might have an impact too.

IDataRecord.IsDBNull causes an System.OverflowException (Arithmetic Overflow)

I have a OdbcDataReader that gets data from a database and returns a set of records.
The code that executes the query looks as follows:
OdbcDataReader reader = command.ExecuteReader();
while (reader.Read())
{
yield return reader.AsMovexProduct();
}
The method returns an IEnumerable of a custom type (MovexProduct). The convertion from an IDataRecord to my custom type MovexProduct happens in an extension-method that looks like this (abbrev.):
public static MovexProduct AsMovexProduct(this IDataRecord record)
{
var movexProduct = new MovexProduct
{
ItemNumber = record.GetString(0).Trim(),
Name = record.GetString(1).Trim(),
Category = record.GetString(2).Trim(),
ItemType = record.GetString(3).Trim()
};
if (!record.IsDBNull(4))
movexProduct.Status1 = int.Parse(record.GetString(4).Trim());
// Additional properties with IsDBNull checks follow here.
return movexProduct;
}
As soon as I hit the if (!record.IsDBNull(4)) I get an OverflowException with the exception message "Arithmetic operation resulted in an overflow."
StackTrace:
System.OverflowException was unhandled by user code
Message=Arithmetic operation resulted in an overflow.
Source=System.Data
StackTrace:
at System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i)
at System.Data.Odbc.OdbcDataReader.IsDBNull(Int32 i)
at JulaAil.DataService.Movex.Data.ExtensionMethods.AsMovexProduct(IDataRecord record) [...]
I've never encountered this problem before and I cannot figure out why I get it. I have verified that the record exists and that it contains data and that the indexes I provide are correct. I should also mention that I get the same exception if I change the if-statemnt to this: if (record.GetString(4) != null). What does work is encapsulating the property-assignment in a try {} catch (NullReferenceException) {} block - but that can lead to performance-loss (can it not?).
I am running the x64 version of Visual Studio and I'm using a 64-bit odbc driver.
Has anyone else come across this? Any suggestions as to how I could solve / get around this issue?
Many thanks!
For any one experiencing the same issue, the way I solved this was to switch from the Odbc* classes to their OleDb* counterparts. This of course demands that your data driver has support for OleDb connections.
Which DB are you trying to talk to? If it uses some "private" column types that can cause problems. That doesn't apply to SQL Server of course :-)
Also check that you are compiling and running as x64 (Process Explorer will show you thsi and even plain tack manager shows it). devenv.exe will still be x86 but your actual binary should run as x64. The reason I mention is that crossing 32/64 bit boundary is notorious for breaking 3rd party ODBC drivers.

Categories

Resources