Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOStream bugs with non-seekable streams #48667

Open
vtjnash opened this issue Feb 13, 2023 · 3 comments
Open

IOStream bugs with non-seekable streams #48667

vtjnash opened this issue Feb 13, 2023 · 3 comments
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:bug Indicates an unexpected problem or unintended behavior

Comments

@vtjnash
Copy link
Sponsor Member

vtjnash commented Feb 13, 2023

There seems to be an implementation quality issue with IOStream, where we attempt to use seekend as a fast-path for filesize, but we should fall back to attempting fstat when that fails.

Additionally, there are some buffering bugs in iostream observed while exploring this object:

julia> fd_mem = SharedArrays.shm_open("test_shared_array$(randstring(10))", Base.JL_O_CREAT | Base.JL_O_RDWR, Base.S_IRUSR | Base.S_IWUSR)
21

julia> s = fdio(fd_mem, true)
IOStream(<fd 21>)

julia> write(s, "hello") # actually, this should have failed, since it returned ENXIO (https://github.com/apple/darwin-xnu/blob/a1babec6b135d1f35b2590a1990af3c5c5393479/bsd/kern/posix_shm.c#L194-L195)
5

julia> read(s, String)
""

julia> seekstart(s)
ERROR: SystemError: seek: Illegal seek

julia> skip(s, -5) # something goes wrong here with the file offset?
ERROR: SystemError: skip: Illegal seek

julia> truncate(s, 1024)
IOStream(<fd 21>)

julia> String(read(s)) # something appears to be wrong here with the filesize?
1025-size String:
"hello\0\0\0C\0\0\0\0\0\0\0\0\x90\x80%\xc4\x7f\0\0<\0\0\0\0\0\0\0\0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0`\xc0\x81%\xc4\x7f\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x80\xa7\xce\x02\0`\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\x99\xce\x02\0`\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0I\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0p\x9e7\x14\x01\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\v\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\v\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\v\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x10\xa2\xb0&\xc4\x7f\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcf"
# this should have been 1024 bytes, and mostly zeros

Originally posted by @vtjnash in #44354 (comment)

Actually, IIUC, this is a very weird file on macOS (from shm_open). I can read and write, but not seek the fd. And stat is a bit awkward, as Julia cannot return it:

julia> Base.StatStruct(stat_buf)
StatStruct for ""
   size: 4096 bytes
 device: 0
  inode: 0
   mode: 0o000600 (-rw-------)
  nlink: 0
    uid: 501 (jameson)
    gid: 20 (staff)
   rdev: 0
  blksz: 0
 blocks: 0
  mtime: 1969-12-31T19:00:00-0500 (19401 days ago)
  ctime: 1969-12-31T19:00:00-0500 (19401 days ago)

julia> stat(s)
ERROR: stat returned zero type for a valid path

implemented here: https://github.com/apple/darwin-xnu/blob/a1babec6b135d1f35b2590a1990af3c5c5393479/bsd/kern/posix_shm.c#L695-L700

Unrelatedly, there appears to be a minor issue in SharedArrays forgetting to close the fd_mem handle in this functions caller.

@vtjnash vtjnash added domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:bug Indicates an unexpected problem or unintended behavior labels Feb 13, 2023
@gbaraldi
Copy link
Member

gbaraldi commented Feb 13, 2023

Does macos have a another implementation of shared memory that works better here? Or do we use this one and work around it's weird behaviour.
Maybe using the System V interface instead?
https://developer.apple.com/forums/thread/719897

System V IPC is a compatibility API an macOS. We recommend against using it in new code. Given that, it shouldn’t come as a big surprise that it doesn’t have a good story regarding the App Sandbox.
If you want to share memory with that style of API, use Posix shared memory (shm_open and friends).

@mkitti
Copy link
Contributor

mkitti commented Apr 23, 2024

Do we have a way of detecting when seekend will work or do try that first, and then fallback to fstat when that fails?

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Apr 23, 2024

Using try is probably faster

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

3 participants