I am receiving a segmentation fault whenever I attempt to push a templated object into a vector. I have ran gdb, and am still unable to understand why I get the segmentation fault error.
Program received signal SIGSEGV, Segmentation fault. 0x0000003f5869d4f3 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib64/libstdc++.so.6
This is where I am inserting the object into the vector:
void ReadyDelivery::LoadTruck(){
string name = "";
int capacity = 0;
ifstream inputStream;
inputStream.open(m_truckFile.c_str());
while(inputStream >> name >> capacity ){
Truck<Item, MAX_CAPACITY> t(name,capacity);
cout<<name<<" "<<capacity<<endl;
m_truck.push_back(t);
}
cout<<"Trucks loaded: "<<m_truck.size()<<endl;
inputStream.close();
If I comment out where I push_back the object into the vector, there is no segmentation fault.
I also have a function that returns the vector. I am not sure if this could be causing it though...
vector<Truck<Item,MAX_CAPACITY> > & ReadyDelivery:: GetTruck(){
return m_truck;
}
Thanks for the help!
Here is the definition of m_truck, which is a private member variable:
private:
vector< Truck<Item, MAX_CAPACITY> > m_truck; //Vector of templated trucks
Here is where I construct the truck object in my template:
template <class T, int N>
Truck<T,N>::Truck(string inName, int capacity){
m_name = inName;
m_capacity = capacity;
}
If I run gdb and use the where command... I get this:
#0 0x000000346ce9d4f3 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib64/libstdc++.so.6
#1 0x0000000000402bd9 in Item::operator= (this=0x60eb00) at Item.h:11
#2 0x0000000000402c66 in Tqueue<Item, 200>::~Tqueue (this=0x60e478,
__in_chrg=<value optimized out>) at Tqueue.h:96
#3 0x0000000000402b43 in Truck<Item, 200>::~Truck (this=0x60e450,
__in_chrg=<value optimized out>) at Truck.h:114
#4 0x00000000004027d5 in std::_Destroy<Truck<Item, 200> > (__pointer=0x60e450)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_construct.h:90
#5 0x000000000040249c in std::_Destroy_aux<false>::__destroy<Truck<Item, 200>*>
(__first=0x60e450, __last=0x60e488)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_construct.h:100
#6 0x00000000004021d3 in std::_Destroy<Truck<Item, 200>*> (__first=0x60e450,
__last=0x60e488)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_construct.h:123
#7 0x0000000000401cdf in std::_Destroy<Truck<Item, 200>*, Truck<Item, 200> > (
__first=0x60e450, __last=0x60e488)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_construct.h:149
#8 0x000000000040197c in std::vector<Truck<Item, 200>, std::allocator<Truck<Item, 200> > >::~vector (this=0x7fffffffe1b0, __in_chrg=<value optimized out>)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_vector.h:313
#9 0x0000000000401593 in main (argc=1, argv=0x7fffffffe2c8) at driver.cpp:29
I get the following runtime error message
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::wave::cpplexer::lexing_exception> >'
what(): boost::wave::lexing_exception
When I am trying to run the following code:
#include <vector>
#include <algorithm>
#include <boost/wave.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>
std::string strip_comments(std::string const& input)
{
std::string output;
typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type;
typedef token_type::position_type position_type;
position_type pos;
lexer_type it = lexer_type(input.begin(), input.end(), pos,
boost::wave::language_support(
boost::wave::support_cpp|boost::wave::support_option_long_long));
lexer_type end = lexer_type();
for (;it != end; ++it)
{
if (*it != boost::wave::T_CCOMMENT
&& *it != boost::wave::T_CPPCOMMENT)
{
output += std::string(it->get_value().begin(), it->get_value().end());
}
}
return output;
}
int main()
{
std::string text="aaa bbb /*cccc*/ ddd // eee";
std::cout<<strip_comments(text)<<std::endl;
return 0;
}
I use gcc compiler:
g++ -std=c++11 test.cpp -o test -lboost_wave -lboost_system
This code is supposed to remove C++ comments from a text specified by // and /* ... */.
Here is gdb backtrack:
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...done.
[New LWP 10573]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./a.out'.
Program terminated with signal SIGABRT, Aborted.
#0 0x00007ff38fe96cc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 0x00007ff38fe96cc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ff38fe9a0d8 in __GI_abort () at abort.c:89
#2 0x00007ff3904cb78d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ff3904c97f6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ff3904c9841 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ff3904c9a58 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ff390a9e063 in void boost::throw_exception<boost::wave::cpplexer::lexing_exception>(boost::wave::cpplexer::lexing_exception const&)
() from /usr/lib/x86_64-linux-gnu/libboost_wave.so.1.54.0
#7 0x00007ff390aa3a5e in boost::wave::cpplexer::re2clex::lexer<__gnu_cxx::__normal_iterator<char const*, std::string>, boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > >, boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >::report_error(boost::wave::cpplexer::re2clex::Scanner const*, int, char const*, ...) ()
from /usr/lib/x86_64-linux-gnu/libboost_wave.so.1.54.0
#8 0x00007ff390aaf2f0 in boost::wave::cpplexer::re2clex::scan(boost::wave::cpplexer::re2clex::Scanner*) ()
from /usr/lib/x86_64-linux-gnu/libboost_wave.so.1.54.0
#9 0x00007ff390aa4329 in boost::wave::cpplexer::re2clex::lexer<__gnu_cxx::__normal_iterator<char const*, std::string>, boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > >, boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >::get(boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > >&) () from /usr/lib/x86_64-linux-gnu/libboost_wave.so.1.54.0
#10 0x000000000040a3b8 in boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >::get_next<boost::spirit::multi_pass<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, boost::spirit::iterator_policies::default_policy<boost::spirit::iterator_policies::ref_counted, boost::spirit::iterator_policies::no_check, boost::spirit::iterator_policies::split_functor_input, boost::spirit::iterator_policies::split_std_deque> > > (mp=..., result=...)
at /usr/include/boost/wave/cpplexer/cpp_lex_iterator.hpp:80
#11 0x0000000000409efb in boost::spirit::iterator_policies::split_functor_input::unique<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, true>::advance_input<boost::spirit::multi_pass<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util---Type <return> to continue, or q <return> to quit---
::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, boost::spirit::iterator_policies::default_policy<boost::spirit::iterator_policies::ref_counted, boost::spirit::iterator_policies::no_check, boost::spirit::iterator_policies::split_functor_input, boost::spirit::iterator_policies::split_std_deque> > > (mp=...)
at /usr/include/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp:91
#12 0x000000000040969f in boost::spirit::iterator_policies::multi_pass_unique<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, boost::spirit::iterator_policies::ref_counted::unique, boost::spirit::iterator_policies::no_check::unique, boost::spirit::iterator_policies::split_functor_input::unique<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, true>, boost::spirit::iterator_policies::split_std_deque::unique<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, true, true, true>::advance_input<boost::spirit::multi_pass<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, boost::spirit::iterator_policies::default_policy<boost::spirit::iterator_policies::ref_counted, boost::spirit::iterator_policies::no_check, boost::spirit::iterator_policies::split_functor_input, boost::spirit::iterator_policies::split_std_deque> > > (mp=...)
at /usr/include/boost/spirit/home/support/iterators/detail/combine_policies.hpp:441
#13 0x0000000000408d7c in boost::spirit::iterator_policies::split_std_deque::unique<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >::increment<boost::spirit::multi_pass<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, boost::spirit::iterator_policies::default_policy<boost::spirit::iterator_policies::ref_counted, boost::spirit::iterator_policies::no_check, boost::spirit::iterator_policies::split_functor_input, boost::spirit::iterator_policies::split_std_deque> > > (mp=...)
at /usr/include/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp:107
#14 0x0000000000408450 in boost::spirit::multi_pass<std::pair<boost::wave::cpplexer::impl::lex_iterator_functor_shim<boost::wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >, boost::wave::cpplexer::lex_input_interface<boost:---Type <return> to continue, or q <return> to quit---
:wave::cpplexer::lex_token<boost::wave::util::file_position<boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> > > > >*>, boost::spirit::iterator_policies::default_policy<boost::spirit::iterator_policies::ref_counted, boost::spirit::iterator_policies::no_check, boost::spirit::iterator_policies::split_functor_input, boost::spirit::iterator_policies::split_std_deque> >::operator++ (this=0x7fff7d8f66e0)
at /usr/include/boost/spirit/home/support/iterators/multi_pass.hpp:119
#15 0x000000000040680e in strip_comments (input="aaa bbb /*cccc*/ ddd // eee") at test.cpp:23
#16 0x0000000000406927 in main () at test.cpp:37
Update
Thanks to jpo38 for his comment. I initialized the pos by
position_type pos(0);
And the previous runtime error fixed.
Now, I got a different runtime error:
#0 0x0000000000406ff8 in std::char_traits<char>::length (__s=0x0) at /usr/include/c++/4.9/bits/char_traits.h:263
#1 0x0000000000408504 in boost::wave::util::flex_string<char, std::char_traits<char>, std::allocator<char>, boost::wave::util::CowString<boost::wave::util::AllocatorStringStorage<char, std::allocator<char> >, char*> >::flex_string (this=0x7ffee3d536a0, s=0x0, a=...)
at /usr/include/boost/wave/util/flex_string.hpp:1502
#2 0x000000000040693f in strip_comments (input="aaa bbb /*cccc*/ ddd // eee") at test.cpp:16
#3 0x0000000000406bf0 in main () at test.cpp:37
I catched the general exception and tried to show it by:
std::cout << "Error occurred: " << ex.what() << std::endl;
while it was not successful.
boost love exception-programming. Meaning exceptions are used to raise errors and warnings....I hate that, but you need to accept it if you use those fantastic c++ libraries. Exceptions lead to "crash" if you don't be careful and catch them, like that:
std::string strip_comments(std::string const& input)
{
std::string output;
typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type;
typedef token_type::position_type position_type;
boost::wave::util::file_position_type current_position; // for error reporting
try
{
position_type pos;
lexer_type it = lexer_type(input.begin(), input.end(), pos,
boost::wave::language_support(
boost::wave::support_cpp|boost::wave::support_option_long_long));
lexer_type end = lexer_type();
for (;it != end; ++it)
{
current_position = (*it).get_position(); // for error reporting
if (*it != boost::wave::T_CCOMMENT
&& *it != boost::wave::T_CPPCOMMENT)
{
output += std::string(it->get_value().begin(), it->get_value().end());
}
}
}
catch (boost::wave::cpplexer::lexing_exception const& e) {
// some lexing error
std::cerr
<< e.file_name() << "(" << e.line_no() << "): "
<< e.description() << std::endl;
}
catch (std::exception const& e) {
// use last recognized token to retrieve the error position
std::cerr
<< current_position.get_file()
<< "(" << current_position.get_line() << "): "
<< "exception caught: " << e.what()
<< std::endl;
}
catch (...) {
// use last recognized token to retrieve the error position
std::cerr
<< current_position.get_file()
<< "(" << current_position.get_line() << "): "
<< "unexpected exception caught." << std::endl;
}
return output;
}
Then, instead of a "crash", you'll get this nice ans safe message:
(1): warning: generic lexer warning: Unterminated 'C++' style comment
You can see that, by not catching exception, a simple boost warning was transformed in a critical crash at your level ;-)
I'm not familiar with wave library, but adding a \n to the end of your string fixes the issue and then no error is reported anymore (by the way, it was actually just a warning):
Change main function text string to: std::string text="aaa bbb /*cccc*/ ddd // eee\n"; and the program will output aaa bbb ddd.
You can add this \n, but you may also rework the code to try/catch within the loop and then report but ignore warnings.
Note: The fact that boost::wave expects a EOL is probably related to this well known C++ warning (but it is really just a warning): "No newline at end of file" compiler warning
Using different gcc optimizations my program dies due different OS signals and I wonder if the cause is the same or not.
I was getting a core dump due a abort() in a c++ multithread program compiled using O2.
Program terminated with signal 6, Aborted.
#0 0x00007ff2572d28a5 in raise () from /lib64/libc.so.6
I just was not able to find out which was the cause as it seems to be in a local std::vector destructor.. that made no
sense for me.
(gdb) thread 1
[Switching to thread 1 (Thread 0x7ff248d6c700 (LWP 16767))]#0 0x00007ff2572d28a5 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ff2572d28a5 in raise () from /lib64/libc.so.6
#1 0x00007ff2572d4085 in abort () from /lib64/libc.so.6
#2 0x00007ff25730fa37 in __libc_message () from /lib64/libc.so.6
#3 0x00007ff257315366 in malloc_printerr () from /lib64/libc.so.6
#4 0x00007ff257317e93 in _int_free () from /lib64/libc.so.6
#5 0x000000000044dd45 in deallocate (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ext/new_allocator.h:95
#6 _M_deallocate (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:146
#7 ~_Vector_base (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:132
#8 ~vector (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:313
#9 ...
Studing deeper the code I realized that the vector was initialized using another vector comming from other thread and,
here is the point, no mutex was used to do that. In order to simplify
I wrote this code that reproduces that. (please ignore that stopThread is not protected)
void* doWork(void*)
{
while(!stopThread)
{
double min = std::numeric_limits<int>::max();
double max = std::numeric_limits<int>::min();
pthread_mutex_lock(&_mutex);
std::vector<double> localVector = (sharedVector);
sharedVector.clear();
pthread_mutex_unlock(&_mutex);
for(unsigned int index = 0; index < localVector.size(); ++index)
{
std::cout << "Thread 2 " << localVector[index] << ", " << std::endl;
if(min > localVector[index])
{
min = localVector[index];
}
if(max < localVector[index])
{
max = localVector[index];
}
}
}
return NULL;
}
int main()
{
pthread_mutex_init(&_mutex, NULL);
stopThread = false;
pthread_create(&_thread, NULL, doWork, NULL);
for(int i = 0; i < 10000; i++)
{
sharedVector.push_back(i);
std::cout << "Thread 1 " << i << std::endl;
usleep(5000);
}
stopThread = true;
pthread_join(_thread, NULL);
pthread_cancel(_thread);
std::cout << "Finished! " << std::endl;
}
I fixed that but I cannot say that I solved the problem (I know I fixed a problem but not the problem I was looking for) as the core happens once per month more or less.
So I decided to compile using O0 to see If i can see more details in the core file and then I forced the program to crash. Now, what I have is a Segfault where I expected.
Program terminated with signal 11, Segmentation fault.
#0 0x00007f4598f70cd7 in memmove () from /lib64/libc.so.6
(gdb) bt
#0 0x00007f4598f70cd7 in memmove () from /lib64/libc.so.6
#1 0x000000000045fb84 in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<double> (__first=0x7f4580977ba0, __last=0x7f4580977ba8, __result=0x0)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:378
#2 0x0000000000465f01 in std::__copy_move_a<false, double const*, double*> (__first=0x7f4580977ba0, __last=0x7f4580977ba8, __result=0x0) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:397
#3 0x0000000000465e66 in std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:436
#4 0x0000000000465d6d in std::copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:468
#5 0x0000000000465c84 in std::__uninitialized_copy<true>::uninitialized_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001,
__result=0x0) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_uninitialized.h:93
#6 0x0000000000465ad9 in std::uninitialized_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_uninitialized.h:117
#7 0x0000000000465718 in std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*, double> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0)
at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_uninitialized.h:257
#8 0x00000000004650f9 in std::vector<double, std::allocator<double> >::vector (this=0x7f4594d90d70, __x=std::vector of length 1, capacity 4 = {...})
at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:243
#9 ...
I look for some documentation but i found nothing saying that the type of error can change due to the optimization.
However, I run the code above, that reproduces the problem and compiling with O0 a Segmentation fault happens but compiling with O2
it finishs fine.
Thanks for your time
You're locking the mutex while the worker thread access the shared vector; but not when the main thread modifies it. You need to guard all accesses to shared mutable data.
for(int i = 0; i < 10000; i++)
{
pthread_mutex_lock(&_mutex); // Add this
sharedVector.push_back(i);
pthread_mutex_unlock(&_mutex); // Add this
std::cout << "Thread 1 " << i << std::endl;
usleep(5000);
}
You might also consider using a condition variable to notify the worker thread when the vector changes, so that the worker doesn't consume resources busy-waiting.
I have this C++ application running on a Ubuntu Lucid 10.04.3 LTS which is crashed and the reason really escapes me.
The method which exhibits failure is this one:
void
IoLogikCommunicator::processPacket(char const* data, WORD wSize)
{
std::string message(data, wSize);
std::stringstream ss(message);
std::string token;
std::vector<std::string> tokens;
while (std::getline(ss, token, '#')) // <- crash
tokens.push_back(token);
if (tokens[0] == "SENSORS")
processSensorsPacket(tokens);
else if (tokens[0] == "SELECTOR")
processSelectorPacket(tokens);
}
According to the core dump, data content is valid and it is:
p data
$1 = 0xb7520214 "SENSORS#192.168.107.62#DI:00#ON#DI:01#ON#DI:02#ON#DI:03#OFF#DI:04#OFF#DI:05#OFF"
p wSize
$2 = 79
The content of tokens, at crash time, is ["SENSORS"], so the first element was parsed correctly.
What happens then is:
Program terminated with signal 6, Aborted.
#0 0x009de422 in __kernel_vsyscall ()
(gdb) bt
#0 0x009de422 in __kernel_vsyscall ()
#1 0x0766a651 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0x0766da82 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0x076a149d in ?? () from /lib/tls/i686/cmov/libc.so.6
#4 0x076ab591 in ?? () from /lib/tls/i686/cmov/libc.so.6
#5 0x076ae710 in ?? () from /lib/tls/i686/cmov/libc.so.6
#6 0x076aff9c in malloc () from /lib/tls/i686/cmov/libc.so.6
#7 0x0070dc07 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
#8 0x006e7d06 in std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) () from /usr/lib/libstdc++.so.6
#9 0x006e9f70 in std::string::_M_mutate(unsigned int, unsigned int, unsigned int) () from /usr/lib/libstdc++.so.6
#10 0x006c4274 in std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) () from /usr/lib/libstdc++.so.6
given the SIGABRT it seems that an assert() fails inside the malloc invocation, but what could be the reason? Of course, it was impossible for me to reproduce the bug: this method is invoked several times per second and the application crashed after 30 and more days of continuous running.
The very same data, then, is processed by another identical application which is hosted on another machine: that one didn't crash.
Do you have any suggestion/hint/tips/pointer?
im using gzip_decompressor() from the boost library but i'm getting a strange Segmentation fault on free().
stringstream gzMessage;
stringstream rawMessage;
gzMessage << (*iter)->message;
filtering_streambuf<input> gzFilter;
gzFilter.push(gzip_decompressor());
gzFilter.push(gzMessage);
boost::iostreams::copy(gzFilter, rawMessage);
message = rawMessage.str();
cout << "ungzipped: " << message << endl;
The line in question is boost::iostreams::copy(gzFilter, rawMessage);
if i comment this one out everything works fine.
the backtrace:
(gdb) bt
#0 0x00007ffff640fd29 in free () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x0000000000453f8c in boost::detail::sp_counted_impl_p<boost::iostreams::symmetric_filter<boost::iostreams::detail::zlib_decompressor_impl<std::allocator<char> >, std::allocator<char> >::impl>::dispose()
()
#2 0x0000000000427f49 in boost::detail::shared_count::~shared_count() ()
#3 0x00000000004598ae in boost::iostreams::stream_buffer<boost::iostreams::basic_gzip_decompressor<std::allocator<char> >, std::char_traits<char>, std::allocator<char>, boost::iostreams::input>::~stream_buffer() ()
#4 0x0000000000459c39 in boost::iostreams::detail::chain_base<boost::iostreams::chain<boost::iostreams::input, char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, std::allocator<char>, boost::iostreams::input>::chain_impl::~chain_impl() ()
#5 0x0000000000459d12 in boost::detail::sp_counted_impl_p<boost::iostreams::detail::chain_base<boost::iostreams::chain<boost::iostreams::input, char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, std::allocator<char>, boost::iostreams::input>::chain_impl>::dispose() ()
#6 0x0000000000427f49 in boost::detail::shared_count::~shared_count() ()
any hints ?