I working on migration of a product from QT4 to 5.
I am getting this error while backtracing it-
#0 0x00007ffff5488cd1 in QAction::text() const () from /fa/sw/registry/22851-export_qt5-04-soni-01/serverdist/dist/x86_linux/lib64/libQt5Widgets.so.5
#1 0x0000000000c17435 in cQ_ELEMENTS_COMBOBOX::AppendItem(QString const&) ()
#2 0x00000000005441e6 in cEXPORT_FILE_PARMS::initialize(QWidget*, cQ_GRID_LAYOUT*, int, bool, char const*) ()
#3 0x0000000000545ad3 in cEXPORT_FILE_PARMS::cEXPORT_FILE_PARMS(QWidget*, cGV_DEC_PROJECT*, ExportOutputFileParameterSet*, cQ_GRID_LAYOUT*, int, QString) ()
asINT32 cQ_ELEMENTS_COMBOBOX::AppendItem(const QString &item_name)
{
//if item already exists then do not append item
if(GetAction(m_popup_p, item_name) == NULL) {
m_popup_p->addAction(item_name);
return 0;
}
return -1;
}
QAction* GetAction(QMenu* menu, const QString& actionName){
QList<QAction*>::iterator menuItr = menu->actions().begin();
/*const*/ QList<QAction*>::iterator menuEnd = menu->actions().end();
while (menuItr != menuEnd)
{
if((*menuItr)->text() == actionName){
return *menuItr;
}
menuItr++;
}
return NULL;
}
After giving print statements on this line program crashes -
if((*menuItr)->text() == actionName)
sometimes it works and sometimes it crashes, not able to see a particular pattern. Is there any workaround or any way to catch the segmentation fault beforehand.
Related
I have a class that has a bsoncxx::document::view view as a private attribute, and a method that get a document from the Mongo database and save the result in the local bsoncxx::document::value value variable and then get the view from the value.view() and save it in the class bsoncxx::document::view view variable:
const bool User::search_one_by_id(const std::string &id = "")
{
// The prototype of the method below: const std::tuple<bool, bsoncxx::document::value> search_one_by_id(mongocxx::collection &, const std::string &) const;
auto status = Crud::search_one_by_id(this->collection, id);
if (std::get<0>(status))
{
// Error
return EXIT_FAILURE;
}
else
{
// Success
bsoncxx::document::value value = std::get<1>(status);
bsoncxx::document::view view = value.view();
this->view = view;
return EXIT_SUCCESS;
}
}
The problem is that if I get some element from the view in the method above, i.e the code below before the return EXIT_SUCCESS, no errors are issued.
bsoncxx::document::element element = this->view["first_name"];
std::cout << "First Name: " << element.get_utf8().value.to_string();
But if I get a view, save it in the bsoncxx::document::view view variable and try to get some element from the view in another class method:
void get_element()
{
bsoncxx::document::element element = this->view["first_name"];
std::cout << "First Name: " << element.get_utf8().value.to_string();
}
I receive the error:
terminate called after throwing an instance of 'bsoncxx::v_noabi::exception'
what(): unset document::element
Makefile:26: recipe for target 'run' failed
make: *** [run] Aborted (core dumped)
I had tried to use a pointer to save the reference to the view that I get in the search_one_by_id method. I had check if the type of the attribute (first_name) I'm getting is the right type to get the value of the element. I had check if the attribute exist in the document. I had tried to use the release() method from the view in the User::search_one_by_id. I had check if the view is empty through:
if (this->view.empty())
{
std::cout << "Empty: " << this->view.empty();
}
else
{
std::cout << "Loaded: " << this->view.empty() << " length " << this->view.length();
}
Inside the get_element method, and the output is:
# If I comment the call to search_one_by_id
$ Empty: 1
# If I enable the call to search_one_by_id
$ Loaded: 0 length 129
The GDB log to backtrace:
#0 __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff6fd7801 in __GI_abort () at abort.c:79
#2 0x00007ffff762c957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7632ab6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7632af1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7632d24 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff793985c in bsoncxx::v_noabi::document::element::type() const () from /usr/local/lib/libbsoncxx.so._noabi
#7 0x00007ffff7939abc in bsoncxx::v_noabi::document::element::get_utf8() const () from /usr/local/lib/libbsoncxx.so._noabi
#8 0x0000555555559353 in User::get_element() ()
#9 0x0000555555556668 in main ()
Some tips ? The project can be found on Github
References:
Unset Document::element, MongoCXX Find Option Projection
Document value
Document view
Document element
document::element::operator[] overloads should not throw when given an invalid element
How do I get the type of a variable?
i think you need to keep the pointer to buffer of value somewhere. view object is pointing to deleted memory i suppose. try something like this
class User
{
bsoncxx::document::value _value; <<< store at class level
};
const bool User::search_one_by_id(const std::string &id = "")
{
// The prototype of the method below: const std::tuple<bool, bsoncxx::document::value> search_one_by_id(mongocxx::collection &, const std::string &) const;
auto status = Crud::search_one_by_id(this->collection, id);
if (std::get<0>(status))
{
// Error
return EXIT_FAILURE;
}
else
{
// Success
_value = std::get<1>(status);
this->view = _value.view();
return EXIT_SUCCESS;
}
}
My program seems to be crashing while inserting and int into a set, and I cannot track down the reason for this. Here is there relevant code:
bool request::check_list(std::vector<int> search_vec)
{
std::set<int> *tmp_ptr = create_int_set();
boost::shared_ptr<std::set<int> > c_list(tmp_ptr);
if(aerospike_query_foreach(as, &err, NULL, &query, process_set, &c_list) != AEROSPIKE_OK)
{
return false;
}
for(int i = 0; i < search_vec.size(); i++)
{
if(c_list->find(search_vec[i]) != c_list->end())
{
c_list_value_ = search_vec[i];
return true;
}
}
return false;
}
bool request::process_set(const as_val *val, void * udata)
{
try
{
boost::shared_ptr<std::set<int> > c_set = *(boost::shared_ptr<std::set<int> > *)(udata);
if(val == NULL)
{
return true;
}
if(val->type == AS_REC)
{
if (val!=NULL)
{
as_record *rec = as_record_fromval(val);
if (rec!=NULL)
{
as_integer* c_id = as_record_get_integer(rec,"c_id");
int cid = 0;
cid = boost::lexical_cast<int>(c_id->value);
if(c_set != nullptr)
{
c_set->insert(c_id);
}
as_record_destroy(rec);
as_integer_destroy(c_id);
}
}
return true;
}catch(...){}
return false;
}
The line c_set->insert(c_id); is causing a segfault. Here is this backtrace of the crash:
#0 0x00007f2064299f94 in std::_Rb_tree_rotate_right(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*&) () from /usr/lib64/libstdc++.so.6
#1 0x00007f206429a12b in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib64/libstdc++.so.6
#2 0x00000000004829d9 in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_insert_<int const&> (this=0x7f1fcc005440, __x=0x0, __p=0x7f1f3c0009a0, __v=#0x7f20159e729c)
at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:981
#3 0x000000000047f1e0 in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_insert_unique<int const&> (this=0x7f1fcc005440, __v=#0x7f20159e729c)
at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:1299
#4 0x000000000047c473 in std::set<int, std::less<int>, std::allocator<int> >::insert (this=0x7f1fcc005440, __x=#0x7f20159e729c)
at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_set.h:415
#5 0x00000000004765ee in request::process_set (val=0x7f20159e73e0, udata=0x7f200b9d6620) at ../../request.cpp:1862
I am assuming there is a problem where the set is not being initialized, or something similar to that. Here is how I create and pass the set from the another function, I have tried two ways to create it:
boost::shared_ptr<std::set<int> > c_list(new std::set<int>());
and
std::set<int> *tmp_ptr = create_int_set();
boost::shared_ptr<std::set<int> > c_list(tmp_ptr);
std::set<int>* request::create_int_set()
{
return new std::set<int>();
}
The calling function is a callback function from a database driver, that takes in a few different objects, most notably however are the process_set and the c_list, which is passed as a void*:
aerospike_query_foreach(as, &err, NULL, &query, process_set, &c_list)
This crash does not happen all the time, in fact it is fairly rare, which makes me think there is something I am doing wrong, some sort of undefined behavior. Any help would be greatly appreciated!
The aerospike APi documentation says for the callback (i.e. process_set(), here):
Execute a query and call the callback function for each result item.
Multiple threads will likely be calling the callback in parallel.
Therefore, your callback implementation should be thread safe.
As several threads might insert at the same time in the same set (the one pointed to by your shared pointer), you'll get race conditions and hence undefined behaviour !
So I think that you should protect at least your set insertion block with a lock_guard on a mutex.
Important edit: boost::shared_ptr<> can't assumed to be thread safe. In the examples on boost.org, they suggest that a shared pointer going out of scope might cause a race. It may therefore be highly advisable to follow Matthew Moss's suggestion in the comments and use a raw pointer to the set within the bounds of process_set().
I have the following function
static node_ptr make_node_ptr()
{
return node_ptr(new node());
}
where using node_ptr = std::shared_ptr<node>;
I tried to find my segmentation fault with valgrind and gdb. In both I get more or less the same stack trace.
Program received signal SIGSEGV, Segmentation fault.
0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
(gdb) bt
#0 0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
#1 0x00007fff8f5d7877 in malloc_zone_malloc () from /usr/lib/system/libsystem_malloc.dylib
#2 0x00007fff8f5d6395 in malloc () from /usr/lib/system/libsystem_malloc.dylib
#3 0x00000001000f17d8 in operator new(unsigned long) () from /usr/local/lib/gcc/4.9/libstdc++.6.dylib
#4 0x0000000100009c04 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<msc::scene_manager<float, int, 3ul>::node*> (this=0x7fff5f4002e8, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:569
#5 0x0000000100008c78 in std::__shared_ptr<msc::scene_manager<float, int, 3ul>::node, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:871
#6 0x00000001000079e5 in std::shared_ptr<msc::scene_manager<float, int, 3ul>::node>::shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr.h:113
#7 0x0000000100005bdc in msc::scene_manager<float, int, 3ul>::make_node_ptr () at ../../common/msc/scene.d/scene_manager_def.h:98
#8 0x00000001000037dd in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (wrappee=...) at ../../common/msc/scene.d/node_impl.h:73
#9 0x0000000100003d53 in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (nodes=...) at ../../common/msc/scene.d/node_impl.h:112
#10 0x0000000100004011 in msc::scene_manager<float, int, 3ul>::insert (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:97
#11 0x0000000100006071 in msc::scene_manager<float, int, 3ul>::insert_if_leq (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:127
The last 2 lines repeat endlessly, I guess at least, as I tried to continue until frame #6000 or smth.
Am I missing something or is the creation of this shared_ptr not allowed?
Edit
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
{
bool swapped = false;
if (root == nullptr)
root = other;
else
{
auto inside = msc::inside::test(*root, *other);
if (inside == msc::inside::NONE)
{
auto oldRoot = root;
root = node::generate_wrapping_node(
std::vector<node_c_ptr>{ oldRoot, other });
insert_if_leq(root, oldRoot);
}
else if ((swapped = (inside == msc::inside::FIRST)))
{
std::swap(root, other);
}
other = insert_if_leq(root, other);
}
return !swapped ? other : root;
}
node_ptr scene_manager::insert_if_leq(node_ptr root, node_ptr other)
{
node_ptr res = root;
if (are_similar(*root, *other))
msc::move_append(root->children, other->children);
else
{
auto idx = root->get_quadrant_idx(other->center);
res = insert(root->quadrants[idx], other);
}
return res;
}
These are the functions which repeat. msc is my own namespace.
As the functions are recursive insert calls insert_if_leq and vice versa, I had to make node_ptr root in insert_if_leq a reference, because the assignment in insert depended on it. The new function definitions are as follows:
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
node_ptr scene_manager::insert_if_leq(node_ptr & root, node_ptr other)
I have the following std::map defined:
//The map holding the list of registered services per partition key.
std::map<SRServicePartitionKey, std::vector<EndPointAddr*>* > mServiceMap;
I have below indicated function whose aim is to remove a specific EndPointAddr* pointer in the vector that is kept in the value of the above defined Map instance. I am getting a SEGABORT in gdb after the following scenario realized:
Add multiple items to the map
Delete the items using the below function one by one.
Add those deleted items again (a few of them)
Delete one item ==> AT THIS POINT I get a sigabort in GDB with the following message:
* glibc detected * /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/build_output/ServiceRegistrar: double free or corruption (fasttop): 0x00007ffff0002e10 *
GDB Back trace is available at the bottom...
QUESTION
What particular things do you think are wrong in this removal function below? Why do I get this "Double free or corruption" error? What do you think I am missing in the removal function where I first find the item to be deleted, then remove it from the vector and finally deallocate it.
REMOVAL FUNCTION
bool
ServiceRegistrar::removeService(const EndPointAddr & epAddrForRemoval)
{
bool condErased = false;
for(auto it = mServiceMap.begin(); it != mServiceMap.end(); ++it)
{
std::cout << "\tPartition ["
<< (*it).first.getInstanceNo() << ","
<< (*it).first.getContext() << ","
<< (*it).first.getVersion() << "]:"
<< std::endl;
std::vector<EndPointAddr*> * serviceList = (*it).second;
auto found =
std::find_if(serviceList->begin(),
serviceList->end(),
[epAddrForRemoval]( EndPointAddr* otherEPAddr )
{
const EndPointTipcAddr & tipcAddrToRemove = epAddrForRemoval.getImmutableTipcAddress();
const EndPointTipcAddr & otherTipcAddr = otherEPAddr->getImmutableTipcAddress();
return (tipcAddrToRemove.compareTo(otherTipcAddr));
});
EndPointAddr * toBeDeAllocatedEP = *found;
auto toBeErasedEP =
std::remove_if(serviceList->begin(),
serviceList->end(),
[epAddrForRemoval]( EndPointAddr* otherEPAddr )
{
const EndPointTipcAddr & tipcAddrToRemove = epAddrForRemoval.getImmutableTipcAddress();
const EndPointTipcAddr & otherTipcAddr = otherEPAddr->getImmutableTipcAddress();
return (tipcAddrToRemove.compareTo(otherTipcAddr));
});
if(toBeErasedEP != serviceList->end())
{
serviceList->erase(toBeErasedEP, serviceList->end());
condErased = true;
}
if(toBeDeAllocatedEP != 0)
{
!!!!!!!!!!!!LINE 1396 is HERE!!!!!!!!!!!!!!!
delete toBeDeAllocatedEP;
}
} //end of For Loop
return condErased;
}
GDB BackTrace
(gdb) bt
#0 0x00007ffff7026425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7029b8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff706439e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff706eb96 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007ffff7681540 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x0000000000434604 in EndPointIpAddr::~EndPointIpAddr (this=0x7ffff0002fb0, __in_chrg=<optimized out>) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_components/../control_api/api_util/EndPointIpAddr.hpp:28
#6 0x0000000000434660 in EndPointAddr::~EndPointAddr (this=0x7ffff0002f90, __in_chrg=<optimized out>) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_components/../control_api/api_util/EndPointAddr.hpp:36
#7 0x000000000043c97f in ServiceRegistrar::removeService (this=0x7fffffffdea0, epAddrForRemoval=...) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_api/ServiceRegistrar.cpp:1396
You appear to be using found without checking if it's valid or not. If you were to fail to find a value and find_if returned serviceList->end(), you'd be dereferencing serviceList->end().
The variable you're storing this dereferenced value to is the one that's causing you trouble later when you attempt to delete it. Are you sure you're actually finding a matching value?
I have a list of pointers as a member of a class. I instantiate that class, and various functions such as size() and empty() fail with a segfault when the list is empty. When I add something to the list, they're fine. I tried to abstract what I'm doing with a test file, and it works perfectly. This is what I THINK I'm doing when my code fails (though am clearly not):
#include <list>
#include <iostream>
class Test {
int i;
};
int main() {
std::list<Test*> tlist;
if (tlist.empty()) {
std::cout << "List empty";
} else {
std::cout << "List not empty";
}
}
I can't really post the entire code listing that's causing the issue, as it's fairly large and over a bunch of files, but will try to paste all the relevant bits straight from code:
Class declaration in player.h:
class Player : public ScreenObject {
private:
std::list<Thing*> inventory;
Nothing is done to that list in the constructor.
Where it's failing:
main.cpp:
Player pc(iname, w_choice, c_choice, 11, 11, WHITE, '#');
....
if (pc.addToInv(t)) {
currentLevel.delObject(id);
}
....
player.cpp:
int Player::addToInv(Thing& t) {
if (inventory.size() <= 52) {
inventory.push_back(&t);
} else {
shiplog("Cannot add to inventory, 52 item limit reached",10);
return 0;
}
}
The error I get when running it with gdb occurs on the call to size(), and ends up here:
Program received signal SIGSEGV, Segmentation fault.
0x0804eda6 in std::_List_const_iterator<Thing*>::operator++ (this=0xbfff9500)
at /usr/include/c++/4.4/bits/stl_list.h:223
223 _M_node = _M_node->_M_next;
Any guesses much appreciated!
Full backtrace is:
(gdb) bt
0 0x0804e28a in std::_List_const_iterator<Thing*>::operator++ (
this=0xbfff9500) at /usr/include/c++/4.4/bits/stl_list.h:223
1 0x0804e64e in std::__distance<std::_List_const_iterator<Thing*> > (
__first=..., __last=...)
at /usr/include/c++/4.4/bits/stl_iterator_base_funcs.h:79
2 0x0804e4d3 in std::distance<std::_List_const_iterator<Thing*> > (
__first=..., __last=...)
at /usr/include/c++/4.4/bits/stl_iterator_base_funcs.h:114
3 0x0804e2e6 in std::list<Thing*, std::allocator<Thing*> >::size (
this=0xbffff244) at /usr/include/c++/4.4/bits/stl_list.h:805
4 0x0804df78 in Player::addToInv (this=0xbffff068, t=...) at player.cpp:551
5 0x0804a873 in main (argc=1, argv=0xbffff494) at main.cpp:182
int Player::addToInv(Thing& t) {
if (inventory.size() <= 52) {
inventory.push_back(&t);
} else {
shiplog("Cannot add to inventory, 52 item limit reached",10);
return 0;
}
}
Thing is passed by reference, but then its address is passed to inventory.push_back(). Try just passing 't'.