On 18.09.2016 22:40, Eugene V. Lyubimkin wrote:
> Thank you. Turned out it is reproducible in release build (at the least on 
> armel porterbox), but not in debug build.
> 
> I'll look into it.

Ok, something fishy is going on with lambda captures. I believe I found an 
issue in either std::function or GCC
optimizer. Looks like a captured value ("this" in this case) is uninitialized 
or corrupted, but only if previous lambda
captures a certain amount of variables, no matter was it called or not. Ugh. I 
managed to reduce
the code to the following small example:

(sid_armhf-dchroot)jackyf@harris:~/smalltests/small-std-function-arm$ cat hm.cpp
#include <iostream>
#include <functional>

struct C
{
        void doCb()
        {
                size_t dummy_a = 1;

                std::cout << "Outside: " << this << std::endl;
                std::function<void ()> f;
                f = [this, &dummy_a]()
                {};
                f = [this]()
                {
                        std::cout << "Inside: " << this << std::endl;
                };
                f();
        }
};

int main()
{
        C c;
        c.doCb();
}

(sid_armhf-dchroot)jackyf@harris:~/smalltests/small-std-function-arm$ cat 
Makefile
all:
        g++ -O2 -Wall -Wextra hm.cpp -o hm.e
(sid_armhf-dchroot)jackyf@harris:~/smalltests/small-std-function-arm$ ./hm.e
Outside: 0xbeaeb5f4
Inside: 0x2
(sid_armhf-dchroot)jackyf@harris:~/smalltests/small-std-function-arm$ 
~/valgrind/valgrind-3.12.0~svn20160714
/vg-in-place ./hm.e
==9628== Memcheck, a memory error detector
==9628== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9628== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==9628== Command: ./hm.e
==9628==
Outside: 0xbdb6a454
==9628== Use of uninitialised value of size 4
==9628==    at 0x4916BF6: ??? (in 
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22)
==9628==
==9628== Conditional jump or move depends on uninitialised value(s)
==9628==    at 0x4916BFC: ??? (in 
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22)
==9628==
==9628== Conditional jump or move depends on uninitialised value(s)
==9628==    at 0x49179FA: std::ostreambuf_iterator<char, std::char_traits<char> 
> std::num_put<char,
std::ostreambuf_iterator<char, std::char_traits<char> > 
>::_M_insert_int<unsigned long>(std::ostreambuf_iterator<char,
std::char_traits<char> >, std::ios_base&, char, unsigned long) const (in 
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22)
==9628==    by 0x4917AC5: std::num_put<char, std::ostreambuf_iterator<char, 
std::char_traits<char> >
>::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, 
>std::ios_base&, char, void const*) const (in
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22)
==9628==    by 0x491FDA3: std::ostream& std::ostream::_M_insert<void 
const*>(void const*) (in
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22)
==9628==
Inside: 0x2
==9628==
==9628== HEAP SUMMARY:
==9628==     in use at exit: 0 bytes in 0 blocks
==9628==   total heap usage: 2 allocs, 2 frees, 21,248 bytes allocated
==9628==
==9628== All heap blocks were freed -- no leaks are possible
==9628==
==9628== For counts of detected and suppressed errors, rerun with: -v
==9628== Use --track-origins=yes to see where uninitialised values come from
==9628== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Reply via email to