Link to home
Start Free TrialLog in
Avatar of RegProctor
RegProctorFlag for United States of America

asked on

Attempted to read or write protected memory. this is often an indication that other memory is corrupt.

Hello Experts,

I am running MySQL (installed the latest version about 2 months ago) on a windows 2000 server. I am connected to it through the MySQL ODBC version 3.51.12.

I am connecting to it through Visual Studio 2005 (VS) using VB.net on an Win XP client computer. VB works fine in reading the tables and data, writing to the DB and so on. Then, all of sudden I started getting the above error.  Looking around on the Internet others seem to have had this problem but no -one seems to have posted a solution that I have found.

Any help greatly appreciated. This is urgent because if I can't fix this I'll have to throw away most of my development and start again with another DB. Aside from the loss in development time, I like MySQL and so I am really hoping an incompatibility between the MySQL ODBC and VB.Net does not become a problem.

This is the line that the error occurs on:
            Dim CustomersChanges As DStruWest.CustomersDataTable = gDS.Customers.GetChanges()
            If Not CustomersChanges Is Nothing Then Me.CustomersTableAdapter.Update(CustomersChanges) ' ERROR ********************
This gives the same result: Me.CustomersTableAdapter.Update(DStruWest.CustomersDataTable)

When I trace all the auto-generated code it is the last line of the routine (upon returning from it) that the error actually occurs:
        <System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
        Private ReadOnly Property Adapter() As System.Data.Odbc.OdbcDataAdapter
            Get
                If (Me._adapter Is Nothing) Then
                    Me.InitAdapter
            End If
            Return Me._adapter
            End Get
        End Property

Here is the stack trace:
"   at System.Data.Common.UnsafeNativeMethods.SQLExecDirectW(OdbcStatementHandle StatementHandle, String StatementText, Int32 TextLength)
   at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, String method, Boolean needReader, Object[] methodArguments, SQL_API odbcApiMethod)
   at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, String method, Boolean needReader)
   at System.Data.Odbc.OdbcCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Odbc.OdbcCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.UpdateRowExecute(RowUpdatedEventArgs rowUpdatedEvent, IDbCommand dataCommand, StatementType cmdIndex)
   at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.Update(DataTable dataTable)
   at truWest.DStruWestTableAdapters.CustomersTableAdapter.Update(CustomersDataTable dataTable)
   at truWest.Customer.SaveData()"
Avatar of newyuppie
newyuppie
Flag of Ecuador image

what is the exception message thrown?
Avatar of RegProctor

ASKER

The exception message is:
      Message      "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

and ex.gettype() returns:

?ex.GetType
{Name = "AccessViolationException" FullName = "System.AccessViolationException"}
    System.RuntimeType: {Name = "AccessViolationException" FullName = "System.AccessViolationException"}
    Assembly: {System.Reflection.Assembly}
    AssemblyQualifiedName: "System.AccessViolationException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    Attributes: 1056769
    BaseType: {Name = "SystemException" FullName = "System.SystemException"}
    ContainsGenericParameters: False
    DeclaringMethod: {"Method may only be called on a Type for which Type.IsGenericParameter is true."}
    DeclaringType: Nothing
    DefaultBinder: {System.DefaultBinder}
    Delimiter: "."c
    EmptyTypes: {Length=0}
    FilterAttribute: {System.Reflection.MemberFilter}
    FilterName: {System.Reflection.MemberFilter}
    FilterNameIgnoreCase: {System.Reflection.MemberFilter}
    FullName: "System.AccessViolationException"
    GenericParameterAttributes: {"Method may only be called on a Type for which Type.IsGenericParameter is true."}
    GenericParameterPosition: {"Method may only be called on a Type for which Type.IsGenericParameter is true."}
    GUID: {System.Guid}
    HasElementType: False
    IsAbstract: False
    IsAnsiClass: True
    IsArray: False
    IsAutoClass: False
    IsAutoLayout: True
    IsByRef: False
    IsClass: True
    IsCOMObject: False
    IsContextful: False
    IsEnum: False
    IsExplicitLayout: False
    IsGenericParameter: False
    IsGenericType: False
    IsGenericTypeDefinition: False
    IsImport: False
    IsInterface: False
    IsLayoutSequential: False
    IsMarshalByRef: False
    IsNested: False
    IsNestedAssembly: False
    IsNestedFamANDAssem: False
    IsNestedFamily: False
    IsNestedFamORAssem: False
    IsNestedPrivate: False
    IsNestedPublic: False
    IsNotPublic: False
    IsPointer: False
    IsPrimitive: False
    IsPublic: True
    IsSealed: False
    IsSerializable: True
    IsSpecialName: False
    IsUnicodeClass: False
    IsValueType: False
    IsVisible: True
    MemberType: TypeInfo {32}
    MetadataToken: 33554500
    Missing: {System.Reflection.Missing}
    Module: {System.Reflection.Module}
    Name: "AccessViolationException"
    Namespace: "System"
    ReflectedType: Nothing
    StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
    TypeHandle: {System.RuntimeTypeHandle}
    TypeInitializer: Nothing
    UnderlyingSystemType: {Name = "AccessViolationException" FullName = "System.AccessViolationException"}
Here's some further information:

To much relief, I have solved the problem and it could just be me being very green (a newbie) with vb.net.

Here's what I found, perhaps you could enlighten me a bit:

I have a child/parent relationship on a form. When I clicked on the BindingNavigatorAddNewItem object it did a normal insert.
If I then went to the child and inserted a row I got an error to the effect that "the value (-1) must exist in the parent". So, I rechecked how I set up the relationships and all seemed well. The -1 did exist on the parent but the child was not picking it up while the record had not yet been committed. So, I put some code in that did an update on the parent table as soon as the DataGridVew (which held the child records) got the focus. Now inserting rows in the DGV no longer caused errors. Great.

Then this error started happening when I went to close the form and update everything (as the code above shows). However, I just had an idea that solved it. Right after I do an update on the parent table from the DGV getting the focus I also do an AcceptChanges. This works. What I am unsure of is why. It was my belief (remember I am very green) that the DataSet was very good at keeping track of what has been done and what needs to be done that calling AcceptChanges should be used in a very sparingly manner.

On the other hand it works and that's the most important thing at this point.

I'm wondering now if I should put an AcceptChanges after all the .update calls.
generally, the .Update method will issue an AcceptChanges call by default, unless you specify that it not do that (via the AcceptChangesDuringUpdate property - http://msdn2.microsoft.com/en-us/library/system.data.common.dataadapter.acceptchangesduringupdate.aspx)

on the issue of the -1 must exist, im guessing it has something to do with the way your dataset is updating its changes. When you add a new child, you have probably set an autonumber column to be the Private Key, and its probably set to start at -1 and substract 1 for each new record (the AutoIncrementSeed and AutoIncrementStep properties of the DataColumn - http://msdn2.microsoft.com/en-us/library/system.data.datacolumn.autoincrement.aspx). This will return errors if you haven't correctly set the method of Update (try reading this http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=189482&SiteId=1)

hope it was helpful
NY
The Child table has its own primary key (I gather you meant primary key, not private key, otherwise please do enlighten me) and so does the parent table. A non-autoincrementing field in the child table points to the parent table's primary key (PK). As I understand it the DataSet is smart enough to keep new child table entries in sync with the parent table's PK. And this is seems to be doing because it's looking for -1 and that is what it will be in the parent table at the time it looks for it. The problem is that the child table doesn't see that the parent table has the -1 value and I assumed that was because I needed to do an Update to make it viewable. I could try doing just an EndEdit on the parent table instead, I haven't tried that yet.

You are right, all that I had read suggested to set the AutoIncrementSeed and AutoIncrementStep properties to -1 and I have done so to avoid collisions with the DB.

I also have some code in a RowUpdated event of the table adapter that gets the real PK from the database when it is actually written to so as the keep the DataSet in sync with the DB. This I found necessary for successive add/deletes.
Oops. I take that back. It was actually EndEdit that I was doing already.
I found it! Ladies and gents, it was in the DataSet designer being internally corrupted. Once I removed the parent table and added it back things were better. When I removed the child table after that and added it back, it finally worked!

For anyone who gets weird errors like this. Try removing the whole table and it's adapter and adding it back again.
ASKER CERTIFIED SOLUTION
Avatar of DarthMod
DarthMod
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial