Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Monaj

macrumors regular
Original poster
May 24, 2009
193
0
Hi all,

I have included SQLite3 db within a cocoa application, from a Leopard system and saving and retrieving some data from it.

Problem is - although it is running fine on Leopard, it is crashing on Snow Leopard.

Part of the crash report is as follows:

Code:
    Process:         RCS [84283]
    Path:            /Volumes/RCS Project/~RCS APPLICATIONS/~RCS (Macintosh)/2011/26-January 2011/RCS.app/Contents/MacOS/RCS
    Identifier:      com.tprf.RCS
    Version:         2.0 build-0235 (2.0)
    Code Type:       X86 (Native)
    Parent Process:  launchd [173]
    
    Date/Time:       2011-01-04 07:51:59.950 -0800
    OS Version:      Mac OS X 10.6.5 (10H574)
    Report Version:  6
    
    Interval Since Last Report:          494528 sec
    Crashes Since Last Report:           24
    Per-App Interval Since Last Report:  25 sec
    Per-App Crashes Since Last Report:   2
    Anonymous UUID:                       A9023F03-79EA-4444-B7BF-25AB6DD07985
    
    Exception Type:  EXC_BREAKPOINT (SIGTRAP)
    Exception Codes: 0x0000000000000002, 0x0000000000000000
    Crashed Thread:  0  Dispatch queue: com.apple.main-thread
    
    Application Specific Information:
    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to open database'
    *** Call stack at first throw:
    (
           0   CoreFoundation                      0x947e76ba __raiseError + 410
           1   libobjc.A.dylib                     0x9182e509 objc_exception_throw + 56
           2   CoreFoundation                      0x947e73e8 +[NSException raise:format:arguments:] + 136
           3   Foundation                          0x913e6bb3 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
           4   RCS                                 0x002af73c -[LocalDBController openDB] + 214
           5   RCS                                 0x00075157 -[SplashScreen awakeFromNib] + 32
           6   CoreFoundation                      0x9477f9b4 -[NSSet makeObjectsPerformSelector:] + 196
           7   AppKit                              0x94d2721c -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1566
           8   AppKit                              0x94d251f4 loadNib + 257
           9   AppKit                              0x94d245ed +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 228
           10  AppKit                              0x94d244fe +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 158
           11  AppKit                              0x94d24449 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 383
           12  AppKit                              0x94d2124d NSApplicationMain + 434
           13  RCS                                 0x00002ce6 start + 54
    )
    
    
    Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
    0   com.apple.CoreFoundation            0x94832a37 ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ + 7
    1   libobjc.A.dylib                     0x9182e509 objc_exception_throw + 56
    2   com.apple.CoreFoundation            0x947e73e8 +[NSException raise:format:arguments:] + 136
    3   com.apple.Foundation                0x913e6bb3 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
    4   com.tprf.RCS                        0x002af73c -[LocalDBController openDB] + 214
    5   com.tprf.RCS                        0x00075157 -[SplashScreen awakeFromNib] + 32
    6   com.apple.CoreFoundation            0x9477f9b4 -[NSSet makeObjectsPerformSelector:] + 196
    7   com.apple.AppKit                    0x94d2721c -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1566
    8   com.apple.AppKit                    0x94d251f4 loadNib + 257
    9   com.apple.AppKit                    0x94d245ed +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 228
    10  com.apple.AppKit                    0x94d244fe +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 158
    11  com.apple.AppKit                    0x94d24449 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 383
    12  com.apple.AppKit                    0x94d2124d NSApplicationMain + 434
    13  com.tprf.RCS                        0x00002ce6 start + 54

The method(s) which I call in beginning to initialize and open db are as follow:

Code:
    -(void)dbInit{ // call in awake from NIB
        databaseName = [[NSString alloc] initWithString:@"test10.sql"];
    	
    	NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    	NSString *documentsDir = [documentPaths objectAtIndex:0];
    	databasePath = [[NSString alloc] initWithString:[documentsDir stringByAppendingPathComponent:databaseName]];
    	NSLog(@"databasePath - %@",databasePath);
    	
    	[self checkAndCreateDatabase];
    	
    }
    -(void)checkAndCreateDatabase{
    	BOOL success;
    	NSFileManager *fileManager = [NSFileManager defaultManager];
    	success = [fileManager fileExistsAtPath:databasePath];
    	NSLog(@"checkAndCreateDatabase, success - %d",success);
    	if(success){
    		[self openDB];
    		return;
    	}
    	NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
    	[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
    	[fileManager release];
    	
    	// opening db 
    	[self openDB];
    	
    }
    - (void)openDB{
    	if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) 
    	{
    		sqlite3_close(database);
    		NSAssert(0, @"Failed to open database");
    	}
    	else{
    		NSLog(@"db successfully opened");
    	}
    }

Can anyone suggest some solution for it?

Thanks,

Monaj
 
Last edited by a moderator:
Oh how this code looks familiar. I used that exact same tutorial when I was learning how to use SQLite on the iPhone. Something to do with animals if I remember...

if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK)


Have you checked before this line what "databasePath" actually is?

Also, I think the reason you are getting this huge stack trace is because you are using NSAssert. The bottom line is that you KNOW that it failed at that point (you are effectively duplicating some logic at that point using the assert). You need to know WHY it failed to open the database.

To be fair, I don't know if NSAssert forces it to print a whole stack trace by throwing an exception, so this is just conjecture, but it looks likely considering the error in the stack trace is the same as the error you "typed". For this usage, you are NOT getting any additional usable information by using NSAssert, and it may be confusing the problem more, considering the assert will "hit" every time because the 0 evaluates to false. With traditional C assert, I know this will terminate the program. Throwing an exception would effectively do the same thing to your program/



Chances are, the path to the sqlite file isn't right, or the file itself isn't actually being deployed to the target. Finally, another option is that you didn't include the right SQLite framework. IIRC, there is SQLITE and SQLITE3 that you can include.
 
Last edited:
Solution found, but new doubts arise

Hi all,

To resolve the problem reported above, I tried to log the result returned from sqlite3_open. I got 14 ie. SQLITE_CANTOPEN. I checked permission for Documents and found that some permissions were not read & write. When I changed all to read & write, it started working properly :)

Now there are some doubts :

1. Is there any-other folder in which I should store SQLite3 db... other than documents.. should I store it in ~/Library/Application Support/ or any other folder?

2. Can we check it via our code that- folder in which we are storing the db file has appropriate permissions or not?

3. If folder does not have appropriate permission then can we change it via code?

Can anyone clear these doubts or tell me the standard way to implement my requirements?

Thanks,
Monaj
 
Last edited:
1. Is there any-other folder in which I should store SQLite3 db... other than documents.. should I store it in ~/Library/Application Support/ or any other folder?

Is this conceptually a document to user? If it is, than you should provide the user with the ability to save the database whereever they want via a standard Save sheet.

If this is not a document then it should not go in ~/Documents. ~/Documents should ONLY contain files explicitly saved there by the user. (Are you listening to this Microsoft and Adobe!?)

If this is a database containing a cache of information that can be reconstructed if it is deleted or missing, then it should go in a subfolder of ~/Library/Caches.

Otherwise putting the database in a subfolder of ~/Library/Application Support would be appropriate.

2. Can we check it via our code that- folder in which we are storing the db file has appropriate permissions or not?

NSFileManager has methods that can help here. Check out isWritableFileAtPath: and the like. The stat POSIX function should also work, if you're already familiar with that.

3. If folder does not have appropriate permission then can we change it via code?

NSFileManager has a setAttributes:ofItemAtPath:error: method which can change the POSIX permissions of a file. There's also a chmod POSIX function.

Neither of these will be effective though if the file an Access Control Lists overriding the POSIX permissions. Search for acl in the developer documentation if want to tackle ACL's.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.