Bug#995393: fakeroot: FTBFS on ppc64el

2021-12-30 Thread Christoph Biedl
Control: reopen 995393
Control: tags 995393 patch

Christoph Biedl wrote...

> As a workaround I propose a tactical __attribute__ to locally disable
> optimization as this issue has been blocking eatmydata for way too long,
> and performance loss should be neglectable.

So as always with a band-aid, it's wiser to address the underlying
problem than to work around it - this time fakeroot broke the glibc
autopkgtest ...

As jtrc27 pointed out in IRC, ppc64el is fairly picky when it comes to
va_arg handling, and next_openat needs a correct "..." parameter in the
prototype to have proper code generated.

As a surprise, it seems the original submitter had that in mind by
introducing a sixth column to wrapfunc.inp, although it's not used by
wrapwak (and not documented either, fix for that included).

My solution isn't nice as it hardcodes the va_arg handling into the
expansion, making it a special for wrapping the openat call. There's
always room for improvement  B=)

Additionally, some headers are not necesarily re-generated - so add
an extra rm call in the clean target to enforce this.

Status: Passes on the porterbox, no compiler warnings/errors from
a prototype mismatch.

Christoph

From d30127a5b2a2f26ae2f6ddc8df077a548ec145e0 Mon Sep 17 00:00:00 2001
From: Christoph Biedl 
Date: Thu, 30 Dec 2021 19:05:37 +0100
Subject: [PATCH] Fix segfault on ppc64el, take 2

---
 debian/patches/fix-prototype-generation.patch | 53 +++
 debian/patches/ppc64el-workaround.patch   | 31 ---
 debian/patches/series |  2 +-
 debian/rules  |  1 +
 4 files changed, 55 insertions(+), 32 deletions(-)
 create mode 100644 debian/patches/fix-prototype-generation.patch
 delete mode 100644 debian/patches/ppc64el-workaround.patch

diff --git a/debian/patches/fix-prototype-generation.patch 
b/debian/patches/fix-prototype-generation.patch
new file mode 100644
index 000..d364c5c
--- /dev/null
+++ b/debian/patches/fix-prototype-generation.patch
@@ -0,0 +1,53 @@
+Subject: Fix prototype generation for openat
+Author: Christoph Biedl 
+Date: 2021-12-30
+Bug-Debian: https://bugs.debian.org/995393
+Forwarded: Yes (implicitely)
+
+As jtrc27 pointed out in IRC, ppc64el is fairly picky when it comes to
+va_arg handling, and next_openat needs a correct "..." parameter in the
+prototype to have proper code generated.
+
+--- a/wrapawk
 b/wrapawk
+@@ -37,7 +37,25 @@
+   argtype=$3;
+   argname=$4;
+   MACRO=$5;
+-  if(MACRO){
++  openat_extra=$6;
++  if(openat_extra){
++print "  {(void(*))_" name ", \"" name "\"},"  > structfile;
++print "extern " ret " (*next_" name ")" openat_extra ";" > headerfile;
++print ret " (*next_" name ")" openat_extra "=tmp_" name ";"> deffile;
++
++print ret " tmp_" name,  openat_extra "{" > tmpffile;
++print " mode_t mode = 0;"> tmpffile;
++print " if (flags & O_CREAT) {"> tmpffile;
++print " va_list args;"> tmpffile;
++print " va_start(args, flags);"> tmpffile;
++print " mode = va_arg(args, int);"> tmpffile;
++print " va_end(args);"> tmpffile;
++print " }"> tmpffile;
++print "  load_library_symbols();"   > tmpffile;
++print "  return  next_" name,  argname ";"   > tmpffile;
++print "}"   > tmpffile;
++print ""> tmpffile;
++  } else if(MACRO){
+ print "  {(void(*))_" MACRO "_NOARG, " name "_QUOTE},"  > structfile;
+ print "extern " ret " (*NEXT_" MACRO "_NOARG)" argtype ";" > headerfile;
+ print ret " (*NEXT_" MACRO "_NOARG)" argtype "=TMP_" MACRO ";"> deffile;
+--- a/wrapfunc.inp
 b/wrapfunc.inp
+@@ -9,8 +9,10 @@
+ /**/*/
+ /* each line of this file lists 4 fields, seperated by a ";".   */
+ /* The first field is the name of the wrapped function, then it's return  */
+-/* value. After that come the function arguments with types, and the last */
++/* value. After that come the function arguments with types, and the fifth */
+ /* field contains the function arguments without types.   */
++/* A sixth field is a special needed when wrapping the openat syscall.*/
++/* Otherwise it's like the third (function arguments with types). */
+ /**/
+ 
+ /* __*xstat are used on glibc systems instead of just *xstat. */
diff --git a/debian/patches/ppc64el-workaround.patch 
b/debian/patches/ppc64el-workaround.patch
deleted file mode 100644
index 95b0ff0..000
--- a/debian/patches/ppc64el-workaround.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Subject: Work around segfault on ppc64el
-Author: Christoph Biedl 
-Date: 2021-12-20
-Bug-Debian: https://bugs.debian.org/995393
-Forwarded: Yes
-
-For whatever reason the generated code segfaults on ppc64el when
-built with 

Bug#995393: fakeroot: FTBFS on ppc64el

2021-12-22 Thread Christoph Biedl
Control: tags 995393 patch

Frédéric Bonnard wrote...

>  #ifdef HAVE_OPENAT
> +#if defined(__powerpc__) && defined(__powerpc64__) && __BYTE_ORDER__ == 
> __ORDER_LITTLE_ENDIAN__
> +static int openat(int dir_fd, const char *pathname, int flags, ...)
> +#else
>  int openat(int dir_fd, const char *pathname, int flags, ...)
> +#endif

Well, that makes openat a private function - the idea however is to
provide a publicly visible function. Also, if I read the objdump output
correctly, the compiler will happily inline the function then as there
is just one usage.

> Hoping you'll get more ideas on this

After digging into this for quite a few hours, this really smells like a
bug in the optimizer but I'm not keen on spending a lot of time on a
reproducer and taking it to gcc upstream.

As a workaround I propose a tactical __attribute__ to locally disable
optimization as this issue has been blocking eatmydata for way too long,
and performance loss should be neglectable.

Status: Works on the porterbox.

Cheers,

Christoph

 #ifdef HAVE_OPENAT
-int openat(int dir_fd, const char *pathname, int flags, ...)
+int
+#if HAVE_OPENAT && defined(__powerpc__) && defined(__powerpc64__) && 
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+__attribute__((optimize("O0")))
+#endif
+openat(int dir_fd, const char *pathname, int flags, ...)


signature.asc
Description: PGP signature


Bug#995393: fakeroot: FTBFS on ppc64el

2021-11-07 Thread Clint Adams
On Thu, Sep 30, 2021 at 04:46:47PM +0200, Frédéric Bonnard wrote:
> Not sure what optimization breaks, I just tried changing openat() to
> modify some aggressive optimization on that function and it helped.

The optimization seems to break with -O1, but not with
-O0 -fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fdefer-pop 
-fforward-propagate -fguess-branch-probability -fipa-profile -fipa-pure-const 
-fipa-reference -fipa-reference-addressable -fmerge-constants 
-fomit-frame-pointer -freorder-blocks -fshrink-wrap -fsplit-wide-types 
-ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-coalesce-vars 
-ftree-copy-prop -ftree-dce -ftree-dominator-opts -ftree-fre -ftree-sink 
-ftree-slsr -ftree-ter -fbranch-count-reg -fdelayed-branch -fdse 
-fif-conversion -fif-conversion2 -finline-functions-called-once 
-fmove-loop-invariants -fssa-phiopt -fipa-modref -ftree-bit-ccp -ftree-dse 
-ftree-pta -ftree-sra

It also seems fine at -O2 if fprintf(stderr, "%i, %s, %x\n", dir_fd, pathname, 
flags);
is called prior to next_openat.



Bug#995393: fakeroot: FTBFS on ppc64el

2021-09-30 Thread Frédéric Bonnard
Package: src:fakeroot
Version: 1.26-1
Control: tags -1 ftbfs

--

Dear maintainer,
fakeroot fails to build on ppc64el since 1.26-1
https://buildd.debian.org/status/fetch.php?pkg=fakeroot=ppc64el=1.26-1=1630982822=0

Backtrace from the core file :
---
Core was generated by `chown -R daemon:sys 2 '.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x05e13c212284 in 001b.plt_call.fdopendir@@GLIBC_2.17 ()
(gdb) bt
#0  0x05e13c212284 in 001b.plt_call.fdopendir@@GLIBC_2.17 ()
#1  0x05e13c220fd4 in opendirat (dir_fd=-100, dir=0x5e13fb347b0 "2", 
extra_flags=32768, pnew_fd=0x7fffc6e5cab0) at lib/opendirat.c:44
#2  0x05e13c21cb74 in fts_build (sp=0x5e13fb33ce0, type=3) at lib/fts.c:1340
#3  0x05e13c21be60 in rpl_fts_read (sp=0x5e13fb33ce0) at lib/fts.c:940
#4  0x05e13c214ca0 in chown_files (files=0x7fffc6e5d210, bit_flags=1040, 
uid=1, gid=3, required_uid=4294967295, required_gid=4294967295, 
chopt=0x7fffc6e5cd00) at src/chown-core.c:531
#5  0x05e13c21349c in main (argc=4, argv=0x7fffc6e5d1f8) at src/chown.c:324
---

Bisecting the code I ended up with this commit : 
https://salsa.debian.org/clint/fakeroot/-/commit/f5e0a89ab6f0024f3d3bec5fd9cf631676b44f6c
from which things start to fail.
Especially the openat() function.
What I noticed also is that lowering optimization to O0 makes the test
work.

Simple way to reproduce is on directories : 
---
mkdir bla
LD_PRELOAD=./obj-sysv/.libs/libfakeroot-0.so /bin/rm -fr bla
---
Each time fdopendir seg fault with the fd coming from openat right
before.

Not sure what optimization breaks, I just tried changing openat() to
modify some aggressive optimization on that function and it helped.

---
--- a/libfakeroot.c
+++ b/libfakeroot.c
@@ -2596,7 +2596,11 @@
 #endif
 
 #ifdef HAVE_OPENAT
+#if defined(__powerpc__) && defined(__powerpc64__) && __BYTE_ORDER__ == 
__ORDER_LITTLE_ENDIAN__
+static int openat(int dir_fd, const char *pathname, int flags, ...)
+#else
 int openat(int dir_fd, const char *pathname, int flags, ...)
+#endif
 {
mode_t mode;
---

Hoping you'll get more ideas on this


Regards,


F.


signature.asc
Description: PGP signature