delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2004/09/15/01:45:12

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Trace-PostClient-IP: 68.147.131.211
From: Brian Inglis <Brian DOT Inglis AT SystematicSW DOT Invalid>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: SQLite problem
Organization: Systematic Software
Message-ID: <gegfk0tqoitvbefal5s56dc206edi4g8er@4ax.com>
References: <opseci8wqr7iosox AT boohiss-927a07e>
X-Newsreader: Forte Agent 1.93/32.576 English (American)
MIME-Version: 1.0
Lines: 106
Date: Wed, 15 Sep 2004 05:43:15 GMT
NNTP-Posting-Host: 24.71.223.147
X-Complaints-To: abuse AT shaw DOT ca
X-Trace: pd7tw1no 1095226995 24.71.223.147 (Tue, 14 Sep 2004 23:43:15 MDT)
NNTP-Posting-Date: Tue, 14 Sep 2004 23:43:15 MDT
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

fOn Wed, 15 Sep 2004 02:05:20 GMT in comp.os.msdos.djgpp, boohiss
<boohiss AT cubesource DOT net> wrote:

>I have come accross a very baffling problem.
>
>My main() function calls a function cust_information(), which in turn,
>may call function add_customer():
>
>	int add_customer()
>	{
>		string strSQL;
>   		sqlite *db;
>   		char **errmsg;
>   		db=sqlite_open(DBFILENAME, 0, NULL);
>   		strSQL = "INSERT INTO customer VALUES (";
>		strSQL+= "\"" + C.phone + "\", ";
>		strSQL+= "\"" + C.name + "\", ";
>		strSQL+= "\"" + C.address + "\", ";
>		strSQL+= "\"" + C.comment + "\");";
>-> 		sqlite_exec(db,strSQL.c_str(),NULL,NULL,errmsg);
>   		sqlite_close(db);
>		return(0);
>	}
>
>Where C is a global object with a couple public functions, and DBFILENAME  
>is #DEFINEd.
>The problem is in the sqlite_exec line.  I call this function in many  
>other places,
>doing very similar things, and I get no problems.  I get a seg fault when  
>this function
>is called.  I've ran gdb on it, and found that it actually seg faults
>right after the return(0) line of cust_information().  When commenting out  
>the sqlite_exec
>line, I get no seg fault, but obviously that's not what I want.  There's  
>no error message
> from sqlite_exec, and it appears to actually add the information to the  
>database file.
>
>I'm completely baffled.  Does anyone have an idea what might cause this?

The last parameter to sqlite_exec() is meant to be the address of or a
reference to a variable which can hold a pointer to an error message. 
It may be passed as NULL if you don't want to handle an error message,
otherwise it is set by SQLite to point to an error message when there
are errors, and it may be set to NULL when there are no errors. 
But your errmsg variable does not point to storage for a pointer, so
SQLite may be returning an error message, or it may be setting the
pointer to NULL (likely) when there is no error, at a random location
depending on the contents of errmsg; this may just happen to be a
return address or some pointer in one of the calling functions, which
causes a SEGV when used or dereferenced later. 
You should be using something more like:

/* standard database error message format */
#define FMT_DB_ERR    "\n* Database error %d on %s %s:\n"	\
			"* message %s\n"			\
			"* in file %s at line %d in function %s\n"

int add_customer()
{
    string strSQL;
/* initialize variables to known safe values to avoid problems */
    int		err	= SQLITE_OK;	/* error */
    sqlite *	db	= NULL;		/* database */
    char   *	errmsg	= NULL;		/* error message */

/* database open -- check for, report, and return error */
    if (!(db = sqlite_open( DBFILENAME, 0, &errmsg)))
    {
        fprintf( stderr, FMT_DB_ERR,
			-1, "OPEN database", DBFILENAME,
				errmsg ? errmsg : "* NO MESSAGE *",
					__FILE__, __LINE__, __func__);
		/* use default error message if pointer still NULL */
	free( errmsg );		/* error message needs free()d */
        return -1;
    }

...

/* database insert table -- check for, report, and return error */
    if((err = sqlite_exec( db, strSQL.c_str(), NULL, NULL, &errmsg))
							!= SQLITE_OK)
    {
        fprintf( stderr, FMT_DB_ERR,
			err, "INSERT table", "CUSTOMER",
				errmsg ? errmsg : "* NO MESSAGE *",
					__FILE__, __LINE__, __func__);
		/* use default error message if pointer still NULL */
	free( errmsg );		/* error message needs free()d */
        sqlite_close( db );
        return err;
    }
/*
 * code duplicated inside if blocks
 * in case more code inserted here
 */
    sqlite_close( db );
    return err;
}

-- 
Thanks. Take care, Brian Inglis 	Calgary, Alberta, Canada

Brian DOT Inglis AT CSi DOT com 	(Brian[dot]Inglis{at}SystematicSW[dot]ab[dot]ca)
    fake address		use address above to reply

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019