I have written an application for the iPhone called Grocery iQ that
uses SQLite.  I don't link to or use the built-in SQLite library on
the iPhone.  Instead, I compile the SQLite amalgamation into the
executable.  The SQLite version currently being used in our app is
3.6.7.

We have been working hard on a new update for our application, which
we first submitted to Apple about 3 weeks ago.  They rejected our
update because they said it crashes on startup.  However, in our
testing (100+ hours of QA on 15+ different devices), we have never
once seen the app crash like they are claiming.

Hoping that maybe our first submission was just an incorrectly signed
executable or a corrupt upload, I rebuilt and resubmitted the app.  It
got rejected again for the same reason.

Apple sent us crash logs, which show it crashing deep in SQLite code.
However, the crash is at an odd place.  We still cannot reproduce this
crash locally, so I'm reaching out for some help on this issue.

The crash logs are all the same, here is the stack trace:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000d
Crashed Thread:  0

Thread 0 Crashed:
0   Grocery iQ                        0x0002d006 sqlite3ExprCodeTarget
(sqlite3.c:57600)
1   Grocery iQ                        0x0002d648 sqlite3ExprCodeTemp
(sqlite3.c:57879)
2   Grocery iQ                        0x0002cde4 sqlite3ExprCodeTarget
(sqlite3.c:57493)
3   Grocery iQ                        0x0002d648 sqlite3ExprCodeTemp
(sqlite3.c:57879)
4   Grocery iQ                        0x0002cde4 sqlite3ExprCodeTarget
(sqlite3.c:57493)
5   Grocery iQ                        0x0002d648 sqlite3ExprCodeTemp
(sqlite3.c:57879)
6   Grocery iQ                        0x0002cde4 sqlite3ExprCodeTarget
(sqlite3.c:57493)
7   Grocery iQ                        0x0002dade sqlite3ExprCode
(sqlite3.c:57894)
8   Grocery iQ                        0x00042ef0 sqlite3Update (sqlite3.c:77390)
9   Grocery iQ                        0x000447de sqlite3Parser (sqlite3.c:84117)
10  Grocery iQ                        0x00045f7a sqlite3RunParser
(sqlite3.c:85471)
11  Grocery iQ                        0x000464fa sqlite3NestedParse
(sqlite3.c:60739)
12  Grocery iQ                        0x00048370
sqlite3AlterFinishAddColumn (sqlite3.c:59173)
13  Grocery iQ                        0x00045b16 sqlite3Parser (sqlite3.c:84603)
14  Grocery iQ                        0x00045f7a sqlite3RunParser
(sqlite3.c:85471)
15  Grocery iQ                        0x000487ee sqlite3LockAndPrepare
(sqlite3.c:71412)
16  Grocery iQ                        0x0003c41e sqlite3_exec (sqlite3.c:71549)
17  Grocery iQ                        0x0000ce44 -[SQLDatabase
execQuery:] (SQLDatabase.m:122)
18  Grocery iQ                        0x00002c42
-[GroceryIQAppDelegate upgradeSchema2To3] (GroceryIQAppDelegate.m:281)
19  Grocery iQ                        0x00003218
-[GroceryIQAppDelegate upgradeSchemaToLatestVersion]
(GroceryIQAppDelegate.m:377)
20  Grocery iQ                        0x00003600
-[GroceryIQAppDelegate ensureDatabases] (GroceryIQAppDelegate.m:442)
21  Grocery iQ                        0x00002250
-[GroceryIQAppDelegate initApp] (GroceryIQAppDelegate.m:68)
22  Grocery iQ                        0x000026b8
-[GroceryIQAppDelegate applicationDidFinishLaunching:]
(GroceryIQAppDelegate.m:143)
23  UIKit                             0x30a4ef24 -[UIApplication
performInitializationWithURL:asPanel:] + 160
24  UIKit                             0x30a57dec -[UIApplication
_runWithURL:] + 644
25  Foundation                        0x306945a2 __NSFireDelayedPerform + 326
26  CoreFoundation                    0x30269d88 CFRunLoopRunSpecific + 2642
27  CoreFoundation                    0x30269320 CFRunLoopRunInMode + 44
28  GraphicsServices                  0x31567e58 GSEventRunModal + 268
29  UIKit                             0x30a4fa6c -[UIApplication _run] + 520
30  UIKit                             0x30a591d0 UIApplicationMain + 1132
31  Grocery iQ                        0x00002090 main (main.m:6)
32  Grocery iQ                        0x0000202c start + 44

The SQL statement it is crashing on is an ALTER TABLE command:

    ALTER TABLE listitems ADD COLUMN 'storeid' INTEGER DEFAULT NULL

Before this statement, the app has already successfully executed
several SQL statements that create and populate other tables.  The
listitems table already exists at the time of the ALTER TABLE
execution.
It is the first ALTER TABLE statement executed against the database.

Other important details about our application:

* we have licensed the CEROD extension for SQLite and it, too, is
compiled into our app.  It's capabilities are not used for this
database, though.
* the database is created with the following call:
sqlite3_open_v2([mPath fileSystemRepresentation], &mDatabase,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nil);
* there is only one connection open to the database
* before opening the database, the only other SQLite API calls are:
        sqlite3_config(SQLITE_CONFIG_HEAP, &mSqliteMemory[0], 3145728,
512); // mSqliteMemory is declared as: unsigned char
mSqliteMemory[3145728];
        sqlite3_activate_cerod(...);
* the reason we limit the heap is because the iPhone has limited
resources and we were getting some out of memory errors from other
parts of the application on some devices due to the amount of memory
that SQLite was using
* we set 3 preprocessor defines that affect SQLite compilation:
        SQLITE_ENABLE_MEMSYS5=1
        SQLITE_ENABLE_CEROD=1
        SQLITE_ENABLE_FTS3=1

According to the crash logs, the code where the crash is occurring is
in the sqlite3ExprCodeTarget function, here is some of the surrounding
code:

#ifndef SQLITE_OMIT_VIRTUALTABLE
      if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){
        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr);
      }else if( nExpr>0 ){
        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr);
      }
#endif
/* line 57600*/ for(i=0; i<nExpr && i<32; i++){ // <<===-------------
this is the offending line of code
        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
          constMask |= (1<<i);
        }
        if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
          pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
        }
      }

This code is from the SQLite 3.6.7 amalgamation, from the switch
statement in sqlite3ExprCodeTarget, for cases TK_CONST_FUNC and
TK_FUNCTION.

As you can see, the line of code where the crash occurs is not
dereferencing or using any pointers, it's only accessing ints on the
stack.  The stack must've been clobbered?

I'm at a loss of what to do.  I've asked Apple iPhone Developer
technical support for help, but the turnaround time for that is
currently 2-3 weeks, which is unacceptable.  The Apple app store
application review team also has not been of any help to me.  Since I
cannot reproduce this, and have never seen it in all of our testing, I
am inclined to believe the underlying cause of the crash is somehow
related to how the app review people test the application.  Either
their test devices or environment differ from a standard iPod touch or
iPhone in a way that I cannot replicate locally.  That's just my
theory, though.

I'd greatly appreciate it if one of you SQLite gurus could take a look
and see if I'm doing anything obviously wrong.  I can provide more
details if necessary.  I may also be willing to purchase technical
support from the SQLite developers, if needed.

Jason Boehle
jboe...@gmail.com
ja...@freestatelabs.com
jboe...@couponsinc.com
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to