From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 18EE23858C52; Sun, 19 May 2024 18:21:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 18EE23858C52 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1716142875; bh=8Kpn7uhKolyCziaYbZPIURCldt8dKGzw6kdyodB/mDA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=wXp0uyLbdypvSVUDU/8OehFIg1BF2ogVT6/0UakvtzhMzDXzQVNP7fT5m0OBbkJVR rrw4gmynrt57kIlrMVUs/uTSei7wMiIBtEMwPDwisCVTUC8r1UKYJmuVQUD+4nJIRE WO/YOp7cwOeM3MbQU+kc6H5d5wQBDcBnj8+jyjOs= From: "jskumari at linux dot ibm.com" To: glibc-bugs@sourceware.org Subject: [Bug nptl/26566] nptl/tst-thread-exit-clobber fails on powerpc/powerpc64 with GCC 10.2 Date: Sun, 19 May 2024 18:21:13 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: nptl X-Bugzilla-Version: unspecified X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jskumari at linux dot ibm.com X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D26566 Surya Kumari J changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jskumari at linux dot ibm.= com --- Comment #9 from Surya Kumari J --- Adding some more details: In this testcase, we have the following call chain: threadfunc()->call_pthread_exit()->call_pthread_exit1()->pthread_exit() The threadfunc() function is passed a struct containing 5 values. 5 local objects of type =E2=80=9Cclass checker=E2=80=9D are created in threadfunc()= and the instance variable in each object is initialized with a value from the struct passed = as parameter. The values in the struct are stored in vector registers vs59-vs63 during the constructor calls. The call_pthread_exit1() routine too is passed a struct containing 5 valu= es (these values are different from those in the struct passed to threadfunc()= ). The prolog in this routine stores the registers v27-v31 as these are non-volatile registers. Note that v27-v31 overlap with vs59-vs63. This rout= ine creates 5 local objects of type =E2=80=98class checker=E2=80=99. The instan= ce variable in each object is initialized with a value from the struct passed as parameter. The values in the struct are stored in vector registers vs59-vs63 during the constructor calls. The destructor for =E2=80=98class checker=E2=80=99 has =E2=80=98inline=E2= =80=99 attribute and hence we have code to destroy the objects inlined into threadfunc() and call_pthread_exit= 1(). 4. The destructor checks if the instance variable in the object is the same= as what it was initialized to, and the test fails if the value is not the same. Since the destructor code is inlined, the value of the instance variable is compared with the value in the vector register. While the checks in the destructors pass in call_pthread_exit1(), the che= cks fail in threadfunc(). In threadfunc(), the vector registers do not contain = the expected values. The assembly code for call_pthread_exit1 looks as follows: call_pthread_exit1() { prolog code (contains code to save non-volatile vector registers) code to copy values from =E2=80=98struct parameter=E2=80=99 to vector = registers code to call constructors call to pthread_exit() landing pad: inlined destructor code which reads vector registers call to _Unwind_Resume() } Assembly code for threadfunc(): threadfunc() { code to copy values from =E2=80=98struct parameter=E2=80=99 to vector = registers code to call constructors landing pad: inlined destructor code which reads vector registers } Pthread_exit() has to destroy all the objects created in the call chain. = So the landing pad code in call_pthread_exit1() is executed to destroy the obj= ects created in call_pthread_exit1(). After the destructors finish executing, _Unwind_Resume is called because we have to unwind the stack. When the stack is unwound and we reach the landing pad in threadfunc(), t= he vector registers no longer contain the correct values. This is because the vector registers have been rewritten in call_pthread_exit1(). Of course, call_pthread_exit1()=E2=80=99s prolog saves these registers on stack before= writing to them. When we unwind and go from call_pthread_exit1()=E2=80=99s frame to th= e previous frame (call_pthread_exit()), these vector registers have to be restored to their original values from the stack. The issue can either be in unwinding (unwind is not restoring vector registers correctly when unwinding the stack frames) or in gcc (gcc does not produce correct unwind info thereby leading to incorrect unwinding) . --=20 You are receiving this mail because: You are on the CC list for the bug.=