64-bit strace improperly decoding 32-bit apps fcntl()

Thomas, Markham M (WTEC) markham.thomas at hp.com
Wed Nov 19 03:07:08 UTC 2008


Hi,
   I have run into a bug in strace that exists all the way up to the latest CVS copy.  To duplicate it requires a 64-bit strace to attempt to decode a 32-bit application that calls fcntl().  The start= and len= values will be incorrect.
-- incorrect decoding of 32-bit app --
fcntl64(3, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=38714100766736384,len=13033246728}) = 0

-- correct decoding of same app with 32-bit strace (on same 64-bit OS as previous test) --
Fcntl64(3, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0

I have a short sample program that can be strace'd to see the issue.  It needs to be compiled to 32-bit or compiled on a similar (x86 linux) 32-bit system and copied over to the 64-bit Linux system.

To execute:
#touch testfile.txt                       (to create sample lockfile)
#strace -fFTxtt -o test.txt ./myfcntl32   (where myfcntl32 is 32-bit sample application)

Examine test.txt and note: fcntl64(3, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=XXXX_big_number_XXXX, len=YYYY_big_num_YYYY})=0

Where XXXX_big_number_XXXX and YYYY_big_num_YYYY are invalid large values and should be zero.
It appears strace is not properly accounting for it decoding a 32-bit applications arguments. I did some tests under gdb and noted it had the proper personality chosen for 32-bit, but it apparently doesn't use that when looking at the arguments to fcntl.

-- myfcntl.c    (sample code to strace) --
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/cdefs.h>

main(void)
{
        FILE *fileptr;
        int   filedes;
        long offset;
        long length;
        struct flock flockstruct;
        fileptr = fopen("./testfile.txt", "r+");
        if (fileptr == NULL) {
                perror("Unable to fopen file");
                exit(1);
        }
        printf("File exists\n");
        filedes = fileno(fileptr);
        flockstruct.l_type = F_WRLCK;
        flockstruct.l_whence = SEEK_SET;
        flockstruct.l_start = 0;
        flockstruct.l_len = 0;
        if ((fcntl(filedes, F_SETLK, &flockstruct)) == -1) {
                printf("Lock failed!\n");
                exit(-1);
        } else {
                printf("Lock worked\n");
                fclose(fileptr);
        }
}

- Regards,  Markham




More information about the Strace-devel mailing list