From patchwork Mon Mar 30 09:21:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitry Shafranov X-Patchwork-Id: 132441 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id BD6404BA9001 for ; Mon, 30 Mar 2026 09:22:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BD6404BA9001 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=FEUOLpOq X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-lj1-x236.google.com (mail-lj1-x236.google.com [IPv6:2a00:1450:4864:20::236]) by sourceware.org (Postfix) with ESMTPS id CAF6D4BA2E04 for ; Mon, 30 Mar 2026 09:22:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CAF6D4BA2E04 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 CAF6D4BA2E04 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=2a00:1450:4864:20::236 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1774862531; cv=pass; b=MWMT8/YQ04YEP87kzoDK07VchXtmiq9AHFS+1sLQj+ub8o5l7Vs9zrZSLjUJZz3xve5YvTEpMGR3GjWFqs+4k+mbwLV0YO84yds71cAn4v+RvWzMF4+3QigMW3GrHLOx/PLvHCXdvGlNKycVqq65GhjER7q+VuarjFuYqMu34/Y= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1774862531; c=relaxed/simple; bh=jllmq5STgI08FVPFIuDORLc2f3MSlTJj+liB6eb7OBw=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=IuFoc9ln8x3Vl8OfhG75kqw0N+7OW9nlddNWWRz9WUCejq/vnlEw4q9EhiCyXxxjpAiTsY6OEDGV3X3uJRSfYXbrNlDWllLEtA3fYhc4SavicakcYzLJspeubL6Y1af9hyiM4g41iaF4glnSa1lGGRlavaYbTGuD4PU2RUWL5L0= ARC-Authentication-Results: i=2; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CAF6D4BA2E04 Received: by mail-lj1-x236.google.com with SMTP id 38308e7fff4ca-38a23dd61c1so35612121fa.1 for ; Mon, 30 Mar 2026 02:22:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774862529; cv=none; d=google.com; s=arc-20240605; b=VA7n/auyNiKAmBj8kMuZ9N2lsPjJhwdla62+R9w/9Pmk4tZcZj0DCCWF4sEY3PSn6e SfjMtpYGKFhZeRGqEqK+0ksq+bCHgl6VOmLeC3wV3lwZBo1N7keF9pCueKqjG4HwUgu8 XbvOnRcV1JspWxMSDbzS4KlZRV5UTeyXMRsjfcSTJLw5+873kqFqJMXsZ7fGBOzCqzVS OVCOgHo21Ml6lUE8A3M1/zgIwplZa4VmAk5otUnOc1rGbTl/G8mpWIhI3sUDW8hmZDkH IbqITUGBd1+CCK5TirGFxxk9UQVh1VFp/CCRwmL2iizOEduJSdKeG8OzDEmzx60M4mVO RXbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=EUCzC4aAyhMjJbHmAAS0jPme9gKFg35XZDXX6BZCHdM=; fh=72kqq0iQhigvR9Vv/oqX5ebs3Yyyw7XhzWxOOEPdupI=; b=eFm7mX1rRszem+HqPdv4wzr7/2z5MOrL3TSueSImrvO9vyDQUAYd/d76Cjc0+WB1TU s/AmxH3ho1Xa3P8PblN0ymR2JKmdXHaXZexknvYR7wKp6bPv0po4NVnuLUjX5bGMt44G 1lGJ8SPf1gRTVVBGWZMS72CS2wRvWE0es6Eu77jy6rj5PgKKikIm6Yw4m0RsYdaY6jkw wc7KUlaffWINJTtatYGaNZDjEc3UeUJBiFi8bA4NC9G3JoeembBCNrlWUAifQi1X5OZt yIWxxWNGgJ6UtnKoTGeC0h+CiOqEyjnGUWcReK8tp6lXcQw3ktn2QD+k7M3jWiKsmFtG cPkw==; darn=sourceware.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774862529; x=1775467329; darn=sourceware.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=EUCzC4aAyhMjJbHmAAS0jPme9gKFg35XZDXX6BZCHdM=; b=FEUOLpOqwdzNp5yaIpIes431pxRhB3HCc7MI/lv+IpUjjvrEMknsKhJ/OqOiUEI65V gpPFuY4jh6DtFE6/dXVpy5XqNo4kIovE0r7Pna9DMflQrOB/AuQxKLom+dCCAJShVQIY 932sZfLEz5K1YgxvF5FD4tc813bpZLfTF9VRN53YgyTypoTrbrKd2bjEJkTyDvXIPyhE c4Bexa6237jpTdce5aBrchB3/JwDC2TE/QbCeDfyluUCOeopPtEZDHIDXvldzZY5hUtj LP7WvvUfvr2f3cKwiwURKCqHXtDqU+Tth6vrVHkjhvf6LjP83GkpTmyCduHKuGHIdgF9 t5Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774862529; x=1775467329; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=EUCzC4aAyhMjJbHmAAS0jPme9gKFg35XZDXX6BZCHdM=; b=Oey4pPA+4xoiy8N1HVh8n0CU1xemx9iJADXd7He4XgDjyUyPVkwo/LUyWiBey4uc8X aG11iu3uaXAhxUCRaRDIHVaRZCXnSsPXl2FCn72BQpXquPaAts7fF1hJaOq/a43GGg9s exoZmsOuMEhHpY4j3qgHEiPD+azBsfYz2LT6r6Iif0b0dwutsDZuWlIj0Gvuw65kkh+/ 6tvwFBrHvGvFeOJKMqjjceZqQr2VaYfdjW1rSVwtqnfSg8AL0aBzb2o7y4NoupqYBknS cksmtnEQX5biU73ALNf99dj53axox8Dh3kafNjju52+aQe9pao7YHsNzJ2+r+LPkaQWy R9vQ== X-Gm-Message-State: AOJu0YzrB+MT/kUk6+Nm9BDStgA8GruwGH/hzgGHSOZhmHuRo5k2llOO Ylf0KDMuAV1W3B9t/KZeT5KnzlVr23kCbUtwoatd/WawYp4h9+7Q6SjG7g+oM4zVmZNrMG4V+0s lPaqdghB3AeAV4XGPJKLKiMBU5ItIS56WNMC35xFTnA== X-Gm-Gg: ATEYQzyVPdwnHuU9WG5y1ox8PGkhR7F18uzC1eT5PohdNOoGDAHk0vR3MTflvgibBv8 xQ/i0Mnd8KLsZEbB3T78MNljPZhqR09heC3bLPKM1gQyeuqWHQSb9oPgwMFKqMQoM1YHCbbKtbZ r5QzwPt3VF+wWwEjfhYOvlwWqjYFIjJ4qi3mGghywomoSQ6Wr7yfrE4WjbBPvp3GIAwDHUPaHPh wrg5hbUqfly30Waq0vS2yMRxM1HSOXvmIQakyUx1KsP5nRZslxyOhyY6qOZFIPAIagg92VXdbdt /lMpxUcHrF88J95KN/VrFbcHCyrK0UIy1oMqkB68 X-Received: by 2002:a05:651c:547:b0:38a:2c09:b44c with SMTP id 38308e7fff4ca-38c74049c21mr39200311fa.32.1774862528560; Mon, 30 Mar 2026 02:22:08 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Dmitry Shafranov Date: Mon, 30 Mar 2026 12:21:55 +0300 X-Gm-Features: AQROBzCNn0YIVIlOsoCzcmYuB49xg-I7Ju2wOgQSmyz0MbPKhOKlRujdBxCXelc Message-ID: Subject: Fwd: [PATCH] Fix backtrace showing ?? or wrong name for solib frame at function entry To: gdb-patches@sourceware.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, PROLO_LEO1, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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~patchwork=sourceware.org@sourceware.org Pinging ---------- Forwarded message --------- От: Дима Date: сб, 7 мар. 2026 г. в 22:48 Subject: [PATCH] Fix backtrace showing ?? or wrong name for solib frame at function entry To: When the resume PC is exactly at a function entry in a shared library without debug info (e.g. a trampoline that does push return-address + jmp), the backtrace shows "??" or the previous function name for that frame. Reason: get_frame_address_in_block gives pc-1 for non-innermost frames, and lookup_minimal_symbol_by_pc(pc-1) then finds nothing or the wrong symbol. The fix: in find_frame_funname, if lookup_minimal_symbol_by_pc(pc) fails, try pc+1; and when a symbol is found, also check pc+1 and prefer the symbol whose address is exactly pc+1 (the actual resume PC at function entry). Tested on x86_64 Linux (-m32). Added gdb.base/solib-bt-trampoline.exp. Reproducer: gdb-solib-bt-bug-repro.tar.gz — see README inside for build and run steps. Patch below: From 935853aaf1e2b4260b026ca36f5cfb9096c6b40c Mon Sep 17 00:00:00 2001 From: Dmitry Shafranov Date: Sat, 7 Mar 2026 22:14:22 +0300 Subject: [PATCH] Fix backtrace showing ?? or wrong name for solib frame at function entry For frames without full symbols (e.g. solib with no debug info), find_frame_funname uses get_frame_address_in_block and then lookup_minimal_symbol_by_pc. For non-innermost frames we get pc-1. When the resume PC is exactly at a function entry (e.g. a trampoline that does push+jmp), pc-1 is before that function, so the lookup fails (backtrace shows "??") or finds the previous function in the same object. Add a fallback: if lookup_minimal_symbol_by_pc(pc) returns NULL, try lookup_minimal_symbol_by_pc(pc+1). This recovers the correct symbol for the "PC at function entry" case without changing unwinding or get_frame_address_in_block. --- gdb/stack.c | 13 ++++ .../gdb.base/solib-bt-trampoline-lib.S | 24 ++++++ gdb/testsuite/gdb.base/solib-bt-trampoline.c | 21 ++++++ .../gdb.base/solib-bt-trampoline.exp | 74 +++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 gdb/testsuite/gdb.base/solib-bt-trampoline-lib.S create mode 100644 gdb/testsuite/gdb.base/solib-bt-trampoline.c create mode 100644 gdb/testsuite/gdb.base/solib-bt-trampoline.exp + } + -re "$gdb_prompt $" { + fail $gdb_test_name + } +} -- 2.53.0 diff --git a/gdb/stack.c b/gdb/stack.c index aa0257902e1..f60258fa9f2 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1311,6 +1311,19 @@ find_frame_funname (const frame_info_ptr &frame, enum language *funlang, return funname; bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); + if (msymbol.minsym == NULL) + { + /* pc may be at function entry (get_frame_address_in_block uses pc-1); try pc+1. */ + msymbol = lookup_minimal_symbol_by_pc (pc + 1); + } + else + { + /* Prefer symbol at pc+1 (resume PC) when it is exactly at function entry. */ + bound_minimal_symbol at_pc_plus_one = lookup_minimal_symbol_by_pc (pc + 1); + if (at_pc_plus_one.minsym != NULL + && at_pc_plus_one.value_address () == pc + 1) + msymbol = at_pc_plus_one; + } if (msymbol.minsym != NULL) { funname = make_unique_xstrdup (msymbol.minsym->print_name ()); diff --git a/gdb/testsuite/gdb.base/solib-bt-trampoline-lib.S b/gdb/testsuite/gdb.base/solib-bt-trampoline-lib.S new file mode 100644 index 00000000000..0273e1b471d --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-bt-trampoline-lib.S @@ -0,0 +1,24 @@ +/* Trampoline: run_then_exit + run_then_exit_return in one object. + When return address is exactly at run_then_exit_return entry, GDB + looks up pc-1 and without the fix shows "run_then_exit" or "??". */ + .text + .globl run_then_exit + .type run_then_exit,@function + .globl run_then_exit_return + .type run_then_exit_return,@function + .extern exit +run_then_exit: + push %ebp + mov %esp, %ebp + call .Lpic +.Lpic: + pop %eax + add $(run_then_exit_return - .Lpic), %eax + push 12(%ebp) + push %eax + jmp *8(%ebp) + .size run_then_exit, .-run_then_exit +run_then_exit_return: + push $0 + call exit@PLT + .size run_then_exit_return, .-run_then_exit_return diff --git a/gdb/testsuite/gdb.base/solib-bt-trampoline.c b/gdb/testsuite/gdb.base/solib-bt-trampoline.c new file mode 100644 index 00000000000..96e150e2279 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-bt-trampoline.c @@ -0,0 +1,21 @@ +/* Test program for run_then_exit trampoline. Stops in user callback so that + "bt" in GDB shows the trampoline return frame: frame #1 should be + run_then_exit_return (not "??" or "run_then_exit"). */ + +#include + +extern void run_then_exit (void (*fn) (void *), void *arg); + +static void +inner_func (void *arg) +{ + (void) arg; + return; /* Break here and run "bt". */ +} + +int +main (void) +{ + run_then_exit (inner_func, NULL); + return 0; +} diff --git a/gdb/testsuite/gdb.base/solib-bt-trampoline.exp b/gdb/testsuite/gdb.base/solib-bt-trampoline.exp new file mode 100644 index 00000000000..18418e8f121 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-bt-trampoline.exp @@ -0,0 +1,74 @@ +# Copyright 2026 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 . + +# Test that backtrace shows the correct function name for a solib frame +# when the resume PC is exactly at function entry (trampoline that does +# push return-address + jmp). Without the fix, frame #1 shows "??" or +# the previous function (run_then_exit) instead of run_then_exit_return. + +require allow_shlib_tests +require {is_any_target "i?86-*-*" "x86_64-*-*"} + +standard_testfile solib-bt-trampoline.c +set libsrc ${srcdir}/${subdir}/solib-bt-trampoline-lib.S +set libname "solib-bt-trampoline-lib" +set libfile [standard_output_file ${libname}.so] + +# Shared library: assembly only, no debug info (so minimal symbols are used). +set lib_opts [list nodebug ldflags=-nostdlib libs=-lc] +if {![istarget "i386-*-*"]} { + lappend lib_opts "additional_flags=-m32" +} + +if {[gdb_compile_shlib $libsrc $libfile $lib_opts] != ""} { + untested "failed to compile shared library (need 32-bit toolchain on x86_64?)" + return -1 +} + +set exec_opts [list debug shlib=$libfile "additional_flags=-fno-omit-frame-pointer"] +if {![istarget "i386-*-*"]} { + lappend exec_opts "additional_flags=-m32" +} + +if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} { + untested "failed to compile executable" + return -1 +} + +clean_restart $testfile +gdb_load_shlib $libfile + +if {![runto_main]} { + return -1 +} + +gdb_breakpoint "inner_func" +# Pattern must match to end of line (e.g. solib-bt-trampoline.c:13) so \r\n is next. +set location_pattern "inner_func\[^\r\n\]*|solib-bt-trampoline\[^\r\n\]*" +gdb_test_multiple "continue" "continue to breakpoint: inner_func" { + -re "(?:Breakpoint|Temporary breakpoint) .* (at|in) $location_pattern\[\r\n\]+.*$gdb_prompt $" { + pass $gdb_test_name + } +} + +# Frame #1 must be run_then_exit_return (not "??" or "run_then_exit"). +gdb_test_multiple "bt" "backtrace shows run_then_exit_return in frame 1" { + -re "#1\[^\r\n\]*run_then_exit_return" { + pass $gdb_test_name