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