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,64 +31,32 @@
/** @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 "lib/format-util.hpp"
#include "lib/meta/trait.hpp"
#include "lib/itertools.hpp"
#include "lib/symbol.hpp"
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cout;
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 CON>
template<class ELM>
inline string
join (CON&& coll, string const& delim =", ")
activate (ELM& something)
{
using Coll = typename lib::meta::Strip<CON>::Type;
using Val = typename Coll::value_type;
std::function<string(Val const&)> toString = [] (Val const& val) { return string(val); };
_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());
std::function<string(ELM const&)> lambda = [] (ELM const& val)
{
return string(val);
};
return lambda(something);
}
@ -96,16 +64,7 @@ join (CON&& coll, string const& delim =", ")
int
main (int, char**)
{
vector<string> crew;
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 << activate("Data") << endl;
cout << "\n.gulp.\n";