Ho riscontrato un problema con un arresto anomalo dovuto alla restituzione di un valore di un set di bit quando il set di bit è ampio. È un bug del compilatore o ho fatto qualcosa per errore che ha causato un comportamento indefinito?Errore di segmento su GCC4.6 quando si tenta di spostare un grosso set di bit, si tratta di un bug del compilatore?
Il codice seguente si arresta in modo anomalo su GCC 4.6.3 con il flag impostato -std=c++0x
.
#include <bitset>
// typedef std::bitset<0xffff> uut;
typedef std::bitset<0xffffff> uut;
struct foo {
foo(uut b)
: b_(std::move(b))
{
}
uut b_;
};
uut make_bits(int)
{
uut bits;
// Only works for 0xffff:
return std::move(bits);
// Works for both 0xffff and 0xffffff:
//return bits;
}
int main()
{
foo(make_bits(0));
}
Stranamente se rimuovere il parametro int
è ok, forse questo fa sì che la funzione da inline?
Come @unwind suggerito, ecco l'output eseguito in valgrind ./a.out
:
==24780== Memcheck, a memory error detector
==24780== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==24780== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==24780== Command: ./a.out
==24780==
==24780== Warning: client switching stacks? SP change: 0x7ff000068 --> 0x7fea00058
==24780== to suppress, use: --max-stackframe=6291472 or greater
==24780== Invalid write of size 8
==24780== at 0x4005E5: main (in /home/sam/scratch/a.out)
==24780== Address 0x7fea00058 is on thread 1's stack
==24780==
==24780== Warning: client switching stacks? SP change: 0x7fea00050 --> 0x7fe800040
==24780== to suppress, use: --max-stackframe=2097168 or greater
==24780== Invalid write of size 8
==24780== at 0x40056F: make_bits(int) (in /home/sam/scratch/a.out)
==24780== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24780== Address 0x7fe800048 is on thread 1's stack
==24780==
==24780==
==24780== Process terminating with default action of signal 11 (SIGSEGV)
==24780== Access not within mapped region at address 0x7FE800048
==24780== at 0x40056F: make_bits(int) (in /home/sam/scratch/a.out)
==24780== If you believe this happened as a result of a stack
==24780== overflow in your program's main thread (unlikely but
==24780== possible), you can try to increase the size of the
==24780== main thread stack using the --main-stacksize= flag.
==24780== The main thread stack size used in this run was 8388608.
==24780==
==24780== Process terminating with default action of signal 11 (SIGSEGV)
==24780== Access not within mapped region at address 0x7FE800039
==24780== at 0x4A255A0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==24780== If you believe this happened as a result of a stack
==24780== overflow in your program's main thread (unlikely but
==24780== possible), you can try to increase the size of the
==24780== main thread stack using the --main-stacksize= flag.
==24780== The main thread stack size used in this run was 8388608.
==24780==
==24780== HEAP SUMMARY:
==24780== in use at exit: 0 bytes in 0 blocks
==24780== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==24780==
==24780== All heap blocks were freed -- no leaks are possible
==24780==
==24780== For counts of detected and suppressed errors, rerun with: -v
==24780== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
E con valgrind --max-stacksize=99999999 ./a.out
, come valgrind mi ha spinto a:
==24790== Memcheck, a memory error detector
==24790== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==24790== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==24790== Command: ./a.out
==24790==
==24790== Warning: client switching stacks? SP change: 0x7ff000068 --> 0x7fea00058
==24790== to suppress, use: --max-stackframe=6291472 or greater
==24790== Invalid write of size 8
==24790== at 0x4005E5: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fea00058 is on thread 1's stack
==24790==
==24790== Warning: client switching stacks? SP change: 0x7fea00050 --> 0x7fe800040
==24790== to suppress, use: --max-stackframe=2097168 or greater
==24790== Invalid write of size 8
==24790== at 0x40056F: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800048 is on thread 1's stack
==24790==
==24790== Invalid write of size 4
==24790== at 0x400576: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800044 is on thread 1's stack
==24790==
==24790== Invalid write of size 8
==24790== at 0x400590: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800038 is on thread 1's stack
==24790==
==24790== Invalid write of size 4
==24790== at 0x4C2E0E0: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x400594: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800050 is on thread 1's stack
==24790==
==24790== Invalid write of size 4
==24790== at 0x4C2E0EB: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x400594: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800058 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2E10E: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800038 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4005A7: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800048 is on thread 1's stack
==24790==
==24790== Invalid write of size 8
==24790== at 0x4C2D10D: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x4005C0: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fee00058 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2D11A: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x4005C0: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe9fffc8 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2D108: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x4005C0: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe9fffc0 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4005C1: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4005E9: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fe800048 is on thread 1's stack
==24790==
==24790== Warning: client switching stacks? SP change: 0x7fe800040 --> 0x7fea00050
==24790== to suppress, use: --max-stackframe=2097168 or greater
==24790== further instances of this message will not be shown.
==24790== Invalid read of size 8
==24790== at 0x4005C9: make_bits(int) (in /home/sam/scratch/a.out)
==24790== by 0x4E5376C: (below main) (libc-start.c:226)
==24790== Address 0x7fea00058 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2D000: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x40060A: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fec00060 is on thread 1's stack
==24790==
==24790== Invalid write of size 8
==24790== at 0x4C2D004: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x40060A: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fea00060 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2D00F: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x40060A: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fec00070 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2D108: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x400650: foo::foo(std::bitset<16777215ul>) (in /home/sam/scratch/a.out)
==24790== by 0x400612: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fec00058 is on thread 1's stack
==24790==
==24790== Invalid read of size 8
==24790== at 0x4C2D11A: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x400650: foo::foo(std::bitset<16777215ul>) (in /home/sam/scratch/a.out)
==24790== by 0x400612: main (in /home/sam/scratch/a.out)
==24790== Address 0x7fec00048 is on thread 1's stack
==24790==
==24790== Invalid write of size 8
==24790== at 0x4C2D10D: [email protected]@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24790== by 0x400650: foo::foo(std::bitset<16777215ul>) (in /home/sam/scratch/a.out)
==24790== by 0x400612: main (in /home/sam/scratch/a.out)
==24790== Address 0x7feffffe0 is on thread 1's stack
==24790==
==24790==
==24790== HEAP SUMMARY:
==24790== in use at exit: 0 bytes in 0 blocks
==24790== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==24790==
==24790== All heap blocks were freed -- no leaks are possible
==24790==
==24790== For counts of detected and suppressed errors, rerun with: -v
==24790== ERROR SUMMARY: 2097097 errors from 19 contexts (suppressed: 2 from 2)
Quel bitset è _huge_! Sei consapevole del fatto che contiene più di 2 megabyte di bit? –
Direi che è un overflow dello stack. – Flexo
@Lightness Races in Orbit: sì! :) –