Question: short-read while loading .so file
ISHIKAWA,chiaki
ishikawa@yk.rim.or.jp
Thu Jun 11 14:44:00 GMT 2015
On 2015/06/10 6:41, Ãngel González wrote:
> On 09/06/15 19:03, ISHIKAWA,chiaki wrote:
>> I asked the following question to binutils mailing list first
>> and was advised to post it to libc-alpha. I misunderstood that dynamic
>> loading was handled by a component of linker.
>> Here it goes. The behavior was observed under Debian GNU/Linux.
> (...)
>> While testing how mozilla thunderbird handles "short read", i.e.,
>> a |read| system call that returns prematurely without returning all the
>> octets (subsequent |read|(s) will return the octets eventually),
>
> (...)
>> BTW, such "short read" can occur with remote file system when there is a
>> network issue, etc. Usually, local file system does not cause "short
>> read", but once we go across the net, anything can happen.)
>
> Note that Linux kernel guarantees that you won't receive a partial read
> for a
> "normal" file (although a custom filesystem could return that, as you
> point out),
> so an application developer might claim that such environment isn't
> supported.
> See http://yarchive.net/comp/linux/wakekill.html#4
>
>
Thank you for your comment.
The link points to a thread that took place in August, 2002.
Today, in 2015, POSIX.1-2008 available at
http://pubs.opengroup.org/onlinepubs/
and man page for |read| specifically,describes a slightly different
semantics.
http://pubs.opengroup.org/onlinepubs/9699919799/
Basically, Single Unix Specification today calls
for old-fashioned BSD-like behavior.
From the above |read| man page: (marking by "***" is mine.)
--- begin quote ---
Earlier versions of this standard allowed two very different behaviors
with regard to the handling of interrupts. In order to minimize the
resulting confusion, it was decided that POSIX.1-2008 should support
only one of these behaviors. Historical practice on AT&T-derived systems
was to have read() and write() return -1 and set errno to [EINTR] when
interrupted after some, but not all, of the data requested had been
transferred. However, the US Department of Commerce FIPS 151-1
and FIPS 151-2 require the historical BSD behavior, in which read() and
*********************************************
write() return the number of bytes actually transferred before the
***********************************************************************
interrupt. If -1 is returned when any data is transferred, it is
***********
difficult to recover from the error on a seekable device and impossible
on a non-seekable device. Most new implementations support this
****************************************
behavior. The behavior required by POSIX.1-2008 is to return the number
************************************************************************
of bytes transferred.
*********************
--- end quote ---
I was thinking of along the line of "the historical BSD behavior, in
which read() and write() return the number of bytes actually transferred
before the interrupt. " and which seems to be supported by modern
implementation and , and thus want to see dynamic loader
re-read the rest of data if short read occurs.
(As a matter of fact, mozilla thunderbird codebase does handle
short-write cases very well. It detects short write and tries to repeat
the write until everything is written.
So I suspect the OSs for which it was developed did show behavior of
POSIX.1-2008 as far as write() is concerned. Short-write occurred there.
It is short-read mozilla thunderbird occasionally mishanldes and that is
why I was testing it
under simulated short-read condition when I noticed dynamic loading
may suffer from similar short-read.
(Yes, I have noticed that Linus specifically mentioned he doesn't care
about POSIX, but even then it was 2002 and he may have a different
opinion today, especially to cope with network file system behavior?
I am not talking about LOCAL kernel interrupting local system call
randomly (most notably read/write calls) which Linus disliked so much,
but here I am talking about read request to the remote file server
returns a short-read result which a local kernel can't do a thing. It
has to return the shorter-than-requested # of octets and errno is NOT
set, I think.)
My analysis of the behavior of dynamic loader (which does not repeat the
read to read the originally requested amount) may
cause problems for a normal program if the dynamically loading
*.so files from a remote file system causes short read occasionally and
dynamic loading mechanism does not repeat the read.
Isn't such dynamic loading handled by a routine in glibc?
(Or is it done inside the kernel???)
Where does glibc get used other other than under linux?
I wonder if this behavior of not repeating short read for *.so file
may cause issues on such systems when remote filesystems are used.
Thank you again.
CI
>
More information about the Libc-help
mailing list