From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id sDtYIPFmgWYXhBUAWB0awg (envelope-from ) for ; Sun, 30 Jun 2024 10:08:49 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=GjdsrdAv; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 74D531E0C3; Sun, 30 Jun 2024 10:08:49 -0400 (EDT) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 3F0981E030 for ; Sun, 30 Jun 2024 10:08:47 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DFEEC3858429 for ; Sun, 30 Jun 2024 14:08:46 +0000 (GMT) Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by sourceware.org (Postfix) with ESMTPS id 68AE23858C33 for ; Sun, 30 Jun 2024 14:08:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 68AE23858C33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 68AE23858C33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1031 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719756505; cv=none; b=fPPsDQm4MryD+EpnJM9OQ2HCIhuoSM1OuyGB2aadD4Hcug+KVzNxQMPuKUZhMJWFyHujcLTS09BIihEwNr3pcP5Wuf06b4ut3tVQPKNaiCcgdPh8BaRUvTXJvXuUzQUYTThvJ83xH3OuXidYg5UnZ/SoxIRwCjgD1jNj6R82lEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719756505; c=relaxed/simple; bh=oNQi+cMnsgXIfboLz86nuHn2bRQEKNR4HZhyZR8LMgY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=GnKsdOdw32NnFOMH6XWf5CD474SzvsQs/b8Tb5tZEgcbQn/Hu1EgfdRW2DSDh5DQ6OuwZveiaT9kgd/9XUp57+M5deod0V1i8KZQcYj8QA0RU2K/wjJdIrWHBLxn2jMRF3liLxEmUhinq7oMJRI9Ro1A4SNlTrVb6qK2XwGxnqY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2c93627e773so900987a91.0 for ; Sun, 30 Jun 2024 07:08:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719756500; x=1720361300; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=tqMYkvnxO5LS3PnPi5kd2d7gQjRpeLj0hPCCda/4krg=; b=GjdsrdAv+qe/NJ7jrSyu77hpEo96lAeECfu6M+yw+g3fs9erYhjGs5ndfTp2cMUkwP JapU7N6gKGkOKG3Yf0cUXb81S2F9v++ZqiHGcRmt1I1nNT+pFAorvtfPoU79S6w/M/n3 34vPGILGFRqEVjOx5jhcj+nHzZ7Z1MfDmVdWjaWYebnaRQPWG6tFwvjjLeb7KU8ryvhR M7mK9Wke9pL8zbX6/4L5HYPqEL6JxcTOc5G6ABcPzUmgy8FJ0fzY1UOcnXOSstP4xO8C wXG92zYqu14RBFNkYoitGVAVBXog/ibhE1aHrx7gjs1mXYtYWMFaaUciKKm9ljmYYou7 295A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719756500; x=1720361300; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=tqMYkvnxO5LS3PnPi5kd2d7gQjRpeLj0hPCCda/4krg=; b=wO1rlYfA1S2MRHrtfToGwPWCanjqMfEYABNWTg7reLOe55iq1N3Bye21GFD5c6TBkJ 6p18PvXRgAY22wj7HbRp0wUx9Iw5MdpKoH6pOkKXuSDY6+4eLnjsr+z3D+AFyAuKMTvo J4NOAXf/kJ1asVtM3CB0Lbp53oKx+uklrJRgllH0sgpAv6RJVP6PfuJ0Wdy8epQ+W+yC xWeQv8IF4wEvN+cwrLRITro79d5DOwlsKgjdkjdyb+1ncZ/v1Lm8Uycw7PCNwURLLSrn JoprH1IrjJba3LayzGmMRt8DSuci6xgnCRC57oqw/WilxbypN3QpEcAIQf04wmCZfWqC 8ndw== X-Gm-Message-State: AOJu0Yz+Mqa9f9CpDgCFWU8t/y15uDIdkv7pTxynBlA/sYfHIXGELQoE ciXqSw/r12xN1fBwrF3DRYgAeE3jy6MlKlwN4M2VbtaxttbGmDPIeVchew== X-Google-Smtp-Source: AGHT+IFrYofLBIKYIv+lYtFSCGlIQJBJ3AnPfCWEkH4aJQm387Y3FfmU2j4/977rvkA8dSfodxo+DQ== X-Received: by 2002:a17:90a:fe13:b0:2c7:af59:dc11 with SMTP id 98e67ed59e1d1-2c93d773057mr1205757a91.48.1719756499989; Sun, 30 Jun 2024 07:08:19 -0700 (PDT) Received: from valdaarhun.. ([223.233.84.154]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac10d1ccesm47674035ad.20.2024.06.30.07.08.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Jun 2024 07:08:19 -0700 (PDT) From: Sahil Siddiq X-Google-Original-From: Sahil Siddiq To: gdb-patches@sourceware.org Cc: Sahil Siddiq Subject: [PATCH] gdb: fix "frame function" issue when call is last instruction Date: Sun, 30 Jun 2024 19:38:08 +0530 Message-ID: <20240630140808.919614-1-sahilcdq@proton.me> X-Mailer: git-send-email 2.45.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Currently, the "frame function" fails when the last instruction is a call. In such a case, the $rip register points to an address that lies outside the frame. Using "get_frame_address_in_block" instead of "get_frame_pc" resolves this issue. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30929 --- Hi, This is my first time contributing to gdb. I have tried to adhere to the styling convention. Please let me know if I have missed something. Instead of extending the existing frame-selection.exp test, I thought I would create a new test since the C file is new and it seemed like the implementation of the test isn't similar enough to be kept in the existing exp file. Please let me know if this is undesirable. Thanks, Sahil gdb/stack.c | 4 +- .../frame-selection-last-instr-call.c | 28 ++++ .../frame-selection-last-instr-call.exp | 139 ++++++++++++++++++ 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 gdb/testsuite/gdb.base/frame-selection-last-instr-call.c create mode 100644 gdb/testsuite/gdb.base/frame-selection-last-instr-call.exp diff --git a/gdb/stack.c b/gdb/stack.c index b36193be2f..8249866468 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -2860,8 +2860,8 @@ find_frame_for_function (const char *function_name) do { for (size_t i = 0; (i < sals.size () && !found); i++) - found = (get_frame_pc (frame) >= func_bounds[i].low - && get_frame_pc (frame) < func_bounds[i].high); + found = (get_frame_address_in_block (frame) >= func_bounds[i].low + && get_frame_address_in_block (frame) < func_bounds[i].high); if (!found) { level = 1; diff --git a/gdb/testsuite/gdb.base/frame-selection-last-instr-call.c b/gdb/testsuite/gdb.base/frame-selection-last-instr-call.c new file mode 100644 index 0000000000..4f056332af --- /dev/null +++ b/gdb/testsuite/gdb.base/frame-selection-last-instr-call.c @@ -0,0 +1,28 @@ +/* Copyright 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +void +frame_1 (void) +{ + __builtin_abort(); +} + +int +main (void) +{ + frame_1 (); +} diff --git a/gdb/testsuite/gdb.base/frame-selection-last-instr-call.exp b/gdb/testsuite/gdb.base/frame-selection-last-instr-call.exp new file mode 100644 index 0000000000..e5e86e0d6f --- /dev/null +++ b/gdb/testsuite/gdb.base/frame-selection-last-instr-call.exp @@ -0,0 +1,139 @@ +# Copyright 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This tests GDB's frame selection as used by the 'frame', +# 'select-frame', and 'info frame' commands in the corner case +# when the last instruction in a frame is a call. + +standard_testfile + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { + return -1 +} + +runto_main +gdb_test "continue" "Continuing.*Program received signal SIGABRT,.*" \ + "received signal SIGABRT" + +gdb_test "bt" \ + ".*#3 $hex in frame_1 .*#4 $hex in main .*" "backtrace at breakpoint" + +# Perform "info frame" to extract the frame's address. +proc get_frame_address { {testname ""} } { + global hex gdb_prompt + + set frame_address "unknown" + set testname "get_frame_address: ${testname}" + gdb_test_multiple "info frame" $testname { + -re ", frame at ($hex):\r\n.*\r\n$gdb_prompt $" { + set frame_address $expect_out(1,string) + pass $testname + } + } + + return $frame_address +} + +# Check that the current frame is at stack depth LEVEL, at frame +# address ADDRESS, and is in FUNCTION. +proc check_frame { level address function } { + global hex gdb_prompt + + if {$function == "abort"} { + set re [multi_line \ + "Stack level ${level}, frame at ($address):" \ + ".* = $hex in ${function}; saved .* = $hex" \ + ".*\r\n$gdb_prompt $" ] + + } else { + set re [multi_line \ + "Stack level ${level}, frame at ($address):" \ + ".* = $hex in ${function} \(\[^\r\n\]*\); saved .* = $hex" \ + ".*\r\n$gdb_prompt $" ] + } + + set testname "check frame level ${level}" + gdb_test_multiple "info frame" $testname { + -re $re { + pass $testname + } + } +} + +# Select frame using level, but relying on this being the default +# action, so "frame 0" performs "frame level 0". +gdb_test "frame 2" "#2 $hex in abort.*" +set frame_2_address [ get_frame_address "frame 2" ] +gdb_test "frame 3" "#3 $hex in frame_1.*" +set frame_3_address [ get_frame_address "frame 3" ] +gdb_test "frame 4" "#4 $hex in main.*" +set frame_4_address [ get_frame_address "frame 4" ] + +# Select frame using 'level' specification. +gdb_test "frame level 2" "#2 $hex in abort.*" +gdb_test "frame level 3" "#3 $hex in frame_1.*" +gdb_test "frame level 4" "#4 $hex in main.*" + +# Select frame by address. +gdb_test "frame address ${frame_2_address}" "#2 $hex in abort.*" \ + "select frame 2 by address" +gdb_test "frame address ${frame_3_address}" "#3 $hex in frame_1.*" \ + "select frame 3 by address" +gdb_test "frame address ${frame_4_address}" "#4 $hex in main.*" \ + "select frame 4 by address" + +# Select frame by function. +gdb_test "frame function abort" "#2 $hex in abort.*" +gdb_test "frame function frame_1" "#3 $hex in frame_1.*" +gdb_test "frame function main" "#4 $hex in main.*" + +with_test_prefix "select-frame, no keyword" { + gdb_test_no_output "select-frame 2" + check_frame "2" "${frame_2_address}" "abort" + gdb_test_no_output "select-frame 3" + check_frame "3" "${frame_3_address}" "frame_1" + gdb_test_no_output "select-frame 4" + check_frame "4" "${frame_4_address}" "main" +} + +with_test_prefix "select-frame, keyword=level" { + gdb_test_no_output "select-frame level 2" + check_frame "2" "${frame_2_address}" "abort" + gdb_test_no_output "select-frame level 3" + check_frame "3" "${frame_3_address}" "frame_1" + gdb_test_no_output "select-frame level 4" + check_frame "4" "${frame_4_address}" "main" +} + +with_test_prefix "select-frame, keyword=address" { + gdb_test_no_output "select-frame address ${frame_2_address}" \ + "select frame 2 by address" + check_frame "2" "${frame_2_address}" "abort" + gdb_test_no_output "select-frame address ${frame_3_address}" \ + "select frame 3 by address" + check_frame "3" "${frame_3_address}" "frame_1" + gdb_test_no_output "select-frame address ${frame_4_address}" \ + "select frame 4 by address" + check_frame "4" "${frame_4_address}" "main" +} + +with_test_prefix "select-frame, keyword=function" { + gdb_test_no_output "select-frame function abort" + check_frame "2" "${frame_2_address}" "abort" + gdb_test_no_output "select-frame function frame_1" + check_frame "3" "${frame_3_address}" "frame_1" + gdb_test_no_output "select-frame function main" + check_frame "4" "${frame_4_address}" "main" +} -- 2.45.2