For this code: #include <map> #include <stdexcept> #include <sstream> class Handler { public: typedef int key_type; typedef std::map<key_type, int> map_type; public: void operator()(const key_type& key) const { find(key); } private: int find( const key_type& key ) const { typename map_type::const_iterator it = data.find(key); if(it == data.end()) { std::ostringstream ost; throw std::runtime_error(ost.str()); } return it->second; } private: map_type data; }; class State { public: void find( int type ) { handlers( type ); } private: Handler handlers; }; int main() { State state; state.find( 0 ); } built with GCC 12.1.1 with optimization: g++ -O1 -g repro.cpp GDB crashes with internal-error: $ gdb -batch -ex "catch throw" -ex r -ex bt a.out Catchpoint 1 (throw) [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Catchpoint 1 (exception thrown), 0x00007ffff7e256d1 in __cxa_throw () from /lib64/libstdc++.so.6 #0 0x00007ffff7e256d1 in __cxa_throw () from /lib64/libstdc++.so.6 #1 0x0000000000401430 in Handler::find (this=this@entry=0x7fffffffde90, ../../gdb/../gdbsupport/array-view.h:217: internal-error: copy: Assertion `dest.size () == src.size ()' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- 0x55895414fe3f ??? 0x558954589ab4 ??? 0x558954589d50 ??? 0x55895472cbf4 ??? 0x5589541f729d ??? 0x55895420f912 ??? 0x558954214239 ??? 0x55895421434a ??? 0x55895421446a ??? 0x5589544b2e88 ??? 0x5589544b36d0 ??? 0x5589544b80cc ??? 0x5589544b9277 ??? 0x558954187074 ??? 0x5589545205b7 ??? 0x55895433c5b1 ??? 0x55895433c681 ??? 0x55895433e613 ??? 0x55895433f13e ??? 0x55895407de6d ??? 0x7f1fbff9754f ??? 0x7f1fbff97608 ??? 0x558954086744 ??? 0xffffffffffffffff ??? --------------------- This is a bug, please report it. For instructions, see: <https://www.gnu.org/software/gdb/bugs/>. Aborted (core dumped)
Also reproduced in master $ ~/build-gdb/gdb/gdb -batch -ex "catch throw" -ex r -ex bt a.out Catchpoint 1 (throw) warning: Cannot parse .gnu_debugdata section; LZMA support was disabled at compile time warning: Cannot parse .gnu_debugdata section; LZMA support was disabled at compile time warning: Cannot parse .gnu_debugdata section; LZMA support was disabled at compile time [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Catchpoint 1 (exception thrown), 0x00007ffff7e256d1 in __cxa_throw () from /lib64/libstdc++.so.6 #0 0x00007ffff7e256d1 in __cxa_throw () from /lib64/libstdc++.so.6 #1 0x0000000000401430 in Handler::find (this=this@entry=0x7fffffffde90, ../../binutils-gdb/gdb/../gdbsupport/array-view.h:217: internal-error: copy: Assertion `dest.size () == src.size ()' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- 0x4b9b62 gdb_internal_backtrace_1 ../../binutils-gdb/gdb/bt-utils.c:122 0x4b9b62 _Z22gdb_internal_backtracev ../../binutils-gdb/gdb/bt-utils.c:168 0x7db474 internal_vproblem ../../binutils-gdb/gdb/utils.c:396 0x7db6b8 _Z15internal_verrorPKciS0_P13__va_list_tag ../../binutils-gdb/gdb/utils.c:476 0x8ef221 _Z14internal_errorPKciS0_z ../../binutils-gdb/gdbsupport/errors.cc:55 0x54d2e1 _ZN3gdb4copyIKhhEEvNS_10array_viewIT_EENS2_IT0_EE ../../binutils-gdb/gdb/../gdbsupport/array-view.h:217 0x54d2e1 _ZN3gdb4copyIKhhEEvNS_10array_viewIT_EENS2_IT0_EE ../../binutils-gdb/gdb/../gdbsupport/array-view.h:215 0x54d2e1 _ZN18dwarf_expr_context12fetch_resultEP4typeS1_lb ../../binutils-gdb/gdb/dwarf2/expr.c:1039 0x56398c dwarf2_evaluate_loc_desc_full ../../binutils-gdb/gdb/dwarf2/loc.c:1519 0x56603e _Z24dwarf2_evaluate_loc_descP4typeP10frame_infoPKhmP18dwarf2_per_cu_dataP18dwarf2_per_objfileb ../../binutils-gdb/gdb/dwarf2/loc.c:1563 0x56603e dwarf_entry_parameter_to_value ../../binutils-gdb/gdb/dwarf2/loc.c:1269 0x56603e value_of_dwarf_reg_entry ../../binutils-gdb/gdb/dwarf2/loc.c:1366 0x56612c value_of_dwarf_block_entry ../../binutils-gdb/gdb/dwarf2/loc.c:1399 0x566217 loclist_read_variable_at_entry ../../binutils-gdb/gdb/dwarf2/loc.c:3920 0x736648 _Z14read_frame_argRK19frame_print_optionsP6symbolP10frame_infoP9frame_argS7_ ../../binutils-gdb/gdb/stack.c:560 0x736dee print_frame_args ../../binutils-gdb/gdb/stack.c:888 0x738611 print_frame ../../binutils-gdb/gdb/stack.c:1391 0x738611 _Z16print_frame_infoRK19frame_print_optionsP10frame_infoi10print_whatii ../../binutils-gdb/gdb/stack.c:1117 0x739dcf backtrace_command_1 ../../binutils-gdb/gdb/stack.c:2070 0x739dcf backtrace_command ../../binutils-gdb/gdb/stack.c:2189 0x4e9514 _Z8cmd_funcP16cmd_list_elementPKci ../../binutils-gdb/gdb/cli/cli-decode.c:2516 0x795b7a _Z15execute_commandPKci ../../binutils-gdb/gdb/top.c:699 0x667de1 catch_command_errors ../../binutils-gdb/gdb/main.c:513 0x667eaf execute_cmdargs ../../binutils-gdb/gdb/main.c:608 0x669c4c captured_main_1 ../../binutils-gdb/gdb/main.c:1298 0x66a73a captured_main ../../binutils-gdb/gdb/main.c:1319 0x66a73a _Z8gdb_mainP18captured_main_args ../../binutils-gdb/gdb/main.c:1344 0x428bf4 main ../../binutils-gdb/gdb/gdb.c:32 --------------------- This is a bug, please report it. For instructions, see: <https://www.gnu.org/software/gdb/bugs/>. Aborted (core dumped)
Found the first bad commit with git bisect # first bad commit: [4bce7cdaf481901edbc5ee47d953ea7e8efb56ca] gdbsupport: add array_view copy function
Thanks for the reproducer, I am able to reproduce. And thanks for the bisection. The patch you found added some additional checks, and it looks like it caught a pre-existing problem. Here: https://gitlab.com/gnutools/binutils-gdb/-/blob/6577f365ebdee7dda71cb996efa29d3714cbccd0/gdb/dwarf2/expr.c#L1027 We try to get the length of subobj_type, but it is a typedef whose actual size hasn't been computed yet: (top-gdb) p subobj_type.main_type.name $1 = 0x6210001ef820 "Handler::key_type" (top-gdb) p subobj_type.main_type.code $2 = TYPE_CODE_TYPEDEF (top-gdb) p subobj_type.length $3 = 0 If I add a check_typedef at the beginning of fetch_result, it looks like it works: From 13d2d8b935f22ac2345c76a69ba009e583f9dc50 Mon Sep 17 00:00:00 2001 From: Simon Marchi <simon.marchi@polymtl.ca> Date: Sat, 23 Jul 2022 21:41:55 -0400 Subject: [PATCH] patch Change-Id: I182733ad08e34df40d8bcc47af72c482fabf4900 --- gdb/dwarf2/expr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 592dbe19d562..d2b7a131de33 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -930,6 +930,11 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type, if (subobj_type == nullptr) subobj_type = type; + /* Ensure that, if TYPE or SUBOBJ_TYPE are typedefs, their length is filled + in instead of being zero. */ + check_typedef (type); + check_typedef (subobj_type); + if (this->m_pieces.size () > 0) { ULONGEST bit_size = 0; base-commit: 4bce7cdaf481901edbc5ee47d953ea7e8efb56ca -- 2.37.1 $./gdb -nx --data-directory=data-directory -q -batch -ex "catch throw" -ex r -ex bt a.out Catchpoint 1 (throw) This GDB supports auto-downloading debuginfo from the following URLs: https://debuginfod.archlinux.org Enable debuginfod for this session? (y or [n]) [answered N; input not from terminal] Debuginfod has been disabled. To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit. [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". Catchpoint 1 (exception thrown), 0x00007ffff7ca5e91 in __cxxabiv1::__cxa_throw (obj=0x55555556af30, tinfo=0x555555557d20 <typeinfo for std::runtime_error@GLIBCXX_3.4>, dest=0x7ffff7cbd370 <std::runtime_error::~runtime_error()>) at /usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_throw.cc:81 81 /usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory. #0 0x00007ffff7ca5e91 in __cxxabiv1::__cxa_throw (obj=0x55555556af30, tinfo=0x555555557d20 <typeinfo for std::runtime_error@GLIBCXX_3.4>, dest=0x7ffff7cbd370 <std::runtime_error::~runtime_error()>) at /usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_throw.cc:81 #1 0x00005555555554a9 in Handler::find (this=this@entry=0x7fffffffdb20, key=key@entry=@0x7fffffffdb1c: 0) at /usr/include/c++/12.1.0/bits/new_allocator.h:90 #2 0x000055555555526e in Handler::operator() (key=@0x7fffffffdb1c: 0, this=0x7fffffffdb20) at repro.cpp:14 #3 State::find (type=<optimized out>, this=0x7fffffffdb20) at repro.cpp:39 #4 main () at repro.cpp:49
Sent patch here: https://sourceware.org/pipermail/gdb-patches/2022-July/191035.html I don't have a test though.
New version with a test: https://sourceware.org/pipermail/gdb-patches/2022-July/191117.html
The master branch has been updated by Simon Marchi <simark@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bde195b84a862f31ac111c0881ad13b89ee89492 commit bde195b84a862f31ac111c0881ad13b89ee89492 Author: Simon Marchi <simon.marchi@polymtl.ca> Date: Wed Jul 27 21:34:22 2022 -0400 gdb: call check_typedef at beginning of dwarf_expr_context::fetch_result Bug 29374 shows this crash: $ ./gdb -nx --data-directory=data-directory -q -batch -ex "catch throw" -ex r -ex bt a.out ... /home/simark/src/binutils-gdb/gdb/../gdbsupport/array-view.h:217: internal-error: copy: Assertion `dest.size () == src.size ()' failed. The backtrace is: #0 internal_error (file=0x5555606504c0 "/home/simark/src/binutils-gdb/gdb/../gdbsupport/array-view.h", line=217, fmt=0x55556064b700 "%s: Assertion `%s' failed.") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:51 #1 0x000055555d41c0bb in gdb::copy<unsigned char const, unsigned char> (src=..., dest=...) at /home/simark/src/binutils-gdb/gdb/../gdbsupport/array-view.h:217 #2 0x000055555deef28c in dwarf_expr_context::fetch_result (this=0x7fffffffb830, type=0x621007a86830, subobj_type=0x621007a86830, subobj_offset=0, as_lval=false) at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:1040 #3 0x000055555def0015 in dwarf_expr_context::evaluate (this=0x7fffffffb830, addr=0x62f00004313e "0", len=1, as_lval=false, per_cu=0x60b000069550, frame=0x621007c9e910, addr_info=0x0, type=0x621007a86830, subobj_type=0x621007a86830, subobj_offset=0) at /home/simark/src/binutils-gdb/gdb/dwarf2/expr.c:1091 #4 0x000055555e084327 in dwarf2_evaluate_loc_desc_full (type=0x621007a86830, frame=0x621007c9e910, data=0x62f00004313e "0", size=1, per_cu=0x60b000069550, per_objfile=0x613000006080, subobj_type=0x621007a86830, subobj_byte_offset=0, as_lval=false) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1485 #5 0x000055555e0849e2 in dwarf2_evaluate_loc_desc (type=0x621007a86830, frame=0x621007c9e910, data=0x62f00004313e "0", size=1, per_cu=0x60b000069550, per_objfile=0x613000006080, as_lval=false) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1529 #6 0x000055555e0828c6 in dwarf_entry_parameter_to_value (parameter=0x621007a96e58, deref_size=0x0, type=0x621007a86830, caller_frame=0x621007c9e910, per_cu=0x60b000069550, per_objfile=0x613000006080) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1235 #7 0x000055555e082f55 in value_of_dwarf_reg_entry (type=0x621007a86890, frame=0x621007acc510, kind=CALL_SITE_PARAMETER_DWARF_REG, kind_u=...) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1332 #8 0x000055555e083449 in value_of_dwarf_block_entry (type=0x621007a86890, frame=0x621007acc510, block=0x61e000033568 "T\004\205\001\240\004\004\243\001T\237\004\240\004\261\004\001T\004\261\004\304\005\004\243\001T\237\004\304\005\310\005\001T\004\310\005\311\005\004\243\001T\237", block_len=1) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:1365 #9 0x000055555e094d40 in loclist_read_variable_at_entry (symbol=0x621007a99bd0, frame=0x621007acc510) at /home/simark/src/binutils-gdb/gdb/dwarf2/loc.c:3889 #10 0x000055555f5192e0 in read_frame_arg (fp_opts=..., sym=0x621007a99bd0, frame=0x621007acc510, argp=0x7fffffffbf20, entryargp=0x7fffffffbf60) at /home/simark/src/binutils-gdb/gdb/stack.c:559 #11 0x000055555f51c352 in print_frame_args (fp_opts=..., func=0x621007a99ad0, frame=0x621007acc510, num=-1, stream=0x6030000bad90) at /home/simark/src/binutils-gdb/gdb/stack.c:887 #12 0x000055555f521919 in print_frame (fp_opts=..., frame=0x621007acc510, print_level=1, print_what=LOCATION, print_args=1, sal=...) at /home/simark/src/binutils-gdb/gdb/stack.c:1390 #13 0x000055555f51f22e in print_frame_info (fp_opts=..., frame=0x621007acc510, print_level=1, print_what=LOCATION, print_args=1, set_current_sal=0) at /home/simark/src/binutils-gdb/gdb/stack.c:1116 #14 0x000055555f526c6d in backtrace_command_1 (fp_opts=..., bt_opts=..., count_exp=0x0, from_tty=0) at /home/simark/src/binutils-gdb/gdb/stack.c:2079 #15 0x000055555f527ae5 in backtrace_command (arg=0x0, from_tty=0) at /home/simark/src/binutils-gdb/gdb/stack.c:2198 The problem is that the type that gets passed down to dwarf_expr_context::fetch_result (the type of a variable of which we're trying to read the entry value) is a typedef whose size has never been computed yet (check_typedef has never been called on it). As we get in the DWARF_VALUE_STACK case (line 1028 of dwarf2/expr.c), the `len` variable is therefore set to 0, instead of the actual type length. We then call allocate_value on subobj_type, which does call check_typedef, so the length of the typedef gets filled in at that point. We end up passing to the copy function a source array view of length 0 and a target array view of length 4, and the assertion fails. Fix this by calling check_typedef on both type and subobj_type at the beginning of fetch_result. I tried writing a test for this using the DWARF assembler, but I haven't succeeded. It's possible that we need to get into this specific code path (value_of_dwarf_reg_entry and all) to manage to get to dwarf_expr_context::fetch_result with a typedef type that has never been resolved. In all my attempts, the typedef would always be resolved already, so the bug wouldn't show up. As a fallback, I made a gdb.dwarf2 test with compiler-generated .S files. I don't particularly like those, but I think it's better than no test. The .cpp source code is the smallest reproducer I am able to make from the reproducer given in the bug (thanks to Pedro for suggestions on how to minimize it further than I had). Since I tested on both amd64 and aarch64, I added versions of the test for these two architectures. Change-Id: I182733ad08e34df40d8bcc47af72c482fabf4900 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29374
Fixed.