This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients Kuberan.Naganathan, jcea, neologix, pitrou, vstinner
Date 2013-06-06.20:16:31
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1370549792.19.0.904781437057.issue12545@psf.upfronthosting.co.za>
In-reply-to
Content
Oh, I just reproduced the issue on my gdb.py program, which is part of the python-ptrace program. When searching for a pattern in the memory of another process, /proc/pid/maps is used to get the list of all memory mappings of this process. On Linux x64, the last mapping is "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]", machine code used for system calls. gdb.py opens /proc/pid/mem in binary mode and tries to seek at 0xffffffffff600000 but FileIO.seek() fails because it gets an offset bigger than 2^63, which is seen as a negative number and FileIO.seek() considers a negative number as an error.

Attached patch fixes this issue by checking not only the result of lseek(), but also errno:

    errno = 0;
    Py_BEGIN_ALLOW_THREADS
#if defined(MS_WIN64) || defined(MS_WINDOWS)
    res = _lseeki64(fd, pos, how);
#else
    res = lseek(fd, pos, how);
#endif
    Py_END_ALLOW_THREADS
    if (res == (off_t)-1 && errno)
        return posix_error();

PyLong_AsUnsignedLong() is tried if PyLong_AsLong() failed with an OverflowError. I kept PyLong_AsLong() for relative seek with a negative offset, and I prefer to try first PyLong_AsLong() because the overflow case is very unlikely compared to negative offsets for relative seek.

The result is always casted to an unsigned number. I never seen a device or file descriptor supporting negative offset.

I don't know how to test this code path automatically. I only know the "[vsyscall]" mapping use case on Linux, and it requires to parse /proc/self/maps which is not trivial and I would prefer sometimes simpler (more reliable with less maintenance). I propose to not add an unit test, except someone find how to write a simple and reliable test.

> This is not true of a regular file where I get errno=22
> when seeking to an offset greater than or equal to 2^63.

Same behaviour on Linux: OSError(22, "Invalid argument") when I try file.seek(1 << 63) on a regular file.
History
Date User Action Args
2013-06-06 20:16:32vstinnersetrecipients: + vstinner, jcea, pitrou, neologix, Kuberan.Naganathan
2013-06-06 20:16:32vstinnersetmessageid: <1370549792.19.0.904781437057.issue12545@psf.upfronthosting.co.za>
2013-06-06 20:16:32vstinnerlinkissue12545 messages
2013-06-06 20:16:31vstinnercreate