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

Reply via email to