[odb-users] Segmentation fault inside destructor of a non-finalised transaction.

Kukreja, Suraj Suraj.Kukreja at qube-rt.com
Fri Feb 25 02:01:44 EST 2022


Hello Team,

We have got crash due to segmentation fault, inside odb::transaction destructor for an unfinalized transaction. Few things to note are :-
1) The crash is not occurring always, infact it has occurred only once till now for given piece of code flow.
2) The crash occurred after return at point 2b, in below code, during stack unwinding and the transaction being destructed is uncommitted / not finalised.
3) No updates were done on loaded object prior to return at point 2b

==============================================================================================================================================================================================================================

Stacktrace for the crash (libodb-2.5.0-b.19) - Postgres DB

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Missing separate debuginfo for /app/lib/libpq.so.5
Try: yum --enablerepo='*debug*' install /usr/lib/debug/.build-id/1d/44f164ff8c0e097da07cc4a9c4ae65717b4c52.debug
Core was generated by `<app_name> -f <configfile_name>'.
Program terminated with signal 11, Segmentation fault.
#0  0x00007f75f0dfaf0c in free () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.26-23.el7.x86_64 glibc-2.17-292.el7.x86_64 gssproxy-0.7.0-26.el7.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 krb5-libs-1.15.1-37.el7_6.x86_64 libcom_err-1.42.9-16.el7.x86_64 libselinux-2.5-14.1.el7.x86_64 libuuid-2.23.2-61.el7.x86_64 nspr-4.21.0-1.el7.x86_64 nss-3.44.0-4.el7.x86_64 nss-softokn-freebl-3.44.0-5.el7.x86_64 nss-util-3.44.0-3.el7.x86_64 openldap-2.4.44-21.el7_6.x86_64 openssl-libs-1.0.2k-19.el7.x86_64 pcre-8.32-17.el7.x86_64 sssd-client-1.16.4-21.el7.x86_64 zlib-1.2.7-18.el7.x86_64
(gdb) bt
#0  0x00007f75f0dfaf0c in free () from /lib64/libc.so.6
#1  0x00007f75f43326fc in __gnu_cxx::new_allocator<odb::transaction::callback_data>::deallocate(odb::transaction::callback_data*, unsigned long) () from /app/qrt_depl/qcore/securityd/lib/libodb-2.5.0-b.19.so
#2  0x00007f75f4332200 in std::allocator_traits<std::allocator<odb::transaction::callback_data> >::deallocate(std::allocator<odb::transaction::callback_data>&, odb::transaction::callback_data*, unsigned long) ()
   from /app/qrt_depl/qcore/securityd/lib/libodb-2.5.0-b.19.so
#3  0x00007f75f4331fa0 in std::_Vector_base<odb::transaction::callback_data, std::allocator<odb::transaction::callback_data> >::_M_deallocate(odb::transaction::callback_data*, unsigned long) ()
   from /app/qrt_depl/qcore/securityd/lib/libodb-2.5.0-b.19.so
#4  0x00007f75f4331d99 in std::_Vector_base<odb::transaction::callback_data, std::allocator<odb::transaction::callback_data> >::~_Vector_base() () from /app/qrt_depl/qcore/securityd/lib/libodb-2.5.0-b.19.so
#5  0x00007f75f4331de9 in std::vector<odb::transaction::callback_data, std::allocator<odb::transaction::callback_data> >::~vector() () from /app/qrt_depl/qcore/securityd/lib/libodb-2.5.0-b.19.so
#6  0x00007f75f4330f4a in odb::transaction::~transaction() () from /app/qrt_depl/qcore/securityd/lib/libodb-2.5.0-b.19.so

==============================================================================================================================================================================================================================

Below is the sample code, as per the flow we have ,  hiding the application specific implementation, and only showing the ODB transaction operations.
error_code func_with_crash()
{
  odb::session tempCache;
  odb::session::current(tempCache);

  try
  {
                transaction t(_db->begin());

                shared_ptr<db_object_classname> obj(_db->load<db_object_classname>(<object_id>);

                if(loaded object is of type 1)
                {
                                1a) Do validations on loaded object
                                1b) return failure, without committing transaction, if validation failed
                                1c) go further if validation is successful, and perform updates on loaded object
                }
                else // loaded object is of type 2
                 {
                                2a) Do validations on loaded object
                                2b) return failure, without committing transaction, if validation failed
                                2c) go further if validation is successful, and perform updates on loaded object
                }

                t.commit();
  }
  catch (const odb::exception &e)
  {
    LOG_ERROR << "EXCEPTION - " << e.what() << go;
    return <error code>;
  }
  catch (const std::bad_optional_access &e)
  {
    LOG_ERROR << "EXCEPTION - " << e.what() << go;
    return <error code>;
  }
  catch (const std::exception &e)
  {
    LOG_ERROR << "EXCEPTION - " << e.what() << go;
    return <error code>;
  }

  odb::session::reset_current();
  return <success>;
}


Let me know if you need more info, or something is not clear in the mail.

Thanks
Suraj Kukreja


More information about the odb-users mailing list