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:
parent
f041e974c6
commit
daace8527a
2 changed files with 66 additions and 56 deletions
51
research/crash_gdb_jessie-2015-08.sh
Executable file
51
research/crash_gdb_jessie-2015-08.sh
Executable 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
|
||||
|
|
@ -31,81 +31,40 @@
|
|||
|
||||
|
||||
/** @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 =", ")
|
||||
{
|
||||
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());
|
||||
}
|
||||
activate (ELM& something)
|
||||
{
|
||||
std::function<string(ELM const&)> lambda = [] (ELM const& val)
|
||||
{
|
||||
return string(val);
|
||||
};
|
||||
return lambda(something);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue