Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EXC_BAD_ACCESS on mutex SQLITE_THREADSAFE sqlite3.c #192

Closed
lukescott opened this issue Aug 31, 2015 · 11 comments
Closed

EXC_BAD_ACCESS on mutex SQLITE_THREADSAFE sqlite3.c #192

lukescott opened this issue Aug 31, 2015 · 11 comments
Labels

Comments

@lukescott
Copy link
Contributor

I'm getting this crash when doing a select query (sqlite.c):

/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
  int i;
  int rc = SQLITE_OK;
  Vdbe *p = (Vdbe*)pStmt;
#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; // <----- EXC_BAD_ACCESS
#endif
  sqlite3_mutex_enter(mutex);
  for(i=0; i<p->nVar; i++){
    sqlite3VdbeMemRelease(&p->aVar[i]);
    p->aVar[i].flags = MEM_Null;
  }
  if( p->isPrepareV2 && p->expmask ){
    p->expired = 1;
  }
  sqlite3_mutex_leave(mutex);
  return rc;
}

screen shot 2015-08-31 at 10 15 04 am

What'd odd about this is it doesn't happen all the time. If I reinstall the app it sometimes doesn't happen. But once it starts happening, I usually can't get it to go away.

Any idea what could be causing this?

@lukescott
Copy link
Contributor Author

sqlite3_stmt *pStmt is NULL. Any idea how to add the SQLite.framework.dSYM to my project? When I step back I don't see the vars in the SQLite.framework methods. Last time I hit an error I added the project into mine without using the framework.

@stephencelis
Copy link
Owner

Hm, is this the master or swift-2 branch? How are you integrating? Carthage?

@lukescott
Copy link
Contributor Author

master, through carthage. I tracked it down to my FTS4 table not being created. That query is giving me no such module: fts4, which is odd because it was working before. I was using the carthage branch but switched after updating Carthage to their master. So it's using the universal version now.

The error occurs when I try to query a table that isn't there. This may be related to #187. The issue, similar to #186, is the need for better error handling.

Any idea why FTS4 is not working?

@stephencelis
Copy link
Owner

I'm not sure FTS4 is always available depending on the system library version. Could you provide the following?

  • The CREATE VIRTUAL TABLE query in its entirety
  • The version of iOS (or OS X) running (and simulator/device)
  • The version of SQLite (select sqlite_version())

@lukescott
Copy link
Contributor Author

let _barcode = Expression<String>("barcode")
let _name = Expression<String>("name")
let _level = Expression<String>("level")
let _lastUpdated = Expression<NSDate>("lastUpdated")
if db.create(table: tickets, { t in
    t.column(_barcode, primaryKey: true)
    t.column(_name)
    t.column(_level)
    t.column(_lastUpdated)
}).failed == false {
    db.create(index: tickets, on: _lastUpdated, unique: false)
    db.execute("\n".join([
        "CREATE VIRTUAL TABLE ticketSearch USING fts4(content='tickets', name);",
        "CREATE TRIGGER tickets_bu BEFORE UPDATE ON tickets BEGIN",
        "DELETE FROM ticketSearch WHERE docid=old.rowid;",
        "END;",
        "CREATE TRIGGER tickets_bd BEFORE DELETE ON tickets BEGIN",
        "DELETE FROM ticketSearch WHERE docid=old.rowid;",
        "END;",
        "CREATE TRIGGER tickets_au AFTER UPDATE ON tickets BEGIN",
        "INSERT INTO ticketSearch(docid, name) VALUES(new.rowid, name);",
        "END;",
        "CREATE TRIGGER tickets_ai AFTER INSERT ON tickets BEGIN",
        "INSERT INTO ticketSearch(docid, name) VALUES(new.rowid, new.name);",
        "END;"
    ]))
}

(Need to find a better way to detect that I need to create the table - ifNotExists makes failed always false)

Devices:

  • Simulator iPhone 5s iOS 8.4 SQLite 3.8.8.3
  • Device iPhone 5s iOS 8.1.2 SQLite 3.8.8.3

This worked at some point on the same devices (last week). I haven't updated iOS. The only thing that changed was SQLite branch and Carthage version. But even then - I would have that same EXC_BAD_ACCESS sometimes, but not all the time. -- This has also worked with FMDB on the same app without error.

@stephencelis
Copy link
Owner

If you have access to sqlite.c are you building SQLite yourself rather than using the version that comes with the iOS SDK? If so, is it built with -DSQLITE_ENABLE_FTS4 and -DSQLITE_ENABLE_FTS3_PARENTHESIS?

Is this behavior only occurring with Carthage? What's your Cartfile look like?

Regardless, EXC_BAD_ACCESS on the statement pointer is bad (misleading). Ideally the error, if valid, needs to be more straightforward.


(Need to find a better way to detect that I need to create the table - ifNotExists makes failed always false)

I generally track the schema for migrations in PRAGMA user_version.

@lukescott
Copy link
Contributor Author

Not building it myself. It's referencing it in sqlcipher. But Carthage builds that as a separate framework and I'm not including that... I don't need sqlcipher. How is that happening?

Could the SQLite.framework file be getting replaced when Carthage builds sqlcipher? If that's the case, that's another issue in itself - Carthage is building both.

@stephencelis
Copy link
Owner

Ah, that's the issue! SQLite.swift currently bundles SQLCipher support in the same repo. Because of this, SQLite.swift on the master branch actually builds twice when using Carthage: once without SQLCipher, and once with (clobbering the first build product). SQLCipher, by default, builds without FTS4 support, unfortunately.

I need to extract SQLCipher support out into its own repo. It's causing too many problems when bundled.

@lukescott
Copy link
Contributor Author

Yeah, that was it. It was a pain to get only SQLite to build. Xcode's caching is agressive. Even after I manually removed SQLiteCipher target from Carthage/Checkouts I had to clear derived data / build folder from both my project and the SQLite project.

Separating it makes sense. Although I wish you could select a scheme in Carthage:

github https://github.com/stephencelis/SQLite.swift "master" "SQLite"

@lukescott
Copy link
Contributor Author

One possible quick fix is to mark the SQLiteCipher scheme as not shared. That way Carthage will ignore it. That way you can keep SQLiteCipher where it is for now.

@lukescott lukescott changed the title EXC_BAD_ACCESS on mutes SQLITE_THREADSAFE sqlite3.c EXC_BAD_ACCESS on mutex SQLITE_THREADSAFE sqlite3.c Aug 31, 2015
@mikemee
Copy link
Collaborator

mikemee commented Jan 6, 2016

Tracking "Separate out SQLiteCipher" at #311. Closing this unless there are objections.

@mikemee mikemee closed this as completed Jan 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants