Summary: | gdb crashes when stepping into for loop where iterators are created and compared | ||
---|---|---|---|
Product: | gdb | Reporter: | Bob Steagall <bob.steagall.cpp> |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | normal | CC: | bob.steagall.cpp, keiths, tromey |
Priority: | P2 | ||
Version: | 8.2 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: | ||
Attachments: |
source file to demonstrate problem
Stack trace from corefile created by gdb segv another stack trace, from gdb built '-g -O0' |
I tried this on my Fedora 28 system, using git master gdb and: pokyo. g++ --version g++ (GCC) 8.2.1 20181011 (Red Hat 8.2.1-4) ... and I could not reproduce. However, that doesn't necessarily mean much since there are many possible variables. Could you get a stack trace from gdb? Maybe that would be helpful. Or could you try git master gdb? Perhaps the bug has already been fixed. Created attachment 11432 [details]
Stack trace from corefile created by gdb segv
Per request by Tom Romey, I have attached a stack trace ("bt full") from the core file dropped by gdb when it SEGVs.
Created attachment 11433 [details]
another stack trace, from gdb built '-g -O0'
I have rebuilt gdb from scratch with the following commands:
$ CFLAGS='-g -O0' CXXFLAGS='-g -O0' ./configure
$ make -j8
I then used this full-debug-info version of gdb to run the test program, using the same steps described in the ticket. This gdb crashed in exactly the same way.
I then captured a stack from the resulting core file, which is attached here. This may be more useful as variables are (mostly) not optimized out.
In both stack traces, the SEGV occurs at line 416 in the file value.c. The pointer variable 'value' is NULL.
│406 /* Returns true if VALUE is entirely covered by RANGES. If the value │
│407 is lazy, it'll be read now. Note that RANGE is a pointer to │
│408 pointer because reading the value might change *RANGE. */ │
│409 │
│410 static int │
│411 value_entirely_covered_by_range_vector (struct value *value, │
│412 const std::vector<range> &ranges) │
│413 { │
│414 /* We can only tell whether the whole value is optimized out / │
│415 unavailable when we try to read it. */ │
>│416 if (value->lazy) │
│417 value_fetch_lazy (value); │
│418 │
Working up the call stack, it looks like the call to value_static_field() on line 321 of file cp-valprint.c might be to blame, either returning NULL or throwing an exception such that the pointer "v" is never changed from its NULL initialization on line 317. │315 else if (field_is_static (&TYPE_FIELD (type, i))) │ │316 { │ │317 struct value *v = NULL; │ │318 │ │319 TRY │ │320 { │ │321 v = value_static_field (type, i); │ │322 } │ │323 │ │324 CATCH (ex, RETURN_MASK_ERROR) │ │325 { │ │326 fprintf_filtered (stream, │ │327 _("<error reading variable: %s>"), │ │328 ex.message); │ │329 } │ │330 END_CATCH │ │331 │ >│332 cp_print_static_field (TYPE_FIELD_TYPE (type, i), │ │333 v, stream, recurse + 1, │ │334 options); │ │335 } │ The gdb binary, build against the 8.2 source code, and the core file are available for download here: https://drive.google.com/open?id=1IDutIrUnJFYw6O9MxLRaiVxvX-WkRK2- Another 20020 dup. For unofficial workaround, see comment #1 in 20020. *** This bug has been marked as a duplicate of bug 20020 *** |
Created attachment 11431 [details] source file to demonstrate problem Consider the following code: ======================== #include <atomic> #include <vector> struct TS { std::atomic<void*> mPtr; }; int main() { std::vector<TS> test(10); volatile int i = 0; for (auto iter = test.begin(); iter != test.end(); ++iter) { ++i; } return 0; } ======================== GDB 7.11 and 8.2 both crash when repeatedly stepping into the for loop on line 14 when compiled with gcc 8.2 and -std=c++17. To reproduce: $ g++ -std=c++17 -g -O0 test_dbg.cpp -o test_dbg $ gdb test_dbg inside of gdb: (gdb) b 12 (gdb) r (gdb) s (gdb) s (gdb) s (gdb) s (gdb) s (gdb) s { gdb crashes with segv } The following is a transcript from such a session: Reading symbols from test_dbg...done. (gdb) b 12 Breakpoint 1 at 0x400738: file test_dbg.cpp, line 12. (gdb) r Starting program: /space/tmp/test_dbg Breakpoint 1, main () at test_dbg.cpp:12 (gdb) s (gdb) s std::vector<TS, std::allocator<TS> >::begin (this=0x7fffffffd7a0) at /usr/local/gcc/8.2.0/include/c++/8.2.0/bits/stl_vector.h:699 (gdb) s __gnu_cxx::__normal_iterator<TS*, std::vector<TS, std::allocator<TS> > >::__normal_iterator ( this=0x7fffffffd778, __i=@0x7fffffffd7a0: 0x614c20) at /usr/local/gcc/8.2.0/include/c++/8.2.0/bits/stl_iterator.h:781 (gdb) s std::vector<TS, std::allocator<TS> >::end (this=0x7fffffffd7a0) at /usr/local/gcc/8.2.0/include/c++/8.2.0/bits/stl_vector.h:717 (gdb) s __gnu_cxx::__normal_iterator<TS*, std::vector<TS, std::allocator<TS> > >::__normal_iterator ( this=0x7fffffffd778, __i=@0x7fffffffd7a8: 0x614c70) at /usr/local/gcc/8.2.0/include/c++/8.2.0/bits/stl_iterator.h:781 (gdb) s Segmentation fault (core dumped) ============================= Here are the tool specs: $ gdb -v GNU gdb (GDB) 8.2 Copyright (C) 2018 Free Software Foundation, Inc. ... $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/local/gcc/8.2.0/libexec/gcc/x86_64-kewb-linux-gnu/8.2.0/lto-wrapper Target: x86_64-kewb-linux-gnu Configured with: /space/zbuild/gcc-builder/gcc-8.2.0/configure -v --with-pkgversion='KEWB Computing Build' --prefix=/usr/local/gcc/8.2.0 --program-suffix= --enable-tls --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++ --enable-lto --enable-bootstrap --disable-nls --disable-multilib --disable-install-libiberty --disable-werror --with-system-zlib Thread model: posix gcc version 8.2.0 (KEWB Computing Build) $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.5 LTS Release: 16.04 Codename: xenia ============================= NOTES: The problem appears to be related to the combination of std::atomic<T> as an element type AND the compilation flag -std=c++17. If I change the flag to -std=c++14, gdb does not crash, and I can step thru the iterator instantiations and comparisons as expected. Also, if I change the pointer type to void*, the crash does not occur, and stepping works correctly. I'm not sure if this is a GDB problem or a g++ codegen problem, so I'll be filing this report for both products. Thanks, --Bob