From patchwork Thu Mar 5 22:21:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 38442 Received: (qmail 113938 invoked by alias); 5 Mar 2020 22:21:12 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 113928 invoked by uid 89); 5 Mar 2020 22:21:12 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_SOFTFAIL autolearn=ham version=3.3.1 spammy=meat, HContent-Transfer-Encoding:8bit X-HELO: barracuda.ebox.ca Received: from barracuda.ebox.ca (HELO barracuda.ebox.ca) (96.127.255.19) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 05 Mar 2020 22:21:10 +0000 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id ouEg4Tt9ryy66B8C (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 05 Mar 2020 17:21:08 -0500 (EST) Received: from epycamd.internal.efficios.com (192-222-181-218.qc.cable.ebox.net [192.222.181.218]) by smtp.ebox.ca (Postfix) with ESMTP id CBF14441B21; Thu, 5 Mar 2020 17:21:08 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH] gdb: make gdb.arch/amd64-disp-step-avx.exp actually test displaced stepping Date: Thu, 5 Mar 2020 17:21:08 -0500 Message-Id: <20200305222108.27194-1-simon.marchi@efficios.com> MIME-Version: 1.0 The test gdb.arch/amd64-disp-step-avx.exp is meant to test that doing a displaced step of an AVX instruction works correctly. However, I found (by pure coincidence) that the test instructions are not actually displaced stepped. Rather, they are inline-stepped, so the test is not actually testing what it's meat to test. This is what a portion of the test binary looks like: 0000000000400180 <_start>: 400180: 90 nop 0000000000400181
: 400181: 90 nop 0000000000400182 : 400182: c5 fb 10 05 0e 00 00 vmovsd 0xe(%rip),%xmm0 # 400198 400189: 00 000000000040018a : 40018a: 90 nop The instruction at 0x400182 is the one we want to test a displaced step for. A breakpoint is placed at 0x400182 and ran to. The execution is then resumed from there, forcing a step-over (which should normally be a displaced step) of the breakpoint. However, the displaced stepping buffer is at the _start label, and that means a breakpoint is present in the displaced stepping buffer. The breakpoint_in_range_p check in displaced_step_prepare_throw evaluates to true, which makes displaced_step_prepare_throw fail, forcing GDB to fall back on an in-line step. This can be easily observed by placing a `gdb_assert (false)` inside the breakpoint_in_range_p condition, in displaced_step_prepare_throw, and running gdb.arch/amd64-disp-step-avx.exp. The assertion will make the test fail. The proposed fix is to pad `_start` with a bunch of nops so that the test instruction is out of the displaced step buffer. I also think it would be good to enhance the test to make sure that we are testing displaced stepping as intended. I did that by enabling "set debug displaced on" while we step over the interesting instruction, and matching a message printed only when a displaced step is executed. gdb/testsuite/ChangeLog: * gdb.arch/amd64-disp-step-avx.S: Add nops after _start. * gdb.arch/amd64-disp-step-avx.exp: Enable "set debug displaced on" while stepping over the test instruction, match printed message. --- gdb/testsuite/gdb.arch/amd64-disp-step-avx.S | 5 +++++ gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S index 76747360b9..c72f6a5ca8 100644 --- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S +++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S @@ -22,7 +22,12 @@ .global _start,main _start: + # The area at _start is used as the displaced stepping buffer. Put + # more than enough nop instructions so that the instructions under test + # below don't conflict with it. + .rept 200 nop + .endr main: nop diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp index 23282f6678..3144a147f3 100644 --- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp +++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp @@ -92,10 +92,16 @@ proc disp_step_func { func } { set value "0xdeadbeefd3adb33f" set_regs $value + # Turn "debug displaced" on to make sure displaced step is actually + # executed, not an inline step. + gdb_test_no_output "set debug displaced on" + gdb_test "continue" \ - "Continuing.*Breakpoint.*, ${test_end_label} ().*" \ + "Continuing.*displaced: displaced pc to.*Breakpoint.*, ${test_end_label} ().*" \ "continue to ${test_end_label}" + gdb_test_no_output "set debug displaced off" + verify_regs $value }