[odb-users] query crash

Патрушев Данил Андреевич d.patrushev at prosoftsystems.ru
Fri Nov 3 07:58:34 EDT 2017



С уважением,
Инженер-программист
ООО «Прософт-Системы»
Патрушев Данил Андреевич

________________________________________
От: Boris Kolpackov <boris at codesynthesis.com>
Отправлено: 3 ноября 2017 г. 14:23
Кому: Патрушев Данил Андреевич
Копия: odb-users at codesynthesis.com
Тема: Re: [odb-users] query crash

Патрушев Данил Андреевич <d.patrushev at prosoftsystems.ru> writes:

> We have a single instance of odb::pgsql::database. We have a custom
> connection pool, all it does is override the "create" method which
> creates a connection with the socket options that we need.
>
> 1) odb::query<MYTABLE> q(MYTABLE::rowid == 555); // create query in main thread
>
> 2) auto functor = [q](){//copy query into the lambda
> odb::database* db = database(); //single instance
> odb::transaction tran(db->begin());
> auto result = db->query<MYTABLE>(q);
> //iterate over result and construct a list of db objects;
> tran.commit();
> return list_of_db_objects;
> };
>
> See, by result I mean a list of objects extracted from odb::result<MYTABLE>;
>
> 3) auto future = QtConcurrent::run(functor); //(I quess you are familiar with the Qt framework)
>    We launch a worker thread and wait for the finished signal (the original
>    query gets destroyed along the way)
>
> 4) The functor gets executed in the worker thread's context. After the
>    finished signal is emitted, we extract the result from the future by
>    calling future->result() in main thread;
>
> I quess that if odb::pgsql::query class is not thread-safe, then we are
> wrong to use it this way .

>No, this should work provided you don't have by-reference parameters
>in your query which you initialize concurrently from multiple threads.
>Quoting the manual, Section 4.3, "Executing a Query":

>"A named query instance that does not have any by-reference parameters is
>immutable and can be shared between multiple threads without
>synchronization. On the other hand, a query instance with by-reference
>parameters is modified every time it is executed. If such a query is shared
>among multiple threads, then access to this query instance must be
>synchronized from the execution point and until the completion of the
>iteration over the result."
>
>If this is not the issue, can you show the stack trace?
>
> Boris

Unfortunately, no exact stacktrace at hand.  But I can say that the latest crash happened during the destruction of query_base, specifically its "parameters_" member, which is of std::vector<details::shared_ptr<query_param> > type, the topmost line in the trace being 
    void dec (Y* p)
        {
          if (static_cast<shared_base*> (p)->_dec_ref ())
            delete p; 
        }
which is contained in file "odb/details/shared-ptr/base.txx"

"delete p " is where the program crashed.

So I thought that there just might be a problem  with details::shared_ptr, something along the lines of thread-safe increment and decrement of the shared pointer's counter. Just a wild guess.

Most of the previous crashes were in "init_parameters"  of base_query (all query parameters taken by value, by the way). We checked and rechecked the code, but still have no idea why this is happening 



More information about the odb-users mailing list