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

how to fix update exception? #561

Closed
shishirong opened this issue Mar 14, 2024 · 23 comments
Closed

how to fix update exception? #561

shishirong opened this issue Mar 14, 2024 · 23 comments

Comments

@shishirong
Copy link

CREATE TABLE users (
    id        INTEGER PRIMARY KEY AUTOINCREMENT,
    pid       INTEGER,
    user_id   TEXT,
    user_name TEXT,
    passwd    TEXT
);
db(update(user).set(user.userName = "test",user.passwd = "test").where(user.userId == "123"));

on sqlite

update other table exception too.

@MeanSquaredError
Copy link
Contributor

You should provide more information, at least the exception message that you get.

@rbock
Copy link
Owner

rbock commented Mar 16, 2024

And with the exception message, please also provide a minimal reproducible example.

@shishirong
Copy link
Author

You should provide more information, at least the exception message that you get.

sorry,the exception message is:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

And with the exception message, please also provide a minimal reproducible example.

minimal example:
demo.zip

@MeanSquaredError
Copy link
Contributor

MeanSquaredError commented Mar 18, 2024

@shishirong

I could not find any obvious problems after looking at your source code.

So I built your project on latest Fedora 39. I had to rename DBModels.h -> DbModels.h because of filesystem case-sensitivity, but other than that, building the project went OK. After running the built executable it also worked fine and exited normally.

What platform (OS, compiler version, SQLite3 version, sqlpp11 version) are you building/running your demo on?

The error that you are getting std::bad_alloc, which implies some kind of memory problem, you are running out of memory or getting heap corruption.

I would check for a mismatch between sqlite3 library headers and the corresponding sqlite3 dynamic/static library. If that is OK, then probably the most straightforward approach would be to run it under your platform debugger to see where it throws std::bad_alloc and if there is any platform-specific error that is mapped to std::bad_alloc. If that doesn't help, then it probably makes sense to run it under a memory debugger like Valgrind.

@shishirong
Copy link
Author

image
os: windows 10 x64,
compiler: mingw81_64
sqlite and sqlpp11 version is in cmakelists.txt

when I select msvc as compiler, problems disappear
image

how I can make corrections on mingw81_64 compiler?

@MeanSquaredError
Copy link
Contributor

I don't have mingw on my Windows 10 machine at the moment, so I cannot test it.

My prime suspect is the sqlite3 library that is linked to your app. You may want to check if the sqlite3 headers are for the same version as the sqlite library that you are linking to your executable. Also make sure that the sqlite3 library uses the same CRT DLL as your main executable, so that you don't have two memory heaps. Maybe try using http://dependencywalker.com/ or another similar tool to check if the main executable and the sqlite3 library use the same CRT DLL.

@rbock
Copy link
Owner

rbock commented Mar 30, 2024

@shishirong Any updates?

@shishirong
Copy link
Author

The project is static link to sqlite library, I don't have any idea about sqlite3 library version and sqlite3 headers version
image
image

@rbock
Copy link
Owner

rbock commented Apr 2, 2024

I cannot comment on the dependency walker, maybe @MeanSquaredError can help with that?

In the meantime:

  • Can you run the sqlite3 tests that come with the sqlpp11 library?
  • The example code you provided fails in the CREATE TABLE already. Can you re-write that using sqlite3 directly? Does that crash, too?

@MeanSquaredError
Copy link
Contributor

I have a machine with Windows 10, so I will install mingw-64 and will try reproducing the problem tomorrow. I will post an update here once I try the demo program on my computer.

@MeanSquaredError
Copy link
Contributor

Also from the screenshot of depwalker it seems that the program uses msvcrt.dll, the non-debug build of the crt library, which is a bit surprising given that you are making a debug build of your project.

Also it is probably worth opening the dependencies of the libgcc_s_seh-1.dll and libstdc++-6.dll in depwalker and checking if they don't import a different build of the msvcrt library.

@MeanSquaredError
Copy link
Contributor

MeanSquaredError commented Apr 6, 2024

OK, I tried installing mingw (the cygwin distribution) and the demo program worked correctly for me without crashing.

I couldn't find your distribution mingw81_64 available for download, at least not from a trusted source. Also it is not clear which g++/gcc version you are using because mingw81_64 is the mingw version, but it doesn't say much about the g++/gcc version.

That is why I just went with the internet install of cygwin. I did a default install and then used its setup program to additionally install gcc-core, g++, cmake and gnu make. Then I built and ran the demo. It exited normally without any crashes. I tried it several times, but it just seems to work normally.

Here is my setup.

OS: Windows 10 64-bit
MinGW: Cygwin (internet installer)
G++ (GCC): 11.4.0
CMake: 3.28.3
GNU Make: 4.4.1

Just for your information, I also built the demo in MinGW with MSVC in debug mode and ran it. The program then complained that

DBModels::Users user;

is being accessed without being initialized first. So you could try changing it to

DBModels::Users user {};

and see if that will make a difference when running it on your computer.

@MeanSquaredError
Copy link
Contributor

MeanSquaredError commented Apr 6, 2024

OK, I think I found a (semi)decent download site for MinGW 8.1, so I will try it as well and will post an update.

EDIT:

I installed MinGW-W64 GCC-8.1.0 x86_64-posix-seh and after compiling the demo program it still worked correctly without any crashes.

@shishirong
Copy link
Author

shishirong commented Apr 8, 2024

@MeanSquaredError very thanks, I tried build in terminal, update is works; I build with qt-creator before.

but insert_into still fail on building:

db(insert_into(user).set(user.userId = "123", user.userName = "user0", user.passwd = "user0"));
 ~\Desktop\buffer\demo\build                                                                               | 10:30:29
➜ make
[ 50%] Built target SQLite3
[ 75%] Building CXX object CMakeFiles/demo.dir/main.cpp.obj
In file included from E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/type_traits.h:32,
                 from E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/serialize.h:29,
                 from E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/sqlite3/connection.h:39,
                 from E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/sqlite3/sqlite3.h:30,
                 from C:\Users\QQ769\Desktop\buffer\demo\main.cpp:1:
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/insert_value_list.h: In instantiation of 'constexpr sqlpp::assert_insert_static_set_all_required_t::assert_insert_static_set_all_required_t(T&& ...) [with T = {}]':
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/insert_value_list.h:539:31:   required from 'sqlpp::no_insert_value_list_t::_base_t<Policies>::_new_statement_t<typename sqlpp::check_insert_static_set<Assignments ...>::type, sqlpp::insert_list_t<void, Assignments ...> > sqlpp::no_insert_value_list_t::_base_t<Policies>::set(Assignments ...) const [with Assignments = {sqlpp::assignment_t<sqlpp::column_t<DBModels::Users, DBModels::Users_::UserId>, sqlpp::text_operand>, sqlpp::assignment_t<sqlpp::column_t<DBModels::Users, DBModels::Users_::UserName>, sqlpp::text_operand>, sqlpp::assignment_t<sqlpp::column_t<DBModels::Users, DBModels::Users_::Passwd>, sqlpp::text_operand>}; Policies = sqlpp::detail::statement_policies_t<void, sqlpp::insert_t, sqlpp::into_t<void, DBModels::Users>, sqlpp::no_insert_value_list_t>; sqlpp::no_insert_value_list_t::_base_t<Policies>::_new_statement_t<typename sqlpp::check_insert_static_set<Assignments ...>::type, sqlpp::insert_list_t<void, Assignments ...> > = sqlpp::assert_insert_static_set_all_required_t]'
C:\Users\QQ769\Desktop\buffer\demo\main.cpp:34:97:   required from here
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/portable_static_assert.h:40:21: error: static assertion failed: at least one required column is missing in set()
       static_assert(wrong_t<T...>::value, message); \
                     ^~~~~~~~~~~~~
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/insert_value_list.h:181:3: note: in expansion of macro 'SQLPP_PORTABLE_STATIC_ASSERT'
   SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_static_set_all_required_t,
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/type_traits.h: In instantiation of 'constexpr sqlpp::assert_run_statement_or_prepared_t::assert_run_statement_or_prepared_t(T&& ...) [with T = {}]':
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/sqlite3/connection.h:425:70:   required from 'decltype (((sqlpp::sqlite3::connection_base*)this)->sqlpp::sqlite3::connection_base::_run(t, sqlpp::run_check_t<sqlpp::sqlite3::context_t, T>{})) sqlpp::sqlite3::connection_base::operator()(const T&) [with T = sqlpp::assert_insert_static_set_all_required_t; decltype (((sqlpp::sqlite3::connection_base*)this)->sqlpp::sqlite3::connection_base::_run(t, sqlpp::run_check_t<sqlpp::sqlite3::context_t, T>{})) = sqlpp::assert_run_statement_or_prepared_t]'
C:\Users\QQ769\Desktop\buffer\demo\main.cpp:34:98:   required from here
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/portable_static_assert.h:40:21: error: static assertion failed: connection cannot run something that is neither statement nor prepared statement
       static_assert(wrong_t<T...>::value, message); \
                     ^~~~~~~~~~~~~
E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/include/sqlpp11/type_traits.h:444:3: note: in expansion of macro 'SQLPP_PORTABLE_STATIC_ASSERT'
   SQLPP_PORTABLE_STATIC_ASSERT(assert_run_statement_or_prepared_t,
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles\demo.dir\build.make:76: CMakeFiles/demo.dir/main.cpp.obj] Error 1
make[1]: *** [CMakeFiles\Makefile2:190: CMakeFiles/demo.dir/all] Error 2
make: *** [Makefile:135: all] Error 2

@rbock
Copy link
Owner

rbock commented Apr 8, 2024

Thanks for confirming the runtime issues to be resolved. You should try to figure out what happens in qt-creator, but that's out of scope for this library, of course.
@MeanSquaredError Thanks a lot for your support!

As for the new problem you are facing: That's a compile time issue, and the static asserts often explain the issue:

[...] static assertion failed: at least one required column is missing in set()

Unfortunately, I have not found a decent way to indicate the exact column, but looking at your code and the demo.zip you sent earlier: You are missing a value for the "pid" column.

@shishirong
Copy link
Author

yes, it is missing "pid" column; I don't know how to control generated sqlpp::tag::require_insert.

@MeanSquaredError
Copy link
Contributor

You should try to figure out what happens in qt-creator

@rbock
+1 to that because the problem could re-appear with the command-line build too and then the user would be back to square one without the ability to create a working build.

@shishirong
The problem causing the update crash seems to be triggered by something in the build environment. Given that the command-line build works and the qt-creator build crashes, then it is one of the following:

  1. Compiler/linker version.
  2. Compiler/linker options used during the build.
  3. Linked libraries.

So if you are intereseted in troubleshooting this issue, then you could try the following.

  1. Record the compiler/linker switches used by qt-creator. Its been quite a while since the last time when I used qt-creator, but I remember that it had a verbose build mode where you could see the exact command-line switches passed to the compiler/linker. I am not sure if the advice here is still relevant but you could try it
  2. Record the compiler/linker switches used by cmake/make by passing -DCMAKE_VERBOSE_MAKEFILE=ON to the initial cmake command
  3. Compare the two sets of compiler/linker switches and try to find out which one(s) make the difference. It might be a long/tedious process but it is easy to execute and in the end it should tell you which one is the culprit.

@shishirong
Copy link
Author

@MeanSquaredError I find the main difference is CMAKE_BUILD_TYPE, if -DCMAKE_BUILD_TYPE=Debug will recurrence exception

@rbock
Copy link
Owner

rbock commented Apr 9, 2024

yes, it is missing "pid" column; I don't know how to control generated sqlpp::tag::require_insert.

Columns require insert if they have no default (including auto increment) and are not marked to be nullable.

@shishirong
Copy link
Author

yes, it is missing "pid" column; I don't know how to control generated sqlpp::tag::require_insert.

Columns require insert if they have no default (including auto increment) and are not marked to be nullable.

CREATE TABLE users (
    id        INTEGER PRIMARY KEY AUTOINCREMENT,
    pid       INTEGER,
    user_id   TEXT,
    user_name TEXT,
    passwd    TEXT
);

I dont set NOT NULL, it don't should be sqlpp::tag::require_insert

@rbock
Copy link
Owner

rbock commented Apr 24, 2024

When I run your table definition through the code generator, I get this column struct for pid:

    struct Pid
    {
      struct _alias_t
      {
        static constexpr const char _literal[] =  "pid";
        using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
        template<typename T>
        struct _member_t
          {
            T pid;
            T& operator()() { return pid; }
            const T& operator()() const { return pid; }
          };
      };
      using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
    };

You seem to be getting something different for using _traits line? What is the exact command you are using for the code generation?

@shishirong
Copy link
Author

You seem to be getting something different for using _traits line? What is the exact command you are using for the code generation?

// generated by E:/.CPM_SOURCE_CACHE/sqlpp11/53edfea4b803fb5a9a646b29baed82aa8bcdcd10/scripts/sqlite2cpp.py ./0.sql ./DBModels DBModels

record in DBModels.h

@rbock
Copy link
Owner

rbock commented Apr 25, 2024

OK, we wandered far enough from the original topic of this issue :-)

I created #569

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants