I get these random seg faults on netbeans - c++

I'm doing c++ and the code is giving me these errors:
new size of the done 64
getting next item to do (0x90b9c0 0x90bab0 0x90be40 0)
vector wait size = 0
running size = 1
done size = 64
done this align #27# #26# Gorilla_gorilla_2
setting the done tuple to 1 to get them next
new size of the done 65
getting next item to do (0xbff3897200000000 0xbfda1b75f84c0030 0x30 17)
vector wait size = 18446744073709551615
running size = 1
done size = 65
getting next item to do (0xbfdcc288867fc50b 0x31 0x1 1)
/usr/local/netbeans-7.2rc1/ide/bin/nativeexecution/dorun.sh: line 33: 8234
Segmentation
fault (core dumped) sh "${SHFILE}"
And I wonder how can I get more details of the seg fault, like the line that caused it, to fix it, thanks.
Edit:
bool tuple_compare(boost::tuple< ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple)
{
if( boost::get< 3 >( tuple) == true)
{
return true;
}
else
{
return false;
}
}
void threaded_function(Model_factory &mf, ppa::Node *root)
{
try {
while(true)
{
boost::mutex::scoped_lock lock(result_mutex);
if(wait.empty())
{
lock.unlock();
break;
}
else {
lock.unlock();
lock.lock();
if(!running_jobs.empty())
{
cout << "vector wait size = " << wait.size() << endl;
cout << "running size = " << running_jobs.size() << endl;
cout << "done size = " << done.size() << endl;
boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple = running_jobs.back();
running_jobs.pop_back();
lock.unlock();
ppa::Node *father = boost::get<0>(tuple);
ppa::Node *first_son = boost::get<1>(tuple);
ppa::Node *second_son = boost::get<2>(tuple);
bool flag = boost::get<3>(tuple);
father->start_alignment_new(&mf);
lock.lock();
cout << "done this align " << father->get_name() << " " << first_son->get_name() << " " << second_son->get_name()
<< endl;
cout << "setting the done tuple to 1 to get them next" << endl;
done.push_back(tuple);
cout << "new size of the done " << done.size() << endl;
lock.unlock();
}
else {
lock.unlock();
lock.lock();
cout << "getting next item to do " << wait.back() << endl;
boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> run = wait.back();
running_jobs.push_back(run);
wait.pop_back();
lock.unlock();
}
}
}
}
catch (boost::lock_error& le)
{
cout << "error this " << le.what() << endl;
}
}
Main:
int main(int argc, char *argv[])
{
clock_t t_start=clock();
ppa::Node* parent;
ppa::Node* left;
ppa::Node* rigth;
ppa::Node* check_root;
/*
...
boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple = dups.back();
ppa::Node *n = boost::get<0>(tuple);
//cout << "creating waiting thread" << endl;
// g.create_thread( boost::bind(wait_function));
cout << "creating other threads" << endl;
for ( int i = 0; i < 5; ++i )
{
cout << "making thread " << i << endl;
g.create_thread( boost::bind( threaded_function, boost::ref(mf), boost::ref(n) ));
}
cout << g.size() << endl ;
// wait for them
// sleep(15);
g.join_all();
I'm pretty sure it comes form this part that is the new I have added.

Bad code, too many locks and unlocks, mutex has a lock method no need to use shared lock.lock()

Related

Not sure where the segmentation fault is

I'm getting problem with segmentation fault when trying to compile a C++ program, but not sure where the problem lies. I suspect that the problem lies with the .find() ..... could it be the iterator operator < and == which are the comparators for find() that is the issue? I hope that someone can point out to me where they think the problem lies.
The following is part of test01.cpp, where I run it to test the code and use print statements to find out where the problem is:
bool confirmEverythingMatches(const btree<long>& testContainer, const set<long>& stableContainer) {
cout << "Confirms the btree and the set "
"contain exactly the same values..." << endl;
for (long i = kMinInteger; i <= kMaxInteger; i++) {
cout << "Start of for-loop to find iterator for comparisons..." << endl;
if (stableContainer.find(i) != stableContainer.end()) {
cout << "can find i (" << i << ") in stableContainer!" << endl;
} else {
cout << "cannot find i (" << i << ") in stableContainer!" << endl;
}
cout << "In between finding i in stable and testContainers..." << endl;
if (testContainer.find(i) != testContainer.end()) {
cout << "can find i (" << i << ") in testContainer!" << endl;
} else {
cout << "cannot find i (" << i << ") in testContainer!" << endl;
}
cout << "Before assigning the find to boolean variables..." << endl;
bool foundInTree = (testContainer.find(i) != testContainer.end());
cout << "testContainer.find(i) != testContainer.end()" << endl;
bool foundInSet = (stableContainer.find(i) != stableContainer.end());
cout << "stableContainer.find(i) != stableContainer.end()" << endl;
if (foundInTree != foundInSet) {
cout << "- btree and set don't contain the same data!" << endl;
cout << "Mismatch at element: " << i << endl;
return false;
} else {cout << "foundInTree == foundInSet!!!" << i << endl;}
}
cout << "- btree checks out just fine." << endl;
return true;
}
} // namespace close
/**
* Codes for testing various bits and pieces. Most of the code is commented out
* you should uncomment it as appropriate.
**/
int main(void) {
// initialise random number generator with 'random' seed
initRandom();
cout << "after initRandom().." << endl;
// insert lots of random numbers and compare with a known correct container
btree<long> testContainer(99);
cout << "after specifying max node elements in testContainer.." << endl;
set<long> stableContainer;
cout << "after constructing stableContainer.." << endl;
insertRandomNumbers(testContainer, stableContainer, 1000000);
cout << "after inserting random numbers into testContainer and for success inserts, also into stableContainer.." << endl;
btree<long> btcpy = testContainer;
cout << "after copy assigning a copy of testContainer to btcopy.." << endl;
confirmEverythingMatches(btcpy, stableContainer);
cout << "after confirming everything internally matches between testContainer and stableContainer.." << endl;
return 0;
}
The output I get when running the program (No problem when compiling) is this:
Confirms the btree and the set contain exactly the same values...
Start of for-loop to find iterator for comparisons...
cannot find i (1000000) in stableContainer!
In between finding i in stable and testContainers...
ASAN:DEADLYSIGNAL
=================================================================
==7345==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x000108d132a8 bp 0x000000000000 sp 0x7fff56eee6f0 T0)
#0 0x108d132a7 in btree<long>::find(long const&) const (test01+0x1000022a7)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (test01+0x1000022a7) in btree<long>::find(long const&) const
==7345==ABORTING
Abort trap: 6
I also got this error when I tried to run it on another machine:
==29936==ERROR: AddressSanitizer failed to allocate 0x200000 (2097152) bytes of SizeClassAllocator32: 12
I found that when it goes into the find(), it will have the segmentation fault:
/**
* Identical in functionality to the non-const version of find,
* save the fact that what's pointed to by the returned iterator
* is deemed as const and immutable.
*
* #param elem the client element we are trying to match.
* #return an iterator to the matching element, or whatever the
* const end() returns if no such match was ever found.
*/
template<typename T> typename btree<T>::const_iterator
btree<T>::find(const T& elem) const {
std::cout << "CONST ITERATOR'S FIND" << std::endl;
Node *tmp_ = root_;
std::cout << "1" << std::endl;
while(true) {
std::cout << "2" << std::endl;
size_t i;
std::cout << "3" << std::endl;
// go through all elements from root to tail
for (i = 0; i < tmp_->__occupied_size_; ++i) {
std::cout << "4" << std::endl;
if (tmp_->__elem_[i] == elem) {
std::cout << "5" << std::endl;
// find the elem, return an iterator
return const_iterator(tmp_, i, this);
std::cout << "6" << std::endl;
} else if (tmp_->__elem_[i] > elem) {
std::cout << "7" << std::endl;
// elem is not in current Node, go to descendants
// for the elem.
if (tmp_->__descendants_ == nullptr) {
std::cout << "8" << std::endl;
return cend();
std::cout << "9" << std::endl;
} else {
std::cout << "10" << std::endl;
tmp_ = tmp_->__descendants_[i];
std::cout << "11" << std::endl;
break;
}
}
}
// handling boundaries cases
if (i == tmp_->__occupied_size_) {
std::cout << "12" << std::endl;
if (tmp_->__descendants_[i] == nullptr) {
std::cout << "13" << std::endl;
return cend();
std::cout << "14" << std::endl;
} else {
std::cout << "15" << std::endl;
tmp_ = tmp_->__descendants_[i];
}
}
}
}
The print statements for this find is:
CONST ITERATOR'S FIND
1
2
3
4
4
7
10
11
2
3
4
7
10
11
ASAN:DEADLYSIGNAL
Ok, so based on the implementation of this find function, I think the problem might be located in
if (tmp_->__descendants_ == nullptr) {
std::cout << "8" << std::endl;
return cend();
std::cout << "9" << std::endl;
} else {
std::cout << "10" << std::endl;
tmp_ = tmp_->__descendants_[i];
std::cout << "11" << std::endl;
break;
}
and then
// handling boundaries cases
if (i == tmp_->__occupied_size_) {
std::cout << "12" << std::endl;
if (tmp_->__descendants_[i] == nullptr) {
std::cout << "13" << std::endl;
return cend();
std::cout << "14" << std::endl;
} else {
std::cout << "15" << std::endl;
tmp_ = tmp_->__descendants_[i];
}
}
So, You are checking if tmp->__descendants_ is not null. If it is not, then you set tmp_ = tmp_->descendants_[i];
Note: you are just checking __descendants_ pointer to be null or not, you are not checking the __descendants_ [i] if it is null!
What if the tmp->__descendants_[i] is null (or gets out of the descendants array)?
If that value is null, then tmp_->occupied_size_ might give you segfault.
Note2: For some reason you are using same index "i" for iterating through __elem_ and __descendants_. I am not sure, how descendants are created, but it might be also a problem here.
This is why debuggers exist. Run your program in the debugger, let the program fail, and then the debugger will tell you where and why it's gone wrong.
It looks like you've got potentially a lot of code to trawl through, which no one here will really want to do as it's not a concise question.
Good luck!

Seemingly empty vector

I've added some slight multi threading to a simple c++ program and have encountered a few issues along the way.
The latest of these issues is that historical::assignthreads for some reason is receiving an empty vector from the function historical::writeData.
Looking at the code below you will see that writeData iterates through a vector and puts the data in a placeholder before sending it forward to assignthreads (after 5 iterations) - meaning that the vector being sent from writeData to assignthreads shouldn't be empty.
However in assignthreads you will see that there are two cout:s, one before and one after the loop. Both writes to cout without the loop even starting.
Does anyone have any idea of how this could be the case?
void historical::writeData(std::vector<std::vector<std::wstring>> in, const string& symbol) {
std::cout << "Sending data to database connector" << std::endl;
std::vector<std::vector<std::wstring>> temp;
std::vector<std::vector<std::wstring>>::iterator it;
int count = 0;
for (it = in.begin(); it != in.end(); it++) {
if (count = 5) {
cout << "I'm in count 5" << endl;
assignthreads(temp, symbol);
temp.clear();
count = 0;
}
else {
cout << "I'm in count 0" << endl;
temp.push_back(*it);
count++;
}
}
if (!temp.empty()) {
cout << "I'm in empty" << endl;
assignthreads(temp, symbol);
}
else cout << "I'm empty!!" << endl;
}
void historical::assignthreads(std::vector<std::vector<std::wstring>>& partVec, const string& symbol) {
int i = 0;
cout << "I'm in assign" << endl;
vector<thread> threads(size(partVec));
std::vector<std::vector<std::wstring>>::iterator it;
for (it = partVec.begin();
it != partVec.end();
it++) {
cout << "I'm in the loop" << endl;
std::shared_ptr<database_con> sh_ptr(new database_con);
threads.at(i) = std::thread(&database_con::start, sh_ptr, *it, symbol);
i++;
}
cout << "I've finished" << endl;
for (auto& th : threads) th.join();
}
void historical::writer(string* pInput) {
ofstream mf("test.csv");
if (mf.is_open()) {
mf << *pInput;
mf.close();
}
else cout << "Unable to open file" << endl;
}
Your fundamental problem here is that count = 5 is an assignment and is therefore always true. You intended to use count == 5.
It's worth noting that particularly as your vector becomes large copying it is very wasteful, and you're doing this 2 ways:
The vector is passed into writeData by value, change to copying by reference: void writeData(std::vector<std::vector<std::wstring>>& in, const string& symbol)
temp will eventually copy every element of in, use iterators instead so your code would have to change to:
#define SIZE 5
void assignthreads(std::vector<std::vector<std::wstring>>::iterator start, std::vector<std::vector<std::wstring>>::iterator finish, const string& symbol) {
cout << "I'm in assign" << endl;
vector<thread> threads(distance(start, finish));
for(auto i = 0; start != finish; ++i, ++start) {
cout << "I'm in the loop" << endl;
std::shared_ptr<database_con> sh_ptr(new database_con);
threads.at(i) = std::thread(&database_con::start, sh_ptr, *start, symbol);
}
cout << "I've finished" << endl;
for (auto& th : threads) th.join();
}
void writeData(std::vector<std::vector<std::wstring>>& in, const string& symbol) {
std::cout << "Sending data to database connector" << std::endl;
auto count = 0;
while(count < in.size() - SIZE) {
auto start = next(in.begin(), count);
count += SIZE;
auto finish = next(in.begin(), count);
assignthreads(start, finish, symbol);
}
assignthreads(next(in.begin(), count), in.end(), symbol);
cout << "I'm empty!!" << endl;
}

Infinite Loop while inputting the different data type values in STACK

Below is the code for STACK with no overflow since I am using vector concept. Program seems to be working fine as long as I push integers, but as soon as I push float value (for testing) the output screen goes to infinite loop and debugger doesn't even stop at cin statement and it simply crosses it without giving the control to the console window.
#include"iostream"
class Mystack
{
private:
int *input;
int top;
int capacity;
public:
Mystack();
~Mystack();
void push(int x);
int pop();
int topElement() const;
bool isEmpty() const;
void print();
};
Mystack::Mystack()
{
top = -1;
capacity = 5;
input = new int[capacity];
}
Mystack::~Mystack()
{
delete[]input;
}
void Mystack::push(int x)
{
if (top + 1 == capacity)
{
int *vec = new int[capacity+capacity];
for (int i = 0; i <=top; i++)
{
vec[i] = input[i];
}
input = vec;
capacity = capacity * 2;
top++;
input[top] = x;
}
else
{
top++;
input[top] = x;
}
}
int Mystack::pop()
{
if (isEmpty())
{
throw std::out_of_range("Stack Underflow");
}
else
{
std::cout << "The popped element is" << input[top];
return input[top--];
}
}
bool Mystack::isEmpty() const
{
if (top == -1)
{
std::cout << "Is Empty" << std::endl;
return true;
}
else
{
std::cout << "Not Empty" << std::endl;
return false;
}
}
int Mystack::topElement() const
{
if (top == -1)
{
throw std::out_of_range("No Element to Display");
}
else
{
std::cout << "The top element is : " << input[top];
return input[top];
}
}
void Mystack::print()
{
for (int i = 0; i <= top; i++)
{
std::cout << input[i] << " ";
}
}
int main()
{
Mystack s1;
int num, ch = 1;
while (ch >0)
{
std::cout << "\n1. PUSH" << std::endl;
std::cout << "2. TOP" << std::endl;
std::cout << "3. IsEmpty" << std::endl;
std::cout << "4. POP" << std::endl;
std::cout << "5. EXIT" << std::endl;
std::cout << "6. Print" << std::endl;
std::cout << "Enter the choice" << std::endl;
std::cin >> ch; // DEBUGGER DOES NOT GIVE CONTROL TO CONSOLE WINDOW AND ASK FOR INPUT ONCE I PUT FLOAT VALUES, IT SIMPLE CROSSES IT
switch (ch)
{
case 1:
std::cout << "Enter the number to be pushed" << std::endl;
std::cin >> num;
s1.push(num);
break;
case 2:
std::cout << "Get the TOP Element" << std::endl;
try
{
s1.topElement();
}
catch (std::out_of_range &oor)
{
std::cerr << "Out of Range error:" << oor.what() << std::endl;
}
break;
case 3:
std::cout << "Check Empty" << std::endl;
s1.isEmpty();
break;
case 4:
std::cout << "POP the element" << std::endl;
try
{
s1.pop();
}
catch (const std::out_of_range &oor)
{
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
break;
case 5: exit(0);
case 6:
s1.print();
break;
default:
std::cout << "Enter a valid input";
break;
}
}
std::cin.get();
}
Once you input the int value for example as 1.1 (invalid int value). Input conversion error occurs and the input stream because of invalid data ignores the rest of the operation even the cin. Make your code more generic in order for it to handle float or double or char.

Deleting and object in a position from a deque

I have this code:
bool tuple_compare(boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> &tuple_from_done)
{
for(int i = 0; i < deque_wait.size(); i++) {
boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple_from_wait = deque_wait.at(i);
ppa::Node *father = boost::get<0>(tuple_from_wait);
ppa::Node *son = boost::get<0>(tuple_from_wait);
ppa::Node *second_son = boost::get<2>(tuple_from_wait);
bool has_seq = boost::get<3>(tuple_from_wait);
cout << "checking this two " << boost::get<1>(tuple_from_wait)->get_name() << " bool sequence "
<< boost::get<1>(tuple_from_wait)->node_has_sequence_object << " and this "
<< boost::get<2>(tuple_from_wait)->get_name() << " bool seq " << boost::get<2>(tuple_from_wait)->node_has_sequence_object
<< " with " << boost::get<0>(tuple_from_done)->get_name() << endl;
if(boost::get<0>(tuple_from_done)->get_name() == boost::get<1>(tuple_from_wait)->get_name()
|| boost::get<0>(tuple_from_done)->get_name() == boost::get<2>(tuple_from_wait)->get_name())
{
cout << " found in here this we need to check if there is something if the sons have a sequences!!!! " << endl;
if(boost::get<1>(tuple_from_wait)->node_has_sequence_object == true && boost::get<2>(tuple_from_wait)->node_has_sequence_object == true)
{
cout << " ding, ding, we have one ready!!!" << endl;
return true;
}
else
{
cout << "not ready yet" << endl;
}
}
}
return false;
}
Now I need to delete the object that is found in the line "ding, ding", but I don't know how to do it, I know the iterators are used well I actually have to delete this tuple from the deque_wait and move it to the deque_run, but I don't really understand those yet, so can you help me, thanks.
deque_wait.erase(deque_wait.begin() + i);
// ^^^^^^^^^^^^^^^^^^^^^^
// that's an iterator
deque supports random access iterators, which are very much like pointers (in fact, pointers are a type of random access iterator), so you can just get the begin iterator and add an integer to it to get the offset, just like you could do with a pointer.

boost thread lock error

I have this code which is giving the error:
error this boost::lock_error
error this boost::lock_error
error this boost::lock_error
error this boost::lock_error
error this boost::lock_error
Since I don't know where is the error I'll try to copy the code:
Main
boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple = dups.back();
ppa::Node *n = boost::get<0>(tuple);
cout << "creating other threads" << endl;
for ( int i = 0; i < 5; ++i )
{
cout << "making thread " << i << endl;
g.create_thread( boost::bind( threaded_function, boost::ref(mf),
boost::ref(n) ));
}
Threads
void threaded_function(Model_factory &mf, ppa::Node *root)
{
try
{
while(true)
{
boost::mutex::scoped_lock lock(result_mutex);
if(wait.empty())
{
lock.unlock();
break;
}
else
{
lock.lock();
if(!running_jobs.empty())
{
cout << "vector wait size = " << wait.size() << "\n";
cout << "running size = " << running_jobs.size() << "\n";
cout << "done size = " << done.size() << "\n";
boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple;
tuple = running_jobs.back();
running_jobs.pop_back();
...
}
...
}
...
}
}
catch (boost::lock_error& le)
{
cout << "error this " << le.what() << endl;
}
}
The code is used in a alignment program I'm trying to do parallel, it aligns the tuples one by one in different threads, until the waiting list (vector wait) is empty. Thanks.
I have done something I put a lock.unlock() before every if and else and its working now, but why??
You are locking the mutex twice.
boost::mutex::scoped_lock lock(result_mutex);
locks the mutex for you. It will also unlock it when it goes out of scope, so you don't need to unlock it by yourself.
So the following lines are unnecessary:
lock.lock();
lock.unlock();