From patchwork Thu Jun 30 13:57:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 13510 Received: (qmail 27516 invoked by alias); 30 Jun 2016 13:57:34 -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 27504 invoked by uid 89); 30 Jun 2016 13:57:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=comparing, 1377, werner, Werner X-HELO: mail-pf0-f193.google.com Received: from mail-pf0-f193.google.com (HELO mail-pf0-f193.google.com) (209.85.192.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 30 Jun 2016 13:57:23 +0000 Received: by mail-pf0-f193.google.com with SMTP id c74so7492831pfb.0 for ; Thu, 30 Jun 2016 06:57:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=XCRh/d7k3ATDwrOXYAvjTcJY683nqC4CVqirI8dOA9o=; b=WPyxMRSCOFRqpRgHVINiN2We3mEvJBDE2XcGTcv/WrV0smC7fRYBrvn/U95AMwErjR AiRa3GfN4tA4bJXuKKy+V3Fw1uP4ZVw2r3X44HVQcFe1njOs7l4FuHiZ+skyZZXcltT9 wzq61qHm9zdHmbMenubVi2J3MSURoNt1lmqAsF27R3HACTaf/waYFZyzDyunepQCcX4J kR0z79rdUyrunKtMZHEKDbN/AgyyLel+uUdtJqC+Dhp1MUm4TaQiYUAalWd0O0iEUYh5 xaH6svhOQu+pWpN1P1JXw0sjp4ypN2IaIctmXjv3LdQiAyj2o39fzL3uN2/a+VlyA3zh EmOQ== X-Gm-Message-State: ALyK8tLW+IpHLym8QWTQpfWiYzZj3e2tAMxTE4sQVQLNoJyJup1d1qnDj7/u7d78oEZW4w== X-Received: by 10.98.93.216 with SMTP id n85mr21642902pfj.36.1467295041683; Thu, 30 Jun 2016 06:57:21 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id s65sm6082834pfd.23.2016.06.30.06.57.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 30 Jun 2016 06:57:21 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [RFC] Set process affinity in test to work around ARM ptrace bug Date: Thu, 30 Jun 2016 14:57:16 +0100 Message-Id: <1467295036-2816-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes We recently found a ARM kernel ptrace bug http://lists.infradead.org/pipermail/linux-arm-kernel/2016-May/431962.html As a result of this bug, after GDB ptrace set VFP registers, the hardware registers may not be updated. This bug causes some intermittent fails in tests, like return.exp, call-rt-st.exp, callfuncs.exp, etc. The bug is fixed in ARM kernel tree, but it is impractical to upgrade linux kernel from git tree or most recently release (I don't know when the fix can be shipped in the mainline kernel release). I am wondering we can workaround this kernel bug somehow. My first attempt is to workaround it in GDB, so that GDB still writes the VFP registers and sync them to hardware. The kernel patch is quite simple, which moves vfp_flush_hwstate one line below. Probably, we can call ptrace set vfp registers twice, and then the second vfp set can flush the state correctly. Unfortunately, it doesn't work, because every time of ptrace set, kernel loads VFP registers from hardware first, which might be out of date after the first ptrace set. That is to say, we can't workaround this kernel bug in GDB. Then, I am thinking we can workaround this bug in testing, because the intermittent fails are confusing in comparing test results, by binding both tracer and tracee on the same core. For example, we can start GDB or GDBserver with "taskset -c 0 ", but this is a global change, may have some affects on gdb.threads tests. I also think about doing "taskset -p PID -c 0" in test harness after the inferior is started, and do the same to the parent process of inferior (which is either GDB or GDBserver). The approach in this patch is to have a small c function which sets both process affinity and its parent's affinity to core 0. This function should be called in these tests explicitly, but other tests are not affected at all. This patch is posted to get comments on the necessity of workaround this kernel bug, and the proper to workaround this bug. There are still some test cases affected by this kernel bug, but this patch doesn't touch them yet. gdb/testsuite: 2016-06-30 Yao Qi * lib/set_process_affinity.c: New file. * gdb.base/call-rt-st.c: Include lib/set_process_affinity.c. (main): Call set_process_affinity. * gdb.base/gnu_vector.c: Likewise. * gdb.base/return.c: Likewise. * gdb.base/gnu_vector.exp: Adjust test. --- gdb/testsuite/gdb.base/call-rt-st.c | 2 ++ gdb/testsuite/gdb.base/gnu_vector.c | 4 +++- gdb/testsuite/gdb.base/gnu_vector.exp | 3 +++ gdb/testsuite/gdb.base/return.c | 2 ++ gdb/testsuite/lib/set_process_affinity.c | 41 ++++++++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/lib/set_process_affinity.c diff --git a/gdb/testsuite/gdb.base/call-rt-st.c b/gdb/testsuite/gdb.base/call-rt-st.c index 072ea86..ad97e28 100644 --- a/gdb/testsuite/gdb.base/call-rt-st.c +++ b/gdb/testsuite/gdb.base/call-rt-st.c @@ -1,3 +1,4 @@ +#include "../lib/set_process_affinity.c" #include #include #include @@ -565,6 +566,7 @@ int main () { struct two_floats_t *f3; gdb_unbuffer_output (); + set_process_affinity (); /* Allocate space for large structures */ diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c index ee03ac1..8e0d6a8 100644 --- a/gdb/testsuite/gdb.base/gnu_vector.c +++ b/gdb/testsuite/gdb.base/gnu_vector.c @@ -18,6 +18,7 @@ Contributed by Ken Werner */ #include +#include "../lib/set_process_affinity.c" #define VECTOR(n, type) \ type __attribute__ ((vector_size (n * sizeof(type)))) @@ -137,7 +138,8 @@ main () { int4 res; - res = add_some_intvecs (i4a, i4a + i4b, i4b); + set_process_affinity (); + res = add_some_intvecs (i4a, i4a + i4b, i4b); /* breakpoint here */ res = add_some_intvecs (i4a, i4a + i4b, i4b); diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp index aafaedd..1e57a26 100644 --- a/gdb/testsuite/gdb.base/gnu_vector.exp +++ b/gdb/testsuite/gdb.base/gnu_vector.exp @@ -55,6 +55,9 @@ gdb_test_multiple "show endian" "show endian" { } } +gdb_breakpoint [gdb_get_line_number "breakpoint here"] +gdb_continue_to_breakpoint "breakpoint here" + # Test printing of character vector types gdb_test "print c4" "\\\$$decimal = \\{1, 2, 3, 4\\}" gdb_test "print c4\[2\]" "\\\$$decimal = 3" diff --git a/gdb/testsuite/gdb.base/return.c b/gdb/testsuite/gdb.base/return.c index c365e88..6ff38e6 100644 --- a/gdb/testsuite/gdb.base/return.c +++ b/gdb/testsuite/gdb.base/return.c @@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "../lib/set_process_affinity.c" #include /* Test "return" command. */ @@ -40,6 +41,7 @@ double tmp3; int main () { + set_process_affinity (); func1 (); printf("in main after func1\n"); tmp2 = func2 (); diff --git a/gdb/testsuite/lib/set_process_affinity.c b/gdb/testsuite/lib/set_process_affinity.c new file mode 100644 index 0000000..2615965 --- /dev/null +++ b/gdb/testsuite/lib/set_process_affinity.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2016 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 . */ + +#if defined(__arm__) && defined(__linux__) +#define _GNU_SOURCE +#include +#include +#include +#endif + +static int +set_process_affinity (void) +{ +#if defined(__arm__) && defined(__linux__) + cpu_set_t my_set; + + /* Set both process and parent process (GDB)'s affinity on core 0 + to workaround ARM linux kernel ptrace bug which doesn't flush the + VFP state to hardware after ptrace set VFP registers. */ + + CPU_ZERO (&my_set); + CPU_SET (0, &my_set); + + sched_setaffinity (0, sizeof(cpu_set_t), &my_set); + sched_setaffinity (getppid (), sizeof(cpu_set_t), &my_set); +#endif +}