Project

General

Profile

Actions

Bug #12768

closed

12392 regressed ftello64 behavior

Added by Robert Mustacchi about 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
High
Category:
lib - userland libraries
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

In 12392 I refactored a bit of the way that the ftell code was implemented to try and centralize that. Unfortunately, while doing this a cast was left behind with the old return type. This resulted in truncation of the return value from the off64_t to a long. While in the 32-bit and 64-bit environments the types are the same; however, in lf64 environment that's no longer the case. An example that generates this is:

#include <stdio.h>
#include <err.h>

int
main(int argc, const char *argv[])
{
        FILE *f;
        off_t o;

        if (argc != 2) {
                (void) fprintf(stderr, "give me a path\n");
                return (1);
        }

        f = fopen(argv[1], "r+");
        if (f == NULL) {
                err(1, "failed to open %s\n", argv[1]);
        }

        if (fseeko(f, 0, SEEK_END) != 0) {
                err(1, "failed to see to end\n");
        }

        o = ftello(f);
        if (o == -1) {
                warn("ftell failed");
        } else {
                printf("ftell returned %llx\n", (long long)o);
        }

        return (0);
}

If compiled with lfs flags and run against a sparse file, you'll see that we get the wrong behavior:

rm@beowulf:~/ftell$ ./ftell.lfs ftell.3g
ftell returned ffffffffc0000000
rm@beowulf:~/ftell$ ./ftell.lfs ftell.5g 
ftell returned 40000000

Instead if you run this with a 64-bit file or with the fixed libc you'll see:

rm@beowulf:~/ftell$ ./ftell.lfs ./ftell.3g 
ftell returned c0000000
rm@beowulf:~/ftell$ ./ftell.lfs ./ftell.5g 
ftell returned 140000000

Related issues

Related to illumos gate - Bug #12392: ftello64 doesn't handle ungetc() correctly when unbufferedClosedRobert Mustacchi

Actions
Actions #1

Updated by Robert Mustacchi about 1 year ago

  • Related to Bug #12392: ftello64 doesn't handle ungetc() correctly when unbuffered added
Actions #2

Updated by Robert Mustacchi about 1 year ago

To test this I wrote some additional regression tests and reran the libc test suite:

rm@beowulf:/opt/libc-tests$ pfexec ./bin/libctest 
Test: /opt/libc-tests/tests/aligned_alloc.32 (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/aligned_alloc.64 (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/c11_threads.32 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/c11_threads.64 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/c11_tss.32 (run as root)              [00:00] [PASS]
Test: /opt/libc-tests/tests/c11_tss.64 (run as root)              [00:00] [PASS]
Test: /opt/libc-tests/tests/call_once.32 (run as root)            [00:00] [PASS]
Test: /opt/libc-tests/tests/call_once.64 (run as root)            [00:00] [PASS]
Test: /opt/libc-tests/tests/catopen (run as root)                 [00:00] [PASS]
Test: /opt/libc-tests/tests/endian.32 (run as root)               [00:00] [PASS]
Test: /opt/libc-tests/tests/endian.64 (run as root)               [00:00] [PASS]
Test: /opt/libc-tests/tests/env-7076.32 (run as root)             [00:00] [PASS]
Test: /opt/libc-tests/tests/env-7076.64 (run as root)             [00:00] [PASS]
Test: /opt/libc-tests/tests/fnmatch.32 (run as root)              [00:00] [PASS]
Test: /opt/libc-tests/tests/fnmatch.64 (run as root)              [00:00] [PASS]
Test: /opt/libc-tests/tests/fpround_test (run as root)            [00:00] [PASS]
Test: /opt/libc-tests/tests/memset_s.32 (run as root)             [00:00] [PASS]
Test: /opt/libc-tests/tests/memset_s.64 (run as root)             [00:00] [PASS]
Test: /opt/libc-tests/tests/newlocale_test (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/nl_langinfo_test (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/posix_memalign.32 (run as root)       [00:00] [PASS]
Test: /opt/libc-tests/tests/posix_memalign.64 (run as root)       [00:00] [PASS]
Test: /opt/libc-tests/tests/printf-6961.64 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/printf-9511.32 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/printf-9511.64 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/priv_gettext (run as root)            [00:00] [PASS]
Test: /opt/libc-tests/tests/psignal (run as root)                 [00:00] [PASS]
Test: /opt/libc-tests/tests/pthread_attr_get_np (run as root)     [00:00] [PASS]
Test: /opt/libc-tests/tests/quick_exit (run as root)              [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4key.ksh (run as root)      [00:01] [PASS]
Test: /opt/libc-tests/tests/random/arc4random (run as root)       [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4random_fork (run as root)  [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4random_forkall (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4random_forksig (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4random_prefork (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4random_preforkall (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/random/arc4random_preforksig (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/random/chacha (run as root)           [00:00] [PASS]
Test: /opt/libc-tests/tests/random/getentropy (run as root)       [00:00] [PASS]
Test: /opt/libc-tests/tests/random/getrandom (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_child (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_inval (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_mlock (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_region (run as root)       [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_split (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_split_vpp (run as root)    [00:00] [PASS]
Test: /opt/libc-tests/tests/random/inz_vpp (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/regex/regex_test (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/select/select.sh (run as root)        [00:08] [PASS]
Test: /opt/libc-tests/tests/set_constraint_handler_s.32 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/set_constraint_handler_s.64 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/fileno.32 (run as root)         [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/fileno.64 (run as root)         [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/fmemopentest.32 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/fmemopentest.64 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/ftell_ungetc.32 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/ftell_ungetc.64 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/ftello_12768.64 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/ftello_12768.lfs (run as root)  [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/memstream.32 (run as root)      [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/memstream.64 (run as root)      [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/memstream_reopen.32 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/memstream_reopen.64 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/open_memstreamtest.32 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/open_memstreamtest.64 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/orientation_test.32 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/orientation_test.64 (run as root) [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/test_mbrtowc.32 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/stdio/test_mbrtowc.64 (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/strcoll-strxfrm-6907.32 (run as root) [00:01] [PASS]
Test: /opt/libc-tests/tests/strcoll-strxfrm-6907.64 (run as root) [00:01] [PASS]
Test: /opt/libc-tests/tests/strerror (run as root)                [00:00] [PASS]
Test: /opt/libc-tests/tests/thread_name (run as root)             [00:00] [PASS]
Test: /opt/libc-tests/tests/timespec_get.32 (run as root)         [00:00] [PASS]
Test: /opt/libc-tests/tests/timespec_get.64 (run as root)         [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsncasecmp-7344.32 (run as root)     [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsncasecmp-7344.64 (run as root)     [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsncasecmp-7350.32 (run as root)     [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsncasecmp-7350.64 (run as root)     [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsncasecmp.32 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsncasecmp.64 (run as root)          [00:00] [PASS]
Test: /opt/libc-tests/tests/wcsrtombs_test (run as root)          [00:01] [PASS]
Test: /opt/libc-tests/tests/wctype_test (run as root)             [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/setup (run as root)           [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/assert_h (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/ctype_h (run as root)         [00:22] [PASS]
3Test: /opt/libc-tests/tests/symbols/dirent_h (run as root)        [00:05] [PASS]
Test: /opt/libc-tests/tests/symbols/fcntl_h (run as root)         [00:14] [PASS]
Test: /opt/libc-tests/tests/symbols/locale_h (run as root)        [00:10] [PASS]
Test: /opt/libc-tests/tests/symbols/math_h (run as root)          [00:03] [PASS]
Test: /opt/libc-tests/tests/symbols/netdb_h (run as root)         [00:01] [PASS]
Test: /opt/libc-tests/tests/symbols/pthread_h (run as root)       [00:03] [PASS]
Test: /opt/libc-tests/tests/symbols/signal_h (run as root)        [00:01] [PASS]
Test: /opt/libc-tests/tests/symbols/stdalign_h (run as root)      [00:01] [PASS]
Test: /opt/libc-tests/tests/symbols/stddef_h (run as root)        [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/stdio_h (run as root)         [00:13] [PASS]
Test: /opt/libc-tests/tests/symbols/stdlib_h (run as root)        [00:11] [PASS]
Test: /opt/libc-tests/tests/symbols/stdnoreturn_h (run as root)   [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/string_h (run as root)        [00:01] [PASS]
Test: /opt/libc-tests/tests/symbols/strings_h (run as root)       [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/sys_stat_h (run as root)      [00:07] [PASS]
Test: /opt/libc-tests/tests/symbols/sys_time_h (run as root)      [00:01] [PASS]
Test: /opt/libc-tests/tests/symbols/sys_timeb_h (run as root)     [00:00] [PASS]
Test: /opt/libc-tests/tests/symbols/time_h (run as root)          [00:01] [PASS]
Test: /opt/libc-tests/tests/symbols/threads_h (run as root)       [00:22] [PASS]
Test: /opt/libc-tests/tests/symbols/ucontext_h (run as root)      [00:02] [PASS]
Test: /opt/libc-tests/tests/symbols/unistd_h (run as root)        [00:19] [PASS]
Test: /opt/libc-tests/tests/symbols/wchar_h (run as root)         [00:09] [PASS]
Test: /opt/libc-tests/tests/symbols/wctype_h (run as root)        [00:23] [PASS]

Results Summary
PASS     109

Running Time:   00:03:20
Percent passed: 100.0%

On bits without the fix, the regression tests failed as we'd expect:

$ ./ftello_12768.lfs 
ftello_12768.lfs: TEST FAILED: stream position mismatch: expected 3221225472, found -1073741824
ftello_12768.lfs: TEST FAILED: stream position mismatch: expected 8589956146, found 21554
Actions #3

Updated by Electric Monk about 1 year ago

  • Status changed from New to Closed
  • % Done changed from 90 to 100

git commit cf3ec608f736765ec9852eed5e611848a25de9a4

commit  cf3ec608f736765ec9852eed5e611848a25de9a4
Author: Robert Mustacchi <rm@fingolfin.org>
Date:   2020-05-22T21:08:20.000Z

    12768 12392 regressed ftello64 behavior
    Reviewed by: Andy Fiddaman <andy@omniosce.org>
    Reviewed by: John Levon <john.levon@joyent.com>
    Reviewed by: Andrew Stormont <andyjstormont@gmail.com>
    Approved by: Dan McDonald <danmcd@joyent.com>

Actions

Also available in: Atom PDF