Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sqlite_orm::internal::connection_holder::release() [sqlite_orm.h : 7072 + 0x8] #855

Closed
DupliChen opened this issue Nov 29, 2021 · 6 comments
Labels

Comments

@DupliChen
Copy link

DupliChen commented Nov 29, 2021

Hi, I am using version 1.6 for my current project (dev branch used on 7th September 2020) and there have been a lot of crashes in stress testing recently, the locations of the crashes are as follows:

Thread 74 (crashed)
 0  libsqlite3.so!sqlite3SafetyCheckSickOrOk + 0x10
     x0 = 0x389e658700000011    x1 = 0x0000000000000000
     x2 = 0x0000007f7d1a7ad8    x3 = 0x0000000000000000
     x4 = 0x0000000000000000    x5 = 0x0000000000000000
     x6 = 0x0000000000000001    x7 = 0x0000000000000000
     x8 = 0x0000007f3c0d1f18    x9 = 0x0000000000000004
    x10 = 0x2f726568636e7561   x11 = 0x6573616261746164
    x12 = 0x665f726573752f73   x13 = 0x6369645f726f7661
    x14 = 0x5f6b61625f62642e   x15 = 0x000032a6f5ab1267
    x16 = 0x000000000400e230   x17 = 0x0000007f7d182de4
    x18 = 0x000000000000006d   x19 = 0x00000000297804b0
    x20 = 0x0000000000000000   x21 = 0x0000007fed90dff8
    x22 = 0x0000007fed90dfef   x23 = 0x0000007ed3ff7370
    x24 = 0x0000007ed3800000   x25 = 0x0000000000000003
    x26 = 0x0000000000800000   x27 = 0x0000000000000000
    x28 = 0x0000007f79dbe6f0    fp = 0x0000007ed3ff67b0
     lr = 0x0000007f7d182d0c    sp = 0x0000007ed3ff67b0
     pc = 0x0000007f7d0d51e8
    Found by: given as instruction pointer in context
 1  libsqlite3.so!sqlite3Close + 0x28
     fp = 0x0000007ed3ff67e0    lr = 0x0000007f7d182d0c
     sp = 0x0000007ed3ff67c0    pc = 0x0000007f7d182d0c
    Found by: previous frame's frame pointer
 2  libsqlite3.so!sqlite3Close + 0x28
     fp = 0x0000007ed3ff6800    lr = 0x0000007f7d182dfc
     sp = 0x0000007ed3ff67f0    pc = 0x0000007f7d182d0c
    Found by: previous frame's frame pointer
 3  libsqlite3.so!sqlite3_close + 0x14
     fp = 0x0000007ed3ff6820    lr = 0x0000000000c9ed4c
     sp = 0x0000007ed3ff6810    pc = 0x0000007f7d182dfc
    Found by: previous frame's frame pointer
 4  translator_cpp_demonstration!sqlite_orm::internal::connection_holder::release() [sqlite_orm.h : 7072 + 0x8]
     fp = 0x0000007ed3ff68b0    lr = 0x0000000000c9f8c0
     sp = 0x0000007ed3ff6830    pc = 0x0000000000c9ed4c
    Found by: previous frame's frame pointer
 5  translator_cpp_demonstration!sqlite_orm::internal::backup_t::~backup_t() [sqlite_orm.h : 8570 + 0x58]
    x19 = 0x0000007f3c0cdb58   x20 = 0x0000007ed3ff6928
     fp = 0x0000007ed3ff68d0    sp = 0x0000007ed3ff6940
     pc = 0x0000000000ca08fc
    Found by: call frame info

I used the function of database backup in the project, and the crash location was sqlite3_close. I wonder if the database was released repeatedly.

Maybe it's because my version is too low. Does the latest 1.7 fix that? Waiting for your good news.

@fnc12
Copy link
Owner

fnc12 commented Nov 29, 2021

just try v1.7. Also what exactly does your stress test? Does it makes backups in multithreaded mode?

@fnc12 fnc12 added the question label Nov 29, 2021
@DupliChen
Copy link
Author

All database operations are performed on a worker thread. There is no multithreading mode.The content of the stress test is: after the working thread is frequently started, the database is operated in the working thread, the database is backed up during the operation, and the database objects are destroyed after the operation.

@DupliChen
Copy link
Author

DupliChen commented Nov 30, 2021

I think I've found the cause of the problem.

When struct backup_t is destructed, the destructor of member variables is executed in the reverse order of declaration, so struct connection_holder destructs first, struct connection_ref destructs after, but struct connection_ref has a member variable connection_holder &, Therefore, after destructing struct connection_ref, calling this->holder.release(); will cause unpredictable problems.

I added a destructor to connection_holder and add log to the destructor, and then add log to release and concluded that, as mentioned above, the destructor log precedes the release log.

The solution is as simple as adjusting the order in which member variables are declared. Don't forget to adjust the order of the initializer list.

        struct backup_t {
            backup_t(connection_ref to_,
                     const std::string &zDestName,
                     connection_ref from_,
                     const std::string &zSourceName,
                     std::unique_ptr<connection_holder> holder_) :
                handle(sqlite3_backup_init(to_.get(), zDestName.c_str(), from_.get(), zSourceName.c_str())),
                holder(move(holder_)), to(to_), from(from_) {
                if(!this->handle) {
                    throw std::system_error(std::make_error_code(orm_error_code::failed_to_init_a_backup));
                }
            }

          ……………………
          protected:
            sqlite3_backup *handle = nullptr;
            std::unique_ptr<connection_holder> holder;
            connection_ref to;
            connection_ref from;
        };

@fnc12
Copy link
Owner

fnc12 commented Nov 30, 2021

wow thanks. I'll fix it soon

@fnc12
Copy link
Owner

fnc12 commented Dec 4, 2021

fix is here #859

@fnc12
Copy link
Owner

fnc12 commented Dec 5, 2021

merged. Thanks

@fnc12 fnc12 closed this as completed Dec 5, 2021
@fnc12 fnc12 removed the in progress label Dec 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants