From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id A705039C0C34 for ; Mon, 28 Jun 2021 17:44:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A705039C0C34 X-ASG-Debug-ID: 1624902270-0c856e67e21780c40001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id WGrUiQI9sAdmZXDB (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 28 Jun 2021 13:44:31 -0400 (EDT) X-Barracuda-Envelope-From: simon.marchi@polymtl.ca X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from simark.localdomain (192-222-157-6.qc.cable.ebox.net [192.222.157.6]) by smtp.ebox.ca (Postfix) with ESMTP id E481B441DAF; Mon, 28 Jun 2021 13:44:30 -0400 (EDT) From: Simon Marchi X-Barracuda-RBL-IP: 192.222.157.6 X-Barracuda-Effective-Source-IP: 192-222-157-6.qc.cable.ebox.net[192.222.157.6] X-Barracuda-Apparent-Source-IP: 192.222.157.6 To: gdb-patches@sourceware.org Subject: [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed Date: Mon, 28 Jun 2021 13:44:26 -0400 X-ASG-Orig-Subj: [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed Message-Id: <20210628174429.275911-3-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210628174429.275911-1-simon.marchi@polymtl.ca> References: <20210628174429.275911-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1624902271 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 8944 X-Barracuda-Spam-Score: 1.00 X-Barracuda-Spam-Status: No, SCORE=1.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests=BSF_RULE7568M, WEIRD_PORT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.90967 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.50 BSF_RULE7568M Custom Rule 7568M X-Spam-Status: No, score=-17.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_QUARANTINE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Jun 2021 17:44:34 -0000 This gives an internal error: $ ./gdb -q -nx --data-directory=data-directory -q testsuite/outputs/gdb.python/py-unwind/py-unwind -x /home/simark/src/binutils-gdb/gdb/testsuite/gdb.python/py-unwind.py -ex "set debug frame 1" -ex r ... /home/simark/src/binutils-gdb/gdb/frame.c:623: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->this_id.p != frame_id_status::COMPUTING' failed. The backtrace is: #9 0x000055d0b48e294a in internal_error (file=0x55d0b4c71380 "/home/simark/src/binutils-gdb/gdb/frame.c", line=623, fmt=0x55d0b4c712a0 "%s: Assertion `%s' failed.") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:55 #10 0x000055d0b28aade3 in get_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:623 #11 0x000055d0b28b5350 in get_prev_frame_id_by_id (id=) at /home/simark/src/binutils-gdb/gdb/frame.c:2601 #12 0x000055d0b375a1ab in value_fetch_lazy_register (val=0x6110000b3500) at /home/simark/src/binutils-gdb/gdb/value.c:3955 #13 0x000055d0b375a9e7 in value_fetch_lazy (val=0x6110000b3500) at /home/simark/src/binutils-gdb/gdb/value.c:4024 #14 0x000055d0b28a0548 in value_of_register (regnum=6, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/findvar.c:274 #15 0x000055d0b301b05a in pending_framepy_read_register (self=0x7f79056bb7f0, args=0x7f790581aa90) at /home/simark/src/binutils-gdb/gdb/python/py-unwind.c:398 #27 0x000055d0b301c6b4 in pyuw_sniffer (self=0x62100018e250, this_frame=0x6210001ff5e0, cache_ptr=0x6210001ff5f8) at /home/simark/src/binutils-gdb/gdb/python/py-unwind.c:568 #28 0x000055d0b28a6587 in frame_unwind_try_unwinder (this_frame=0x6210001ff5e0, this_cache=0x6210001ff5f8, unwinder=0x62100018e250) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:130 #29 0x000055d0b28a67b5 in frame_unwind_find_by_frame (this_frame=0x6210001ff5e0, this_cache=0x6210001ff5f8) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:193 #30 0x000055d0b28aa80f in compute_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:585 #31 0x000055d0b28aaeae in get_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:635 #32 0x000055d0b28b5350 in get_prev_frame_id_by_id (id=) at /home/simark/src/binutils-gdb/gdb/frame.c:2601 #33 0x000055d0b375a1ab in value_fetch_lazy_register (val=0x6110000b3280) at /home/simark/src/binutils-gdb/gdb/value.c:3955 #34 0x000055d0b375a9e7 in value_fetch_lazy (val=0x6110000b3280) at /home/simark/src/binutils-gdb/gdb/value.c:4024 #35 0x000055d0b28a0548 in value_of_register (regnum=1, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/findvar.c:274 #36 0x000055d0b2826b1c in eval_op_register (expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL, name=0x60400003e2e8 "rbx") at /home/simark/src/binutils-gdb/gdb/eval.c:1074 #37 0x000055d0b218139f in expr::register_operation::evaluate (this=0x60400003e2d0, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/expop.h:830 #38 0x000055d0b282f5d5 in expr::operation::evaluate_for_cast (this=0x60400003e2d0, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/eval.c:2506 #39 0x000055d0b2181c64 in expr::unop_cast_operation::evaluate (this=0x6030000d6870, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/expop.h:1975 #40 0x000055d0b2820b04 in expression::evaluate (this=0x6030000d6840, expect_type=0x6210001949f0, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/eval.c:101 #41 0x000055d0b2820c46 in evaluate_expression (exp=0x6030000d6840, expect_type=0x6210001949f0) at /home/simark/src/binutils-gdb/gdb/eval.c:115 #42 0x000055d0b337b0fd in stap_probe::evaluate_argument (this=0x60f0000053b0, n=1, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/stap-probe.c:1435 #43 0x000055d0b32d86e8 in svr4_handle_solib_event () at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:1932 #44 0x000055d0b32f1f39 in handle_solib_event () at /home/simark/src/binutils-gdb/gdb/solib.c:1258 #45 0x000055d0b21e6c62 in bpstat_stop_status (aspace=0x6030000554e0, bp_addr=0x7ffff7fd18d8, thread=0x61700003db80, ws=0x7ffcff02c708, stop_chain=0x0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470 #46 0x000055d0b2aa44c2 in handle_signal_stop (ecs=0x7ffcff02c6e0) at /home/simark/src/binutils-gdb/gdb/infrun.c:6254 #47 0x000055d0b2aa0962 in handle_inferior_event (ecs=0x7ffcff02c6e0) at /home/simark/src/binutils-gdb/gdb/infrun.c:5740 #48 0x000055d0b2a94a0f in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4111 When the get_frame_id call is done at frame 31, on frame #0, the id is not computed yet, and therefore compute_frame_id is called. compute_frame_id looks for an unwinder, which goes through the Python unwinders. When value_fetch_lazy_register is called at frame 12, get_frame_id is called again for frame #0. But we are in the process of computing that frame id, so it can't work. The assert in get_frame_id works as intended. The second call to get_frame_id happens in VALUE_FRAME_ID (val) at value.c:3955. If we dig down this, we see that: 1. VALUE_NEXT_FRAME_ID is called first, returning the next frame's id, stored in struct value (it happens to be the sentinel's frame id, in this case) 2. it is passed to get_prev_frame_id_by_id 3. frame_find_by_id is called on that, that returns the frame_info for the sentinel frame 4. get_prev_frame is called on that, that returns a frame_info for our frame #0 5. get_frame_id is called on that, this is where the gdb_assert fails. 6. had the previous step worked, value_fetch_lazy_register would have called frame_find_by_id on it, to get the frame_info for frame #0 In the end, all value_fetch_lazy_register wants is a frame_info for the value's frame. In step 4, we have that. In step 5, we fetch the frame's id only to go back to a frame_info in step 6. That seems unnecessary, and causes the internal error. Change value_fetch_lazy_register to do the more straightforward thing: - fetch the value's next frame id - fetch the frame info from that - fetch the prev frame from that (the value's frame) With this change, the command shown above no longer asserts and the produced message makes sense: { value_fetch_lazy (frame=0,regnum=1(rbx),...) -> register=1 bytes=[c0e0fff7ff7f0000] } gdb/ChangeLog: * value.c (value_fetch_lazy_register): Don't use VALUE_FRAME_ID to fetch value's frame for debug message. Change-Id: I294f06f8b32206d442da5355f1b897159414e5b6 --- gdb/value.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/gdb/value.c b/gdb/value.c index 9df035a50b3b..6c969a911376 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3883,8 +3883,6 @@ value_fetch_lazy_memory (struct value *val) static void value_fetch_lazy_register (struct value *val) { - struct frame_info *next_frame; - int regnum; struct type *type = check_typedef (value_type (val)); struct value *new_val = val, *mark = value_mark (); @@ -3896,8 +3894,8 @@ value_fetch_lazy_register (struct value *val) { struct frame_id next_frame_id = VALUE_NEXT_FRAME_ID (new_val); - next_frame = frame_find_by_id (next_frame_id); - regnum = VALUE_REGNUM (new_val); + frame_info *next_frame = frame_find_by_id (next_frame_id); + int regnum = VALUE_REGNUM (new_val); gdb_assert (next_frame != NULL); @@ -3948,18 +3946,17 @@ value_fetch_lazy_register (struct value *val) if (frame_debug) { - struct gdbarch *gdbarch; - struct frame_info *frame; - /* VALUE_FRAME_ID is used here, instead of VALUE_NEXT_FRAME_ID, - so that the frame level will be shown correctly. */ - frame = frame_find_by_id (VALUE_FRAME_ID (val)); - regnum = VALUE_REGNUM (val); - gdbarch = get_frame_arch (frame); + frame_id next_frame_id = VALUE_NEXT_FRAME_ID (val); + frame_info *next_frame = frame_find_by_id (next_frame_id); + frame_info *value_frame = get_prev_frame (next_frame); + + int regnum = VALUE_REGNUM (val); + gdbarch *gdbarch = get_frame_arch (value_frame); fprintf_unfiltered (gdb_stdlog, "{ value_fetch_lazy " "(frame=%d,regnum=%d(%s),...) ", - frame_relative_level (frame), regnum, + frame_relative_level (value_frame), regnum, user_reg_map_regnum_to_name (gdbarch, regnum)); fprintf_unfiltered (gdb_stdlog, "->"); -- 2.32.0