Teg, 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?
[code] SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){ if( p ){ assert( sqlite3GlobalConfig.mutex.xMutexEnter ); // This is the line that fails sqlite3GlobalConfig.mutex.xMutexEnter(p); } } [/code] 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 >>>