Dhiru
Dhiru

Reputation: 3060

SQLite Error : EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) -iOS

When I am trying to insert data into my table, sometimes I get this error, and my app crashes!

enter image description here

Crash logs :

Observation(4001,0x10dd67000) malloc: *** error for object 0x7fff3a917100: Non-aligned pointer being freed (2)
*** set a breakpoint in malloc_error_break to debug
2016-11-03 11:12:03.063 Observation[4001:46477] Insertion failed !


Printing description of dbpath:
(const char *) dbpath = 0x00007fff3b8a5690 "/Users/macbt/Library/Developer/CoreSimulator/Devices/0EEC62AE-6DF0-4FC4-9D30-1EB90CB695A5/data/Containers/Data/Application/A709E729-3162-4CC8-B9FF-2F22A32FC6BD/Documents/ObservationDB.db"


Printing description of insertSQL:
insert into table_hazard (id, name, modifiedDate) values ("1","Hazard", "03/11/2016 11:12:03 AM")


Printing description of insert_stmt:
(const char *) insert_stmt = 0x00007fff3b9291a1 "insert into table_hazard (id, name, modifiedDate) values (\"1\",\"Hazard\", \"03/11/2016 11:12:03 AM\")"

Upvotes: 1

Views: 908

Answers (4)

Dhiru
Dhiru

Reputation: 3060

The solution of this type of problems is , you may be missing below statement.

 sqlite3_finalize(statement);
        sqlite3_close(database);

after every

sqlite3_open()
sqlite3_prepare_v2()

we should always finalize the statement and close the database before return statement. Don't leave database open.
without finalizing statement and without closing Database if you try to again open it sqlite3_open()

or

sqlite3_prepare_v2()

this will result in EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) regarding database .

For example:

-(BOOL) insertDropdownValues:(NSString *)tableName
                       andId:(NSInteger) dID
                        name:(NSString*) name
                modifiedDate:( NSString*) modifiedDate {

    const char *dbpath = [databasePath UTF8String];

    if (sqlite3_open(dbpath, &database) == SQLITE_OK)
    {

        NSString *insertSQL = [NSString stringWithFormat:@"insert into %@ (%@, %@, %@) values (\"%ld\",\"%@\", \"%@\")",tableName,ID,NAME,MODIFIED_DATE, dID,name,modifiedDate];

        const char *insert_stmt = [insertSQL UTF8String];


        sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);


        if (sqlite3_step(statement) == SQLITE_DONE)
        {

            NSLog(@"Inserted SuccessFull");
            sqlite3_finalize(statement);
            sqlite3_close(database);

            return YES;
        }
        else {

            NSLog(@"Insertion failed !");
            sqlite3_finalize(statement);
            sqlite3_close(database);

            return NO;
        }

    }

    sqlite3_reset(statement);
    return NO;

}

Upvotes: 1

Ahmed Sahib
Ahmed Sahib

Reputation: 213

Go for Fmdb for sqlite implementation https://github.com/ccgus/fmdb it's very easy to understand

Upvotes: 0

Manishankar
Manishankar

Reputation: 327

  • Try to set a breakpoint on malloc_error_break.

  • Set your variables to nil after you release them.

  • Go carefully over all the calls to sqlite3_prepare_v2 instructions and make sure that the matching sqlite3_finalize is called for each one of them.

  • Add @synchroinized block to make it thread safe

Upvotes: 1

KrishnaCA
KrishnaCA

Reputation: 5695

I believe the problem might be due to accessing database in different threads at the same time. You can use thread lock to solve this problem. You can write the code for database operations inside @synchronized block for solving this problem. It can be implemented as follows.

@synchronized (self) {
    // do the operation
}

Please let me know if it either works or doesn't work. Feel free to suggest edits.

Upvotes: 0

Related Questions