Hi, Adam, On Mon, Jan 25, 2016 at 2:46 PM, Adam Devita <adevita at verifeye.com> wrote: > Hi Igor, > I don't think you understood what I was trying to get at. Please > allow me to rephrase: There isn't enough information about how things > are being cleaned up to point out a problem, only make general > suggestions about good practice. > > This is why I was asking about where you would ensure you are properly > shutting down the database before deleting your wrapper. I had > expected to see something of the form: > > > //private: sqlite3 *db; > BOOL SomeWrapperClass::Closedb() > { > if(db==NULL){ > b_sqlite_db_open = false;//Ensure state variable of wrapper is correct > return TRUE; // db wasn't open, so Closed is OK > } > > int ret=sqlite3_close(db); > if (ret==SQLITE_OK){ > db = NULL; > b_sqlite_db_open = false; > return TRUE; //properly closed my db connection, no errors > } > return FALSE; //if we got here, there is an error; break-point hit > ; What didn't get finalized? How did this happen? > } > > I would have expect you to, before delete m_db to do something like > if(m_db != NULL) { > if(!m_db->Closedb() ){ //assumes that queries have already been > finalized ; > ;//error handle code, break point, how did we fail to close? > } > delete m_db; > } > > or a method of your dll that is some exported DestroyObject(Database *db) ; > > or at least tell us that you are ensuring sqlite_close is called via > the destructor of m_db;
Yes, sqlite3_close() _is_ called from the m_db destructor. Moreover, for now I am just opening the db thru the loading the DLL dynamically and calling the DLL function which creates an object and connects to the db: SQLiteDatabase::SQLiteDatabase() { } SQLiteDatabase::~SQLiteDatabase() { sqlite3_close(); } int SQLiteDatabase::Connect() { int result = sqlite3_open(); if( result != SQLITE_OK ) { // handling error } } In the MainFrame: void MainFrame::ConnectToDb() { Database *db = NULL; LoadLibrary(); func = GetProcAddress( "CreateObject" ); m_db = func( db ); } In the DLL: extern "C" __declspec(dllexport) Database *CreateObject(Database *db) { db = new SQLiteDatabase(); int res = db->Connect(); if( res ) delete db; return db; } and then exiting the main application, i.e. closing the connection. No queries are issued for the database. Moreover all pointers are the same: from the point I call new in DLL' CreateObject(), then in ConnectToDB() in MainFrame' ConnectToDb() function and finally in the MainFrame' destructor. Also it does not matter whether I'm trying to do "delete m_db" in the MainFrame destructor or try to close the connection from an additional exported function - it still crashes. Thank you. > > While in C++ one may choose to not check if the thing being deleted is > NULL before doing it, it is a clutter/style thing. For debugging > purposes finding out that the thing that should have been null isn't > as expected. It can often lead to one saying "hey, that should have > got deleted already!... oh somehow delete x instead of safe_delete(x) > got used so while it got deleted earlier and x should have been null > at this point" > > Are you unit testing the trivial cases? > Create+Destroy > Create+Connect+Destroy > Create+Connect+DoBasicQuery+Destroy > > > regards, > Adam > > On Mon, Jan 25, 2016 at 2:02 PM, Igor Korot <ikorot01 at gmail.com> wrote: >> Hi, Adam, >> >> On Mon, Jan 25, 2016 at 11:27 AM, Adam Devita <adevita at verifeye.com> >> wrote: >>> Where do you pass to the dll something that goes to sqlite3_close(db); ? >>> ( https://www.sqlite.org/c3ref/close.html ) >>> When that happens, does m_db get set to NULL (or now refers to memory >>> that is now NULL) >>> Do you check for m_db == NULL before deleting it? >> >> SQLiteDatabase class is just a wrapper around the SQLite interface. >> The constructor is empty, but in the Connect() function of the class I call >> >> sqlite3_open(). >> >> And here is the code that you are asking for: >> >> void MainFrame::ConnectToDb() >> { >> Database *db = NULL; >> LoadLibrary(); >> func = GetProcAddress(); >> m_db = func( db ); >> } >> >> Also, in C++ delete'ing NULL is perfectly normal operation. >> >> Thank you. >> >>> >>> regards, >>> Adam DeVita >>> >>> On Mon, Jan 25, 2016 at 11:16 AM, Igor Korot <ikorot01 at gmail.com> wrote: >>>> Hi, Peter, >>>> >>>> On Mon, Jan 25, 2016 at 10:50 AM, Peter Aronson <pbaronson at att.net> >>>> wrote: >>>>> Igor, >>>>> >>>>> You can't safely pass a SQLite handle between different SQL DLLs that way >>>>> if >>>>> they're both built with their own copy of the amalgamation (or link to >>>>> things built with different copies). SQLite uses a handful of global >>>>> variables, but each DLL has its own copy of each of these global variables >>>>> and they can and will have different values, which can mess things up. I >>>>> ran into a version of this problem when I tried to load a 2nd DLL built >>>>> with >>>>> its own copy of the sqlite3.c amalgamation. I fixed that by exposing the >>>>> SQLite3 entrypoints in the first DLL and linking the second DLL against it >>>>> so there was only one copy of the amalgamation used for that SQLite3 >>>>> handle. >>>> >>>> The SQLite is built only once and with just one version of the code. >>>> >>>> Consider following pseudo-code: >>>> >>>> In DLL: >>>> >>>> BOOL APIENTRY DLLMain() >>>> { >>>> } >>>> >>>> extern "C" __declspec(dllexport) Database *CreateObject(Database *db) >>>> { >>>> db = new SQLiteDatabase(); >>>> db->Connect(); >>>> return db; >>>> } >>>> >>>> In the main application: >>>> >>>> mainframe.h: >>>> >>>> class MainFrame >>>> { >>>> public: >>>> MainFrame(); >>>> ~MainFrame(); >>>> void ConnectToDb(); >>>> private: >>>> Database *m_db; >>>> }; >>>> >>>> mainframe.cpp: >>>> >>>> void MainFrame::ConnectToDb() >>>> { >>>> Database *db = NULL; >>>> LoadLibrary(); >>>> func = GetProcAddress(); >>>> m_db = func( db ); >>>> } >>>> >>>> MainFrame::~MainFrame() >>>> { >>>> delete m_db; // this is where the crash happens >>>> } >>>> >>>> The pointer address are the same in DLL and main application MainFrame >>>> class. >>>> And as I said the crash occurs when it tries to acquire the mutex lock. >>>> >>>> Thank you. >>>> >>>>> >>>>> Peter >>>>> >>>>> >>>>> >>>>> >>>>> On 1/24/2016 10:18 PM, Igor Korot wrote: >>>>>> >>>>>> Hi, ALL, >>>>>> I have a strange problem. >>>>>> >>>>>> I am trying to use sqlite in my program. It has a main application and >>>>>> couplef DLLs. >>>>>> >>>>>> I am getting the connection in one of the DLL, then the pointer is passed >>>>>> up >>>>>> to the main application. >>>>>> >>>>>> Upon exiting from the application I'm trying to close the connection and >>>>>> delete all the memory. >>>>>> >>>>>> Unfortunately upon exiting the application it crashes inside >>>>>> sqlite3_mutex_enter(). >>>>>> The comment above the function says: >>>>>> >>>>>> [quote] >>>>>> /* >>>>>> ** Obtain the mutex p. If some other thread already has the mutex, block >>>>>> ** until it can be obtained. >>>>>> */ >>>>>> [/quote] >>>>>> >>>>>> The DLL does not start any threads, in fact the application will be 1 >>>>>> thread only. >>>>>> So is there some compile-time switch I should use to mitigate the issue? >>>>>> >>>>>> Moreover I don't understand why am I getting the assertion - there is no >>>>>> MT >>>>>> involved. >>>>>> >>>>>> Can someone shed some lights? >>>>>> >>>>>> Thank you. >>>>>> _______________________________________________ >>>>>> sqlite-users mailing list >>>>>> sqlite-users at mailinglists.sqlite.org >>>>>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >>>>>> >>>>> >>>>> _______________________________________________ >>>>> sqlite-users mailing list >>>>> sqlite-users at mailinglists.sqlite.org >>>>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >>>> _______________________________________________ >>>> sqlite-users mailing list >>>> sqlite-users at mailinglists.sqlite.org >>>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >>> >>> >>> >>> -- >>> -------------- >>> VerifEye Technologies Inc. >>> 151 Whitehall Dr. Unit 2 >>> Markham, ON >>> L3R 9T1 >>> _______________________________________________ >>> sqlite-users mailing list >>> sqlite-users at mailinglists.sqlite.org >>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >> _______________________________________________ >> sqlite-users mailing list >> sqlite-users at mailinglists.sqlite.org >> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users > > > > -- > -------------- > VerifEye Technologies Inc. > 151 Whitehall Dr. Unit 2 > Markham, ON > L3R 9T1 > _______________________________________________ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users