[PATCH] fix build on systems that do not implement statfs64

Adrien Kunysz adrien at kunysz.be
Mon Mar 29 12:11:19 UTC 2010


On Mon, Mar 29, 2010 at 04:55:23AM +0400, Dmitry V. Levin wrote:
> On Sun, Mar 28, 2010 at 06:01:47PM +0100, Adrien Kunysz wrote:
> > Commit 9906e6da8be98d27bffa2baeeccd40cf1a1b11c1 "Fix handling of Linux
> > systems without struct statfs64" breaks the build on my system (on which
> > the autoconf macros cannot find statfs64 but I believe that is another
> > problem).
> > 
> > gcc -Wall -g -O2   -o strace strace.o syscall.o count.o util.o desc.o
> > file.o ipc.o io.o ioctl.o mem.o net.o process.o bjm.o quota.o resource.o
> > signal.o sock.o system.o term.o time.o proc.o scsi.o stream.o
> > syscall.o:(.rodata+0x4a88): undefined reference to `sys_statfs64'
> > syscall.o:(.rodata+0x4aa8): undefined reference to `sys_fstatfs64'
> > 
> > This patch allows me to complete the build (not sure whether tab or
> > space is best after the define as the file has a mix of both).
> 
> Such a change is not fail-safe: if configure check failed to recognize
> struct statfs64 on an architecture where sys_statfs64 is known to exist,
> then the proposed printargs fallback would just result to degraded
> statfs64 parser.

OK, so how do we safely fix the build for platforms without statfs64?

> I wonder why the autoconf test fails to find struct statfs64 on your
> system.

Initially it was because I didn't have -D__USE_LARGEFILE64 in the
CFLAGS. But even after using it, it fails to build. However the problem
seems to actually be with the AC_STAT64 macro:

$ make distclean ; autoconf ; CFLAGS='-D__USE_LARGEFILE64' ./configure &&
make
[...]
gcc -Wall -D__USE_LARGEFILE64   -o strace strace.o syscall.o count.o
util.o desc.o file.o ipc.o io.o ioctl.o mem.o net.o process.o bjm.o
quota.o resource.o signal.o sock.o system.o term.o time.o proc.o scsi.o
stream.o  
syscall.o:(.rodata+0x5668): undefined reference to `sys_statfs64'
syscall.o:(.rodata+0x5688): undefined reference to `sys_fstatfs64'
[...]
$ less config.log
[...]
configure:5973: checking for stat64 in (asm|sys)/stat.h
configure:6005: gcc -c -D__USE_LARGEFILE64  conftest.c >&5
conftest.c: In function 'main':
conftest.c:39: error: storage size of 'st' isn't known
configure:6011: $? = 1
configure: failed program was:
| /* confdefs.h.  */
| #define PACKAGE_NAME "strace"
| #define PACKAGE_TARNAME "strace"
| #define PACKAGE_VERSION "4.5.19"
| #define PACKAGE_STRING "strace 4.5.19"
| #define PACKAGE_BUGREPORT ""
| #define PACKAGE "strace"
| #define VERSION "4.5.19"
| #define LINUX 1
| #define X86_64 1
| #define _GNU_SOURCE 1
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define HAVE__BOOL 1
| #define HAVE_STDBOOL_H 1
| #define HAVE_DIRENT_H 1
| #define HAVE_STRUCT_STAT_ST_BLKSIZE 1
| #define HAVE_STRUCT_STAT_ST_BLOCKS 1
| #define HAVE_STRUCT_STAT_ST_RDEV 1
| /* end confdefs.h.  */
| #include <sys/types.h>
| #ifdef LINUX
| #include <linux/types.h>
| #include <asm/stat.h>
| #else
| #include <sys/stat.h>
| #endif
| int
| main ()
| {
| struct stat64 st;
|   ;
|   return 0;
| }
configure:6027: result: no
configure:6038: checking for statfs64 in sys/vfs.h
configure:6067: gcc -c -D__USE_LARGEFILE64  conftest.c >&5
configure:6073: $? = 0
configure:6089: result: yes
[...]

However, this compiles:
$ cat t.c 
#define _GNU_SOURCE 1

#include <sys/types.h>
#include <sys/stat.h>
int
main ()
{
struct stat64 st;
  ;
  return 0;
}

$ gcc -c -D__USE_LARGEFILE64 t.c

So, if I hack AC_STAT64 like this:

--- a/acinclude.m4
+++ b/acinclude.m4
@@ -197,12 +197,7 @@ AC_DEFUN([AC_STAT64],
 [AC_MSG_CHECKING(for stat64 in (asm|sys)/stat.h)
 AC_CACHE_VAL(ac_cv_type_stat64,
 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-#ifdef LINUX
-#include <linux/types.h>
-#include <asm/stat.h>
-#else
-#include <sys/stat.h>
-#endif]], [[struct stat64
st;]])],[ac_cv_type_stat64=yes],[ac_cv_type_stat64=no])])
+#include <sys/stat.h>]], [[struct stat64
st;]])],[ac_cv_type_stat64=yes],[ac_cv_type_stat64=no])])
 AC_MSG_RESULT($ac_cv_type_stat64)
 if test "$ac_cv_type_stat64" = yes
 then

I get a different error:

$ make distclean ; autoconf ; CFLAGS=-D__USE_LARGEFILE64 ./configure ; make
[...]
gcc -DHAVE_CONFIG_H -I. -Ilinux/x86_64 -I./linux/x86_64 -Ilinux
-I./linux   -Wall -D__USE_LARGEFILE64 -MT file.o -MD -MP -MF
.deps/file.Tpo -c -o file.o file.c
file.c: In function ‘printstat64’:
file.c:1046: error: storage size of ‘statbuf’ isn’t known

But the tests pass:

configure:5973: checking for stat64 in (asm|sys)/stat.h
configure:6000: gcc -c -D__USE_LARGEFILE64  conftest.c >&5
configure:6006: $? = 0
configure:6022: result: yes
configure:6033: checking for statfs64 in sys/vfs.h
configure:6062: gcc -c -D__USE_LARGEFILE64  conftest.c >&5
configure:6068: $? = 0
configure:6084: result: yes

The code is:

1042 #ifdef HAVE_STAT64
1043 static void
1044 printstat64(struct tcb *tcp, long addr)
1045 {
1046         struct stat64 statbuf;

My guess is that the error is caused by file.c including <linux/types.h>
and/or <asm/stat.h> instead of <sys/types.h> and <sys/stat.h> but I
didn't dig deeper. This is Debian Lenny 5.0.4 x86_64 if you want to
know.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20100329/7bbc38e9/attachment.bin>


More information about the Strace-devel mailing list