From dad6b9e9d592fd5be223cb1f8565c2d0b7bfc94f Mon Sep 17 00:00:00 2001 From: Ron Pedde Date: Mon, 6 Mar 2006 01:35:49 +0000 Subject: [PATCH] add debugging code to try and find the sqlite3 double-free bug --- src/db-sql-sqlite3.c | 18 ++++++++++++++++-- src/dispatch.c | 21 +++++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/db-sql-sqlite3.c b/src/db-sql-sqlite3.c index 04231f21..c9f51961 100644 --- a/src/db-sql-sqlite3.c +++ b/src/db-sql-sqlite3.c @@ -62,7 +62,7 @@ static sqlite3 *db_sqlite3_songs; /**< Database that holds the mp3 info */ static pthread_mutex_t db_sqlite3_mutex = PTHREAD_MUTEX_INITIALIZER; /**< sqlite not reentrant */ static sqlite3_stmt *db_sqlite3_stmt; static int db_sqlite3_reload=0; -static char *db_sqlite3_enum_query; +static char *db_sqlite3_enum_query=NULL; static char **db_sqlite3_row = NULL; static char db_sqlite3_path[PATH_MAX + 1]; @@ -229,6 +229,10 @@ int db_sqlite3_enum_begin_helper(char **pe) { int err; const char *ptail; + if(!db_sqlite3_enum_query) + *((int*)NULL) = 1; + + DPRINTF(E_DBG,L_DB,"Executing: %s\n",db_sqlite3_enum_query); err=sqlite3_prepare(db_sqlite3_songs,db_sqlite3_enum_query,0, &db_sqlite3_stmt,&ptail); @@ -237,6 +241,7 @@ int db_sqlite3_enum_begin_helper(char **pe) { db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_songs)); db_sqlite3_unlock(); sqlite3_free(db_sqlite3_enum_query); + db_sqlite3_enum_query=NULL; return DB_E_SQL_ERROR; } @@ -250,7 +255,9 @@ int db_sqlite3_enum_begin_helper(char **pe) { } /** - * fetch the next row + * fetch the next row. This will return DB_E_SUCCESS if it got a + * row, or it's done. If it's done, the row will be empty, otherwise + * it will be full of data. Either way, if fetch fails, you must close. * * @param pe error string, if result isn't DB_E_SUCCESS * @param pr pointer to a row struct @@ -265,6 +272,9 @@ int db_sqlite3_enum_fetch(char **pe, SQL_ROW *pr) { int idx; int counter=10; + if(!db_sqlite3_enum_query) + *((int*)NULL) = 1; + while(counter--) { err=sqlite3_step(db_sqlite3_stmt); if(err != SQLITE_BUSY) @@ -312,10 +322,14 @@ int db_sqlite3_enum_fetch(char **pe, SQL_ROW *pr) { int db_sqlite3_enum_end(char **pe) { int err; + if(!db_sqlite3_enum_query) + *((int*)NULL) = 1; + if(db_sqlite3_row) free(db_sqlite3_row); db_sqlite3_row = NULL; sqlite3_free(db_sqlite3_enum_query); + db_sqlite3_enum_query = NULL; err = sqlite3_finalize(db_sqlite3_stmt); if(err != SQLITE_OK) { diff --git a/src/dispatch.c b/src/dispatch.c index 108cb2b2..b710ab78 100644 --- a/src/dispatch.c +++ b/src/dispatch.c @@ -1257,6 +1257,7 @@ void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { int song_count; int list_length; unsigned char *block; + char *pe; if(ws_getvar(pwsc,"meta")) { pqi->meta = db_encode_meta(ws_getvar(pwsc,"meta")); @@ -1273,7 +1274,12 @@ void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { } /* FIXME: Error handling */ - db_enum_size(NULL,pqi,&song_count,&list_length); + if(db_enum_size(&pe,pqi,&song_count,&list_length) != DB_E_SUCCESS) { + DPRINTF(E_LOG,L_DAAP,"Error getting dmap size: %s\n",pe); + song_count=0; + list_length=0; + free(pe); + } DPRINTF(E_DBG,L_DAAP,"Item enum: got %d songs, dmap size: %d\n",song_count,list_length); @@ -1287,18 +1293,21 @@ void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { dispatch_output_start(pwsc,pqi,61+list_length); dispatch_output_write(pwsc,pqi,items_response,61); + pe=NULL; while((db_enum_fetch(NULL,pqi,&list_length,&block) == DB_E_SUCCESS) && - (list_length)) - { + (list_length)) { DPRINTF(E_SPAM,L_DAAP,"Got block of size %d\n",list_length); dispatch_output_write(pwsc,pqi,block,list_length); free(block); } - DPRINTF(E_DBG,L_DAAP,"Done enumerating.\n"); - db_enum_end(NULL); + if(pe) { + DPRINTF(E_LOG,L_DAAP,"Error enumerating items: %s\n",pe); + free(pe); + } + dispatch_output_end(pwsc,pqi); return; } @@ -1478,7 +1487,7 @@ void dispatch_server_info(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { current += db_dmap_add_string(current,"minm",servername); /* 8 + strlen(name) */ current += db_dmap_add_char(current,"msau", /* 9 */ - conf_isset("general","password") ? 2 : 0); + conf_isset("general","password") ? 1 : 0); current += db_dmap_add_char(current,"msex",0); /* 9 */ current += db_dmap_add_char(current,"msix",0); /* 9 */ current += db_dmap_add_char(current,"msbr",0); /* 9 */