Hello Igor,

https://msdn.microsoft.com/en-us/library/ms235460.aspx?f=255&MSPPError=-2147217396

This discussed in more details what I originally posted about.

>>A related problem can occur when you allocate memory (either
>>explicitly with new or malloc, or implicitly with strdup,
>>strstreambuf::str, and so on) and then pass a pointer across a DLL
>>boundary to be freed. This can cause a memory access violation or heap
>>corruption if the DLL and its users use different copies of the CRT
>>libraries.

Are you sure the DLL and the main application are built with the same
RTL?  This is almost certainly not an Sqlite problem. It's probably an
Sqlite mis-use problem.


How are you compiling the code? What run time library are you using? I
use  /MT  and /MTd for mostly static linking.  Then I "getprocaddress"
on  any DLL's I load. So, in my case each DLL has its own copy of the
RTL.    I'm not clear how using /MD or /MDd impacts this.

I  don't use Sqlite the way you're trying to. I static link a copy and
the  wrapper  into  each application so there are no DLL boundaries to
contend with.


Monday, January 25, 2016, 11:30:00 PM, you wrote:

IK> Teg,

IK> On Mon, Jan 25, 2016 at 9:25 PM, Igor Korot <ikorot01 at gmail.com> wrote:
>> Hi, Teg,
>>
>> On Mon, Jan 25, 2016 at 5:21 PM, Igor Korot <ikorot01 at gmail.com> wrote:
>>> Hi, Teg,
>>>
>>> On Mon, Jan 25, 2016 at 4:51 PM, Teg <Teg at djii.com> wrote:
>>>> Hello Igor,
>>>>
>>>> Then  I'd  note  the address of the object (make a copy of the pointer
>>>> right  as  it's  allocated)  and  then  verify that the address you're
>>>> deleting  is  the same as the address that was allocated.  I've verify
>>>> that the correct calling convention is being used throughout too.
>>>
>>> Yes, pointers (addresses) are the same.
>>>
>>>>
>>>>
>>>> I'd single step into the destructor and see what's actually happening to
>>>> make  it  crash. I'd pay attention to the "this" pointer and see if it
>>>> makes sense.
>>
>> I just ran the program under the debugger step-by-step and everything
>> looks "normal".
>> All addresses are the same. and the opening db executes successfully.
>>
>> The stack trace look like this:
>>
>>>    sqlite.dll!sqlite3_mutex_enter(sqlite3_mutex * p)  Line 19996 + 0xc 
>>> bytes    C
>>      sqlite.dll!sqlite3Close(sqlite3 * db, int forceZombie)  Line 726
>> + 0xc bytes    C
>>      sqlite.dll!sqlite3_close(sqlite3 * db)  Line 772 + 0xe bytes    C
>>      
>> sqlite.dll!SQLiteDatabase::Disconnect(std::vector<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>
>>>,std::allocator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>
>>> > > & errorMsg)  Line 49 + 0xc bytes    C++
>>      dialogs.dll!DisconnectFromDb(Database * db)  Line 108 + 0x13 bytes    
>> C++
>>      docview.exe!MainFrame::~MainFrame()  Line 73 + 0xf bytes    C++
>>
>> The DisconnectFromDb() function is a function from DLL. It calls
>> SQLiteDatabase::Disconnect().
>> Then everything is sqlite.
>>
>> Any idea of what is going on?

IK> [code]
IK> SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
IK>   if( p ){
IK>     assert( sqlite3GlobalConfig.mutex.xMutexEnter );    // This is the
IK> line that fails
IK>     sqlite3GlobalConfig.mutex.xMutexEnter(p);
IK>   }
IK> }
IK> [/code]

IK> Thank you.

>>
>> Thank you.
>>
>>>>
>>>> Assuming you're using visual studio and have the source to the wrapper
>>>> if  should be easy to simply step in and see exactly what line of code
>>>> makes it crash.
>>>
>>> Yes, MSVC 2010 and the code is mine. ;-)
>>>
>>> Thank you.
>>>>
>>>> C
>>>>
>>>>
>>>> Monday, January 25, 2016, 1:00:53 PM, you wrote:
>>>>
>>>> IK> Hi, Teg,
>>>>
>>>> IK> On Mon, Jan 25, 2016 at 11:31 AM, Teg <Teg at djii.com> wrote:
>>>>>> Hello Igor,
>>>>>>
>>>>>> MainFrame::~MainFrame()
>>>>>> {
>>>>>>     delete m_db;  // this is where the crash happens
>>>>>> }
>>>>>>
>>>>>> I suspect you need to add a "Close" or destroy function to the DLL and
>>>>>> pass the handle back to the DLL to let it get deleted in the DLL
>>>>>> context and not in the context of the caller.
>>>>
>>>> IK> Does not make a difference.
>>>> IK> I added that function and call it from the MainFrame destructor.
>>>>
>>>> IK> It still crashed.
>>>>
>>>> IK> Thank you.
>>>>
>>>>>>
>>>>>>
>>>>>> extern "C" __declspec(dllexport) void DestroyObject(Database *db)
>>>>>> {
>>>>>>       delete db;
>>>>>> }
>>>>>>
>>>>>> It was my impression that each DLL got it's own heap so, memory
>>>>>> allocated inside the DLL needs to be free'd inside the DLL. I use
>>>>>> Sqlite in a static lib in my applications.
>>>>>>
>>>>>> I  treat  memory  allocated  in  DLL's as being owned by the DLL so, I
>>>>>> typically  pass  it  back  to the DLL to be cleaned up.  It believe it
>>>>>> depends  on what run time library you're using though. If you're using
>>>>>> an RTL where all the DLL's end up using a DLL supplied allocator, this
>>>>>> probably isn't an issue. I tend to dynamic load my DLL's so they don't
>>>>>> all use the same allocator.
>>>>>>
>>>>>> C
>>>>>>
>>>>>>
>>>>>>
>>>>>> Monday, January 25, 2016, 11:16:57 AM, you wrote:
>>>>>>
>>>>>> IK> Hi, Peter,
>>>>>>
>>>>>> IK> 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.
>>>>>>
>>>>>> IK> The SQLite is built only once and with just one version of the code.
>>>>>>
>>>>>> IK> Consider following pseudo-code:
>>>>>>
>>>>>> IK> In DLL:
>>>>>>
>>>>>> IK> BOOL APIENTRY DLLMain()
>>>>>> IK> {
>>>>>> IK> }
>>>>>>
>>>>>> IK> extern "C" __declspec(dllexport) Database *CreateObject(Database *db)
>>>>>> IK> {
>>>>>> IK>     db = new SQLiteDatabase();
>>>>>> IK>     db->Connect();
>>>>>> IK>     return db;
>>>>>> IK> }
>>>>>>
>>>>>> IK> In the main application:
>>>>>>
>>>>>> IK> mainframe.h:
>>>>>>
>>>>>> IK> class MainFrame
>>>>>> IK> {
>>>>>> IK> public:
>>>>>> IK>      MainFrame();
>>>>>> IK>      ~MainFrame();
>>>>>> IK>      void ConnectToDb();
>>>>>> IK> private:
>>>>>> IK>      Database *m_db;
>>>>>> IK> };
>>>>>>
>>>>>> IK> mainframe.cpp:
>>>>>>
>>>>>> IK> void MainFrame::ConnectToDb()
>>>>>> IK> {
>>>>>> IK>     Database *db = NULL;
>>>>>> IK>     LoadLibrary();
>>>>>> IK>     func = GetProcAddress();
>>>>>> IK>     m_db = func( db );
>>>>>> IK> }
>>>>>>
>>>>>> IK> MainFrame::~MainFrame()
>>>>>> IK> {
>>>>>> IK>     delete m_db;  // this is where the crash happens
>>>>>> IK> }
>>>>>>
>>>>>> IK> The pointer address are the same in DLL and main application 
>>>>>> MainFrame class.
>>>>>> IK> And as I said the crash occurs when it tries to acquire the mutex 
>>>>>> lock.
>>>>>>
>>>>>> IK> 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
>>>>>> IK> _______________________________________________
>>>>>> IK> sqlite-users mailing list
>>>>>> IK> sqlite-users at mailinglists.sqlite.org
>>>>>> IK> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>>  Teg                            mailto:Teg at djii.com
>>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>>  Teg                            mailto:Teg at djii.com
>>>>



-- 
 Teg                            mailto:Teg at djii.com

Reply via email to