From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id CUMJM5zN2GlAXhAAWB0awg (envelope-from ) for ; Fri, 10 Apr 2026 06:14:52 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=tzYcPtbU; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=9evfeBR7; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=tzYcPtbU; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=9evfeBR7; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id CB9B11E0BC; Fri, 10 Apr 2026 06:14:52 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (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 C01191E08C for ; Fri, 10 Apr 2026 06:14:51 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id ADC994BA23C3 for ; Fri, 10 Apr 2026 10:14:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ADC994BA23C3 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=tzYcPtbU; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=9evfeBR7; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=tzYcPtbU; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=9evfeBR7 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2a07:de40:b251:101:10:150:64:1]) by sourceware.org (Postfix) with ESMTPS id 47CEF4BA23C8 for ; Fri, 10 Apr 2026 10:13:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 47CEF4BA23C8 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 47CEF4BA23C8 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a07:de40:b251:101:10:150:64:1 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775815982; cv=none; b=qwHjo2L3xGxLNUwM9s07Mvl6wdolLU2fIUb9lMS0xl6pQFiOI/Gaau6zjNI9lmiX8Z8bClHWMtdEywbfM+ertdpOJXFYbedHR8Cdw2QWt79Ly7zArnXbhLSxj29MOngS6bT+A9gj6jci2ZziAB7kXkcsyDlQn8HRZ3Yfff84/80= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775815982; c=relaxed/simple; bh=VM84zIy7yBL3oFKQJmDBKq6kB2jlL+wtm76/8xqEETQ=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:From: To:Subject:Date:Message-ID:MIME-Version; b=mfQ+OGMss88LO09Nbs0nPSMkpOGq8JdaA8fQHI+vuEosn3GU1p2LZX7ln+jjSvqs07KXPVZkTbP4+Q90uVWB/TPRBmUQbHHdDvwJWkAR4zRxhFE+nNeMPduu7ZHXxCKMcYqcCSQzSILwPC9Eo4JXhLfZosshQ0OMaAkgLqKeNyI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 47CEF4BA23C8 Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [IPv6:2a07:de40:b281:104:10:150:64:97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 6E0DF6A7ED for ; Fri, 10 Apr 2026 10:12:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1775815973; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=auyqp49q+y7JN7eQ95Zr93U6Mv7yKbjhBmVdrwv70nI=; b=tzYcPtbUKxSmxRFSfpgXwZ8BOhWuVgGs6Ecc6GVpcZmnaH/OQBKTbQhFJWW2/C3vy2pOxZ lSNKgU5j7uywIHW7YUZFHiY+5ZmjuFlHOkJO+x9VeNfgbrd2WaPP77t3+GTdiNncJnfEQv N7FA2YfLJvzpHju62EbiUARpWcW7Cqc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1775815973; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=auyqp49q+y7JN7eQ95Zr93U6Mv7yKbjhBmVdrwv70nI=; b=9evfeBR7uxKUazbbCh3t4pKTQrfU3IAxsPZAYXWpWbSDovdmZKpDdaEWWxcr44vFaBX5g2 K65vbTo24F+q93Aw== Authentication-Results: smtp-out1.suse.de; dkim=pass header.d=suse.de header.s=susede2_rsa header.b=tzYcPtbU; dkim=pass header.d=suse.de header.s=susede2_ed25519 header.b=9evfeBR7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1775815973; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=auyqp49q+y7JN7eQ95Zr93U6Mv7yKbjhBmVdrwv70nI=; b=tzYcPtbUKxSmxRFSfpgXwZ8BOhWuVgGs6Ecc6GVpcZmnaH/OQBKTbQhFJWW2/C3vy2pOxZ lSNKgU5j7uywIHW7YUZFHiY+5ZmjuFlHOkJO+x9VeNfgbrd2WaPP77t3+GTdiNncJnfEQv N7FA2YfLJvzpHju62EbiUARpWcW7Cqc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1775815973; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=auyqp49q+y7JN7eQ95Zr93U6Mv7yKbjhBmVdrwv70nI=; b=9evfeBR7uxKUazbbCh3t4pKTQrfU3IAxsPZAYXWpWbSDovdmZKpDdaEWWxcr44vFaBX5g2 K65vbTo24F+q93Aw== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 59CC74A0B2 for ; Fri, 10 Apr 2026 10:12:53 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id uMe2FCXN2GlFaQAAD6G6ig (envelope-from ) for ; Fri, 10 Apr 2026 10:12:53 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH v4 3/4] gdb: fix missing print frame when stepping out of function Date: Fri, 10 Apr 2026 12:12:51 +0200 Message-ID: <20260410101252.1805303-4-tdevries@suse.de> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260410101252.1805303-1-tdevries@suse.de> References: <20260410101252.1805303-1-tdevries@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spamd-Result: default: False [-3.01 / 50.00]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; MID_CONTAINS_FROM(1.00)[]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.20)[-1.000]; R_DKIM_ALLOW(-0.20)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; MIME_GOOD(-0.10)[text/plain]; MX_GOOD(-0.01)[]; FUZZY_RATELIMITED(0.00)[rspamd.com]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; ARC_NA(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; FROM_HAS_DN(0.00)[]; MIME_TRACE(0.00)[0:+]; FROM_EQ_ENVFROM(0.00)[]; RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[2a07:de40:b281:106:10:150:64:167:received]; DBL_BLOCKED_OPENRESOLVER(0.00)[suse.de:dkim,suse.de:mid]; TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_NONE(0.00)[]; RCVD_TLS_ALL(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[gdb-patches@sourceware.org]; DNSWL_BLOCKED(0.00)[2a07:de40:b281:106:10:150:64:167:received]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; DKIM_TRACE(0.00)[suse.de:+] X-Rspamd-Action: no action X-Rspamd-Server: rspamd1.dmz-prg2.suse.org X-Rspamd-Queue-Id: 6E0DF6A7ED 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 Consider test-case gdb.dwarf2/dw2-extend-inline-block.exp, specifically the "contiguous block" prefix part, which can be stepped through like this: ... $ gdb -q outputs/gdb.dwarf2/dw2-extend-inline-block/dw2-extend-inline-block-5 Reading symbols from dw2-extend-inline-block-5... (gdb) start ... snip ... Temporary breakpoint 1, main () at dw2-extend-inline-block.c:35 35 /* main:2 */ (gdb) s 36 /* main:3 */ foo (); /* foo call line */ (gdb) foo () at dw2-extend-inline-block.c:26 26 /* foo:1 */ (gdb) s 27 /* foo:2 */ (gdb) s 28 /* foo:3 */ (gdb) s main () at dw2-extend-inline-block.c:37 37 /* main:4 */ (gdb) ... If we slightly modify the line program: ... DW_LNE_set_address main_4 + DW_LNS_advance_line 1 DW_LNS_copy DW_LNE_set_address main_5 - DW_LNS_advance_line 1 DW_LNS_negate_stmt DW_LNS_copy ... we change the 36/0x401165 entry into a 37/0x401165 entry: ... File name Line number Starting address View Stmt dw2-extend-inline-block.c 34 0x401116 x dw2-extend-inline-block.c 35 0x401129 x dw2-extend-inline-block.c 26 0x401138 x dw2-extend-inline-block.c 27 0x401147 x dw2-extend-inline-block.c 28 0x401156 x dw2-extend-inline-block.c 36 0x401156 -dw2-extend-inline-block.c 36 0x401165 +dw2-extend-inline-block.c 37 0x401165 dw2-extend-inline-block.c 37 0x401174 x dw2-extend-inline-block.c 38 0x401183 x dw2-extend-inline-block.c 39 0x401192 x dw2-extend-inline-block.c 40 0x4011a1 x dw2-extend-inline-block.c - 0x4011b7 ... As it happens, the fix to extend truncated inlined function blocks doesn't work in this case. This is PR gdb/33930. We can work around this by making sure that the inlined function block isn't truncated in the first place: ... - DW_AT_high_pc main_3 addr + DW_AT_high_pc main_4 addr ... But then we still run into PR gdb/33981: the problem that gdb doesn't notify us when stepping out of foo: ... (gdb) step^M 28 /* foo:3 */^M (gdb) step^M 37 /* main:4 */^M (gdb) ... What happens is that the slightly different line program triggers a different stepping path, which includes a case of "stepped to a different frame, but it's not the start of a statement", which refreshes the stepping info and consequently updates tp->control.step_frame_id to the frame id of main. So by the time we're stopped at line 37, and are trying to figure out what to print in print_stop_location, this condition evaluates to true: ... if (tp->control.stop_step && (tp->control.step_frame_id == get_frame_id (get_current_frame ())) && (tp->control.step_start_function == find_symbol_for_pc (tp->stop_pc ()))) ... and we get: ... /* Finished step in same frame and same file, just print source line. */ source_flag = SRC_LINE; ... It's good to realize here that because foo is inlined into main, tp->control.step_start_function is not foo but main, so consequently the step_start_function check (which checks if we are still in the same function) also passes, even though we actually stepped from foo into main. The problem is the use of find_symbol_for_pc, this function deliberately skips over inline frames and returns the symbol for the innermost non-inline frame. It might be tempting to think that we should switch to use find_symbol_for_pc_sect_maybe_inline, which will return the symbol for an inline frame, but this also has problems, specifically, attempting this caused a regression in gdb.opt/inline-cmds.exp. The previous version of this patch, which showed the regression can be found here: https://inbox.sourceware.org/gdb-patches/20260331132342.1050954-1-tdevries@suse.de At a given $pc the inferior might be reported as being within an inline frame, or it might be reported as being in the containing non-inline frame. When the user performs a 'step' the step_start_function needs to be set based on the function symbol of the frame the inferior is actually reported in. And we have a function that gives us this information, get_frame_function. So instead of looking up the step_start_function based on the $pc value, set it based on the frame. Test gdb.dwarf2/dw2-extend-inline-block.exp is extended with the additional test case described above. Tested on x86_64-linux. Co-Authored-By: Andrew Burgess Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33930 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33981 --- gdb/gdbthread.h | 12 ++--- gdb/infcmd.c | 3 +- gdb/infrun.c | 5 +-- .../gdb.dwarf2/dw2-extend-inline-block.exp | 45 +++++++++++++++++-- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 224e6e4b657..c56c4ce4036 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -154,10 +154,10 @@ struct thread_control_state CORE_ADDR step_range_start = 0; /* Inclusive */ CORE_ADDR step_range_end = 0; /* Exclusive */ - /* Set m_step_start_function according to PC. */ - void set_step_start_function (CORE_ADDR pc) + /* Set m_step_start_function according to FRAME. */ + void set_step_start_function (const frame_info_ptr &frame) { - m_step_start_function = find_symbol_for_pc (pc); + m_step_start_function = get_frame_function (frame); } /* Reset m_step_start_function. */ @@ -166,11 +166,11 @@ struct thread_control_state m_step_start_function = nullptr; } - /* Return true if the function symbol for PC matches + /* Return true if the function symbol of FRAME matches m_step_start_function. */ - bool in_step_start_function (CORE_ADDR pc) + bool in_step_start_function (const frame_info_ptr &frame) { - return m_step_start_function == find_symbol_for_pc (pc); + return m_step_start_function == get_frame_function (frame); } /* Return true if m_step_start_function is set. */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index a1df59e09f2..c0d12be6e4a 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -898,8 +898,7 @@ set_step_frame (thread_info *tp) symtab_and_line sal = find_frame_sal (frame); set_step_info (tp, frame, sal); - CORE_ADDR pc = get_frame_pc (frame); - tp->control.set_step_start_function (pc); + tp->control.set_step_start_function (frame); } /* Step until outside of current statement. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index becd68a21ad..dea2a2cbd48 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -7871,8 +7871,7 @@ process_event_stop_test (struct execution_control_state *ecs) == ecs->event_thread->control.step_stack_frame_id) && ((ecs->event_thread->control.step_stack_frame_id != outer_frame_id) - || !ecs->event_thread->control.in_step_start_function - (ecs->event_thread->stop_pc ())))) + || !ecs->event_thread->control.in_step_start_function (frame)))) { CORE_ADDR stop_pc = ecs->event_thread->stop_pc (); CORE_ADDR real_stop_pc; @@ -9359,7 +9358,7 @@ print_stop_location (const target_waitstatus &ws) if (tp->control.stop_step && (tp->control.step_frame_id == get_frame_id (get_current_frame ())) - && tp->control.in_step_start_function (tp->stop_pc ())) + && tp->control.in_step_start_function (get_current_frame ())) { symtab_and_line sal = find_frame_sal (get_selected_frame (nullptr)); if (sal.symtab != tp->current_symtab) diff --git a/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp b/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp index 9e4798b53f3..481dfbdd134 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp @@ -52,8 +52,11 @@ get_func_info main # Create DWARF for the test. In this case, inline function 'foo' is created # with a contiguous address range that needs extending. -proc build_dwarf_for_contiguous_block { asm_file } { +proc build_dwarf_for_contiguous_block { asm_file {range_correct 0} {variant 0} } { Dwarf::assemble $asm_file { + upvar range_correct range_correct + upvar variant variant + declare_labels lines_table inline_func cu { } { @@ -83,7 +86,11 @@ proc build_dwarf_for_contiguous_block { asm_file } { DW_AT_call_file 1 data1 DW_AT_call_line $::foo_call_line data1 DW_AT_low_pc main_1 addr - DW_AT_high_pc main_3 addr + if {$range_correct} { + DW_AT_high_pc main_4 addr + } else { + DW_AT_high_pc main_3 addr + } } } } @@ -120,10 +127,15 @@ proc build_dwarf_for_contiguous_block { asm_file } { DW_LNS_copy DW_LNE_set_address main_4 + if {$variant == 1} { + DW_LNS_advance_line 1 + } DW_LNS_copy DW_LNE_set_address main_5 - DW_LNS_advance_line 1 + if {$variant == 0} { + DW_LNS_advance_line 1 + } DW_LNS_negate_stmt DW_LNS_copy @@ -146,6 +158,22 @@ proc build_dwarf_for_contiguous_block { asm_file } { } } +# Like build_dwarf_for_contiguous_block, but use a slightly different line +# info by setting variant == 1. +# Use range_correct 1, so we're not testing the fix for PR33930. + +proc build_dwarf_for_contiguous_block_2 { asm_file } { + return [build_dwarf_for_contiguous_block $asm_file 1 1] +} + +# Like build_dwarf_for_contiguous_block, but use a slightly different line +# info by setting variant == 1. +# Use range_correct 0, so we're testing the fix for PR33930. + +proc build_dwarf_for_contiguous_block_3 { asm_file } { + return [build_dwarf_for_contiguous_block $asm_file 0 1] +} + # Assuming GDB is stopped at the entry $pc for 'foo', use 'maint info # blocks' to check the block for 'foo' is correct. This function checks # 'foo' created by 'build_dwarf_for_contiguous_block'. @@ -555,6 +583,12 @@ set test_list \ [list "contiguous block" \ build_dwarf_for_contiguous_block \ check_contiguous_block] \ + [list "contiguous block 2" \ + build_dwarf_for_contiguous_block_2 \ + check_contiguous_block] \ + [list "contiguous block 3" \ + build_dwarf_for_contiguous_block_3 \ + check_contiguous_block] \ ] # Run all the tests. @@ -566,6 +600,11 @@ foreach test_spec $test_list { set build_dwarf_func [lindex $test_spec 1] set check_block_func [lindex $test_spec 2] + if {$build_dwarf_func == "build_dwarf_for_contiguous_block_3"} { + # Work around PR gdb/33930. + continue + } + with_test_prefix $prefix { set asm_file [standard_output_file ${testfile}-${suffix}.S] $build_dwarf_func $asm_file -- 2.51.0