From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id E04C83858C56; Fri, 17 May 2024 14:08:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E04C83858C56 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1715954938; bh=HVPMf/5mXvzSCEvD4zvkzcVPdKbvcttIl1AaXZE1Iws=; h=From:To:Subject:Date:In-Reply-To:References:From; b=xEZSz/JXe5+IV/tTq8Yaz+0bTABylMNW5cG/+EM1vE+i67oKARsPzxLaeP3Zwd0gb dRyaqfTLbmxjv5xi3QnSuXNdH47WSFaK52PaV2bVpyjY+j06g1JTvQcW2W3MfPupxU GJ2xa9KQ3XXpylZaXH8u0EmEpGX5ajvez2KEU/wE= From: "jeevitha 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: Fri, 17 May 2024 14:08:57 +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: jeevitha 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: 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 --- Comment #7 from Jeevitha P. --- This test case fails with glibc built using the following configuration: configure --enable-debug --with-cpu=3Dpower8 --prefix=3D/usr High-Level Information: The issue lies in the callee-saved registers, which are not properly restor= ed by `__unwind_resume` from `libgcc_s.so.1`. Test Case Flow:[Skipped integer cases since we don't have issues there] In this test case, the `threadfunc` function calls `call_pthread_exit` under certain conditions, which eventually calls `pthread_exit`. 1. A thread is created and it calls `threadfunc` with an initial structure containing five values. 2. In threadfunc, the `checker` constructor is called five times to set th= ose initial values. 3. Based on a condition, either `call_pthread_exit` or `pthread_exit` is called. The failure occurs when `call_pthread_exit` is called. 4. `call_pthread_exit` creates a new structure with five new values and pa= sses it to `call_pthread_exit_1` where the `checker` is constructor called again five more times with these new values.=20 5. `pthread_exit` is then called, which tries to destroy the objects creat= ed by this thread. Since the thread called the `checker` constructor ten times= , it will call the corresponding destructor ten times to destroy them: First, it destroys the five objects in call_pthread_exit_1. Then, it destroys the five objects in threadfunc. 6. The destructors check that the values passed during the function calls matches the original struct values. Assembly Perspective: 1. In `threadfunc`, the structure values are stored in vector registers (vs59-vs63) during the constructor calls. 2. When `call_pthread_exit_1` is called, the callee-saved registers (v27-v= 31), which overlap with (vs59-vs63), are saved in the stack. Then the same regis= ters (vs59-vs63) are then used to load the new structure values during the constructor calls in `call_pthread_exit_1`. 4. After that, `pthread_exit` is called, which invokes the destructor.=20 5. After all destructors are called in `call_pthread_exit_1`, `__unwind_resume` is called to unwind the stack to restore the callee-saved registers. However, `__unwind_resume` does not restore the vector registers= , so they do not have the original values which was set in `threadfunc`. 6. When the destructors for the checker objects in `threadfunc` are called, the values are overridden because of the same register usage in `call_pthread_exit_1`. The checker destructor fails because the values do n= ot match. If we disable vector instruction generation using -mno-vsx for the test cas= e, the issue does not occur. This is because the floating point registers, used instead of vector registers, which are properly restored after the destruct= or in `__unwind_resume`. Backtrace for `_Unwind_resume` call from glibc, gdb) bt #2 0x00007ffff7b7132c in ._Unwind_Resume () from /lib/powerpc64-linux-gnu/libgcc_s.so.1 #3 0x00007ffff7f324c4 in ?? ()//call_pthread_exit_1 #4 0x00007ffff7f32558 in ?? () #5 0x00007ffff7f325e4 in ?? () #6 0x00007ffff79bc958 in start_thread (arg=3D0x7ffff784f100) at pthread_create.c:447 #7 0x00007ffff7a55dcc in .LY__clone3 () at ../sysdeps/unix/sysv/linux/powerpc/powerpc64/clone3.S:114 --=20 You are receiving this mail because: You are on the CC list for the bug.=