investigation: Segfault in GDB (IV) (related to #946)

now isolated the problem.
It is triggered by a std::function bound to a lambda
where some argument type is picked up from the
template parameter of the enclosing function.
This commit is contained in:
Fischlurch 2015-08-13 20:59:19 +02:00
parent f041e974c6
commit daace8527a
2 changed files with 66 additions and 56 deletions

View file

@ -0,0 +1,51 @@
#/!bin/sh
#
# crash_gdb -- demostrate a Segfault when invoking the debugger
# observed 8/2015 on Debian/Jessie on X86_64
# <deb@ichthyostega.de>
CODE=`mktemp`
cat << __END__ | g++ -x c++ - -o$CODE -std=gnu++11 && echo "compiled successfully to $CODE"
#include <functional>
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
template<class ELM>
inline string
activate (ELM& something)
{
std::function<string(ELM const&)> lambda = [] (ELM const& val)
{
return string(val);
};
return lambda(something);
}
int
main (int, char**)
{
cout << activate ("Data") << endl;
return 0;
}
__END__
$CODE && echo "executed successfully without debugger"
echo -e "now try to crash the debugger...\n\n"
gdb $CODE -ex run -ex quit
if (($?))
then echo -e "\n\n\n\n *** Debugger crashed"
else echo -e "\n\n\n\n +++ Debugger worked, no crash"
fi

View file

@ -31,81 +31,40 @@
/** @file try.cpp /** @file try.cpp
** Investigation: Segfault when loading into GDB (on Debian/Jessie 64bit) ** Investigation: Segfault when loading into GDB (on Debian/Jessie 64bit).
**
** Problem could be narrowed down to a std::function bound to lambda,
** where some argument type is picked up as template parameter
** **
*/ */
#include "lib/test/test-helper.hpp" #include <functional>
//#include "lib/format-util.hpp"
#include "lib/meta/trait.hpp"
#include "lib/itertools.hpp"
#include "lib/symbol.hpp"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector>
using std::string; using std::string;
using std::vector;
using std::cout; using std::cout;
using std::endl; using std::endl;
namespace { // helper to build range iterator on demand
template<class CON, typename TOGGLE = void>
struct _RangeIter
{
using StlIter = typename CON::const_iterator;
lib::RangeIter<StlIter> iter;
_RangeIter(CON const& collection)
: iter(begin(collection), end(collection))
{ }
};
}
template<class ELM>
template<class CON>
inline string inline string
join (CON&& coll, string const& delim =", ") activate (ELM& something)
{ {
using Coll = typename lib::meta::Strip<CON>::Type; std::function<string(ELM const&)> lambda = [] (ELM const& val)
using Val = typename Coll::value_type; {
return string(val);
std::function<string(Val const&)> toString = [] (Val const& val) { return string(val); }; };
return lambda(something);
_RangeIter<Coll> range(std::forward<Coll>(coll)); }
auto strings = lib::transformIterator(range.iter, toString);
if (!strings) return "";
std::ostringstream buffer;
for (string const& elm : strings)
buffer << elm << delim;
// chop off last delimiter
size_t len = buffer.str().length();
ASSERT (len > delim.length());
return buffer.str().substr(0, len - delim.length());
}
int int
main (int, char**) main (int, char**)
{ {
vector<string> crew; cout << activate("Data") << endl;
crew.push_back("Picard");
crew.push_back("Riker");
crew.push_back("Data");
crew.push_back("Troi");
crew.push_back("Worf");
crew.push_back("Crusher");
crew.push_back("La Forge");
cout << "enterprise = " << join(crew)<<endl;
cout << "\n.gulp.\n"; cout << "\n.gulp.\n";