After switching from GCC to LLVM for a codebase which relies on Protobuf, I keep getting a segfault during "initialization". No Protobuf r/w is being executed when the exception occurs.
The stack trace looks like this:
__dynamic_cast (#__dynamic_cast:13)
google::protobuf::Message const* google::protobuf::internal::down_cast<google::protobuf::Message const*, google::protobuf::MessageLite const>(google::protobuf::MessageLite const*) (#google::protobuf::Message const* google::protobuf::internal::down_cast<google::protobuf::Message const*, google::protobuf::MessageLite const>(google::protobuf::MessageLite const*):25)
google::protobuf::Message::CheckTypeAndMergeFrom(google::protobuf::MessageLite const&) (#google::protobuf::Message::CheckTypeAndMergeFrom(google::protobuf::MessageLite const&):12)
google::protobuf::MessageLite::ParseFromArray(void const*, int) (#google::protobuf::MessageLite::ParseFromArray(void const*, int):68)
google::protobuf::EncodedDescriptorDatabase::Add(void const*, int) (#google::protobuf::EncodedDescriptorDatabase::Add(void const*, int):23)
google::protobuf::DescriptorPool::InternalAddGeneratedFile(void const*, int) (#google::protobuf::DescriptorPool::InternalAddGeneratedFile(void const*, int):17)
protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptorsImpl() (#protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptorsImpl():9)
__pthread_once_slow (#__pthread_once_slow:58)
___lldb_unnamed_symbol7928 (#___lldb_unnamed_symbol7928:24)
and the method in which it occurs is in protobuf/message.cc:
void Message::MergeFrom(const Message& from) {
auto* class_to = GetClassData();
auto* class_from = from.GetClassData();
auto* merge_to_from = class_to ? class_to->merge_to_from : nullptr;
if (class_to == nullptr || class_to != class_from) {
merge_to_from = [](Message* to, const Message& from) {
ReflectionOps::Merge(from, to);
};
}
merge_to_from(this, from);
}
at from.GetClassData().
I've built Protobuf locally (Ubuntu 20.04) using various configurations with similar results. The most successful configuration being:
./configure CC=clang CXX="clang++ -std=c++11 -stdlib=libstdc++" --disable-shared
I've also seen instructions online suggesting to build Protobuf using libc++, in which case my code fails to link.
Related
I have this simple code:
#include <boost/unordered_set.hpp>
int main (int argc, char* argv[])
{
boost::unordered_set<int> bset;
for (int i=0; i<10000; i++) {
bset.insert(i);
}
return 0;
}
When I create a purify build and run, I am getting the following UMR (uninitialized memory read) error. I could not figure out how to get rid of this.
**** Purify instrumented app_pure (pid 21943) ****
UMR: Uninitialized memory read (10000 times):
This is occurring while in thread 21943:
std::pair>, bool > boost::unordered::detail::table_impl, int, boost::hash, std::equal_to >>::emplace_impl>(int const&, boost::unordered::detail::set, int, boost::hash, std::equal_to > const&) [unique.hpp:414]
std::pair>, bool > boost::unordered::detail::table_impl, int, boost::hash, std::equal_to >>::emplace(boost::unordered::detail::emplace_args1, int, boost::hash, std::equal_to >> const&) [unique.hpp:393]
std::pair, boost::unordered::detail::ptr_node const* >, bool > boost::unordered::unordered_set, std::equal_to, std::allocator >::emplace(int const&) [unordered_set.hpp:277]
boost::unordered::unordered_set, std::equal_to, std::allocator >::insert(int const&) [unordered_set.hpp:380]
main [app.cxx:8]
__libc_start_main [libc.so.6]
_start [crt1.o]
Reading 8 bytes from 0x7fffffffd668 on the stack of thread 21943 (7 bytes at 0x7fffffffd669 uninit).
Address 0x7fffffffd668 is 56 bytes past start of local variable "pos" in function std::pair>, bool > boost::unordered::detail::table_impl, int, boost::hash, std::equal_to >>::emplace_impl>(int const&, boost::unordered::detail::set, int, boost::hash, std::equal_to > const&).
My boost version is 1.54.0
My GCC version is 4.8.3
Purify version is 7.3 (Purify 7.3-mod1 150930 Linux (64-bit))
Can anyone please give any hint on how to solve this?
Thanks
When built with the latest XCode 5.1, iOS SDK 7.1 and LLVM 5.1, using libstdc++ for the C++ standard library, get crash in the std::string append method only on iOS 5.1 device.
Here's code example:
class TestClass
{
public:
TestClass()
{
m_string = "string1";
}
void AppendString()
{
m_string += std::string("string2");
std::string newString2 = m_string + "string3";
}
private:
string m_string;
};
App crashes in AppendString() method on this line:
std::string newString2 = m_string + "string3";
If I remove this line m_string += std::string("string2"); before creating newString2, code works fine.
Here's the stacktrace of crash:
#0 0x34c99fe8 in memcpy$VARIANT$CortexA8 ()
#1 0x3706f95a in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) ()
#2 0x3706fbfa in std::string::reserve(unsigned long) ()
#3 0x3706fdb0 in std::string::append(char const*, unsigned long) ()
#4 0x000c0e5a in std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/c++/4.2.1/bits/basic_string.h:2121
#5 0x000c0e3c in TestClass::AppendString() at /Users/sergei/Documents/2_3/House of Fun/cpp/CasinoSceneManager.cpp:122
Have anybody experinced same crash? It happens only on devices with iOS 5.1 and 5.1.1 and only if app was compiled with release flag, not debug.
Thank you for the help.
One more note.
If I change Optimization level to None [-O0] in Code Generation section in project settings, everything works fine.
Maybe the problem has some connection to code optimization.
Apple released a new GM seed for Xcode 5.1.1. In the release notes they say they fixed a couple crashes:
Fixed a compiled code crash on when targeting iOS 5.1.1. (16485980)!
Fixed a compiled code crash when using ARC and C++. (16368824)
http://adcdownload.apple.com//Developer_Tools/xcode_5.1.1_gm_seed/release_notes_xcode_5.1.1_gm_seed.pdf
I can create .o file with g++ -c test.cpp -std=c++0x, but cant link it, got next errors:
test.cpp:(.text+0xe5): undefined reference to `std::regex_iterator<char const*, char, std::regex_traits<char> >::regex_iterator(char const*, char const*, std::basic_regex<char, std::regex_traits<char> > const&, std::bitset<11u>)'
test.cpp:(.text+0xf1): undefined reference to `std::regex_iterator<char const*, char, std::regex_traits<char> >::regex_iterator()'
Code:
#include <regex>
#include <iostream>
#include <string.h>
typedef std::regex_iterator<const char *> Myiter;
int main()
{
const char *pat = "axayaz";
Myiter::regex_type rx("a");
Myiter next(pat, pat + strlen(pat), rx);
Myiter end;
return (0);
}
The GNU C++ standard library supports <regex>, but not until version 4.9.0. (The headers were present in earlier versions, but were unusable.)
The other compilers don't support it, as far as I can see.
You can use a different library if you use an older GCC.
I am writing an application that uses pion library and notice a crash when I try to send a request. The crash is happening due to segmentation fault. This is in Linux and I am linking with PION_FULL.
Code:
pion::net::HTTPRequest httpRequest("/sm_login/trusted.asp?app-id=test");
int port = 80;
httpRequest.setMethod("GET");
httpRequest.addHeader("Host", "127.0.0.1");
pion::net::TCPConnection connPtr(IO_service);
error = connPtr.connect(boost::asio::ip::address::from_string("127.0.0.1"), port);
if (error || !connPtr.is_open())
{
dprintf(("Unable to establish connection"));
return false;
}
httpRequest.send(connPtr, error);
Dump:
#0 0x0eec4bb4 in void pion::net::HTTPMessage::changeValue<std::tr1::unordered_multimap<std::string, std::string, CaseInsensitiveHash, CaseInsensitiveEqual, std::allocator<std::pair<std::string const, std::string> > >
>(std::tr1::unordered_multimap<std::string, std::string, CaseInsensitiveHash, CaseInsensitiveEqual, std::allocator<std::pair<std::string const, std::string> > >&, std::string const&, std::string const&) () from /sw/lib/libpion-net-2.2.12.so
#1 0x0eec11f0 in pion::net::HTTPMessage::send(pion::net::TCPConnection&, boost::system::error_code&) () from /sw/lib/libpion-net-2.2.12.so
#2 0x0f1e6c24 in CHeapInterface::SendRequest(std::string const&, std::string&, CHeapInterface::EHeapMsgType) () from /sw/lib/libMgmt.so
Thanks,
The problem was due to mismatch in cross compiler version used to build pion libs. The application is not crashing anymore.
Does anyone know if it's kosher to pass a boost::unordered_set as the first parameter to boost::split? Under libboost1.42-dev, this seems to cause problems. Here's a small example program that causes the problem, call it test-split.cc:
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/unordered_set.hpp>
#include <string>
int main(int argc, char **argv) {
boost::unordered_set<std::string> tags_set;
boost::split(tags_set, "a^b^c^",
boost::is_any_of(std::string(1, '^')));
return 0;
}
Then, if I run the following commands:
g++ -o test-split test-split.cc; valgrind ./test-split
I get a bunch of complaints in valgrind like the one that follows (I also sometimes see coredumps without valgrind, though it seems to vary based on timing):
==16843== Invalid read of size 8
==16843== at 0x4ED07D3: std::string::end() const (in /usr/lib/libstdc++.so.6.0.13)
==16843== by 0x401EE2: unsigned long boost::hash_value<char, std::allocator<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /tmp/test-split)
...
==16843== by 0x402248: boost::unordered_set<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> >& boost::algorithm::split<boost::unordered_set<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> >, char const [26], boost::algorithm::detail::is_any_ofF<char> >(boost::unordered_set<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> >&, char const (&) [26], boost::algorithm::detail::is_any_ofF<char>, boost::algorithm::token_compress_mode_type) (in /tmp/test-split)
==16843== by 0x40192A: main (in /tmp/test-split)
==16843== Address 0x5936610 is 0 bytes inside a block of size 32 free'd
==16843== at 0x4C23E0F: operator delete(void*) (vg_replace_malloc.c:387)
==16843== by 0x4ED1EE8: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/libstdc++.so.6.0.13)
==16843== by 0x404A8B: void boost::unordered_detail::hash_unique_table<boost::unordered_detail::set<boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> > >::insert_range_impl<boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, char const*>, boost::algorithm::split_iterator<char const*>, boost::use_default, boost::use_default> >(std::string const&, boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, char const*>, boost::algorithm::split_iterator<char const*>, boost::use_default, boost::use_default>, boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, char const*>, boost::algorithm::split_iterator<char const*>, boost::use_default, boost::use_default>) (in /tmp/test-split)
...
==16843== by 0x402248: boost::unordered_set<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> >& boost::algorithm::split<boost::unordered_set<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> >, char const [26], boost::algorithm::detail::is_any_ofF<char> >(boost::unordered_set<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::string> >&, char const (&) [26], boost::algorithm::detail::is_any_ofF<char>, boost::algorithm::token_compress_mode_type) (in /tmp/test-split)
==16843== by 0x40192A: main (in /tmp/test-split)
This is a Debian Squeeze box; here's my relevant system info:
$ g++ --version
g++ (Debian 4.4.5-2) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ dpkg -l | grep boost
ii libboost-iostreams1.42.0 1.42.0-4 Boost.Iostreams Library
ii libboost1.42-dev 1.42.0-4 Boost C++ Libraries development files
$ uname -a
Linux gcc44-buildvm 2.6.32-5-amd64 #1 SMP Fri Sep 17 21:50:19 UTC 2010 x86_64 GNU/Linux
However, the code seems to work fine if I downgrade libboost1.42-dev to libboost1.40-dev. So is this a bug in boost 1.42, or am I misusing boost::split by passing in a container that can't handle sequences? Thanks!
This was confirmed on the boost-users mailing list to be a bug in the boost::unordered_set implementation. There is a patch available on the mailing list, and a fix will be checked in soon, hopefully in time for boost 1.45.
Boost-users: patch
Boost-users: confirmation
Thanks everyone for looking into this!
I think the answer should be yes.
Reading the headers (split.hpp and iter_find.hpp) split takes a SequenceSequenceT& Result as its first argument, which it passes to iter_split which range-constructs it from two boost::transform_iterators:
SequenceSequenceT Tmp(itBegin, itEnd);
Result.swap(Tmp);
return Result;
So all it needs of this type is that it has a constructor that takes a pair of iterators which dereference to std::string (or, technically, to BOOST_STRING_TYPENAME). And has a .swap() member.. and has a SequenceSequenceT::iterator type whose type is std::string.
proof:
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <string>
#include <iterator>
#include <algorithm>
#include <iostream>
struct X
{
typedef std::iterator<std::forward_iterator_tag,
std::string, ptrdiff_t, std::string*, std::string&>
iterator;
X() {}
template<typename Iter> X(Iter i1, Iter i2)
{
std::cout << "Constructed X: ";
copy(i1, i2, std::ostream_iterator<std::string>(std::cout, " " ));
std::cout << "\n";
}
void swap(X&) {}
};
int main()
{
X x;
boost::split(x, "a^b^c^", boost::is_any_of(std::string(1, '^')));
}
I think that unordered_set<std::string> should satisfy these requirements as well.
Apparently, the answer is no yes.
Using the following code, I get compile-time warnings and a runtime assert (Visual C++ v10) on the unordered_set while the vector works fine (apart from an empty string in the last element, due to the trailing '^').
boost::unordered_set<std::string> tags_set;
vector<string> SplitVec; // #2: Search for tokens
boost::split( SplitVec, "a^b^c^", boost::is_any_of("^") );
boost::split( tags_set, "a^b^c^", boost::is_any_of("^") );
Iterator compatibility between source (string) and the target container is the issue. I would post the warning error, but it's one of those "War and Peace" template warnings.
EDIT:
This looks like a bug in Boost unordered_set? When I use the following, it works as you would expect:
std::unordered_set<std::string> tags_set_std;
boost::split( tags_set_std, string("a^b^c^"), boost::is_any_of(string("^")) );