Live data from Hacker News

Use mmap with care

sublimetext.com

91–100 of 218 posts

Re: Use mmap with care

#91
post #84

Honestly, this reads like a thorough indictment of signals in user space. * Signal handlers are process global * Signal handlers need to be re-entrant safe Re-entrancy is painful but can be done, but process-global signal handlers means that pulling in a totally unrelated library can break your code. Moreover, it makes the combined use of certain libraries straight-up impossible. Similarly, it means that the use of l…

Normal libraries should never register signal handlers. Google Breakpad is a crash-reporting system and as such requires signal handling to function.

Also since we're on the topic, here's a nice vulnerability caused by bad signal handling: https://news.ycombinator.com/item?id=16753013

Pretty sure there are no plans to replace signals, but maybe there are libraries that make signal handling easier?

Re: Use mmap with care

#92
It would be really nice if there was a POSIX equivalent to Foundation's NSDataReadingMappedIfSafe, which uses mmap() when the file isn't backed by NFS and falls back to read() when unsafe or not worth it.

Re: Use mmap with care

#93
post #20

Earlier quoted context omitted.

Alternatively one can run a separated process that does mmap and runs the calculations or whatever that needs to access the file as quickly as possible and do the the straightforward recovery in the parent process when the child process dies. The drawback is the need to some form of RPC, but there a lot of libraries to do that without much hustle.

If you are already copying things around (between address spaces even), you might as well just use pread or lseek+read, which at that point is likely a much better choice overall.

Couldn’t you mmap a shared, read-only page so that your OS doesn’t copy it?

Re: Use mmap with care

#94
post #87

Earlier quoted context omitted.

> Anonymous mappings are backed by swap and may be overcommitted, it's still possible to catch signals in a wide variety of circumstances Anonymous mappings won't cause signals, they'll trigger the OOM killer. Remember that malloc() is just a fancy wrapper for mmap() (and sbrk()).

If a process was swapped out and a fault fails to bring a page back due to an IO error, you can at least catch (I think) SIGBUS. But this just reinforces the point: nobody really understands virtual memory, even people like us that think they do

Okay, but I'd say the correct thing to do is let SIGBUS kill the process. You can at least expect to handle SIGBUS for a file you've mapped.

Re: Use mmap with care

#96
post #86
post #62

Now I'm curious how Vim deals with large files. I'm assuming the went the pread route.

Vim needs to do a lot more special stuff, because it has to handle random insertions and deletions. Doing those things to a file (mmaped or otherwise) requires moving all data after the edit. If I recall correctly, vim/vi uses a linked list of 'chunks' that is dynamically merged. For long files I would expect some form of lazy loading of chunks.

That's right. The key data structure is the rope: https://en.wikipedia.org/wiki/Rope_(data_structure)

Re: Use mmap with care

#97
post #90
post #87

Earlier quoted context omitted.

If a process was swapped out and a fault fails to bring a page back due to an IO error, you can at least catch (I think) SIGBUS. But this just reinforces the point: nobody really understands virtual memory, even people like us that think they do

So should we extend your conclusion above to the following? "There is probably enough evidence in this thread to use it as a reference for why typical apps should avoid virtual memory whenever possible -- it's clear almost nobody fully understands it" I'd suggest that is ludicrous, and for the same reason your original conclusion is also excessive.

It is not constructive to form a sweeping generalization from a statement and then claim the sweeping generalization is ludicrous, implying the original statement is ludicrous. :)

My first comment was in reply to one claiming anonymous memory did not have the same problems as file-backed memory, indicating the parent did not understand they are the same thing. The subsequent reply was to another comment continuing to claim anonymous memory was somehow safer, both instances supporting the notion that most people in this thread don't seem to understand mmap at all.

What we're examining is a powerful (and consequently hazardous) OS feature that often provides only marginal performance improvement, yet introduces many exotic error paths into a program that have their own exotic problems (memory access in thread A can raise SEGV in thread B, async-signal safety), that 7 hours' commenting has not been sufficient to fully capture. This thread is full of upvoted miscomprehension, bad advice (spawn a child to deal with SEGV!?), obviously incorrect solutions (signalfd), and yet still manages to completely omit some critical characteristics of mmap, for example, that faults take a VM-global semaphore -- mmap can easily destroy multithreaded app performance in a way read() is immune to, because nobody expects file IO in one thread to cause malloc() latency in another.

If this isn't evidence for "avoid this feature wherever possible", I really don't know what is.

Re: Use mmap with care

#98

The mistake here is using longjmp / siglongjmp. This is a possible way to handle SIGBUS, but in practice it will be intractable in larger programs written in C or C++. The compiler is generally free to move loads and stores around, and you might be completely blindsided by how the compiler has reordered your memory operations once you add side effects to one of the operations. Theoretically, if accessing a memory loc…

This sounds interesting. Do you know of an example that does this?

So if I have multiple threads reading the same mmap'd file, I use si_addr in the signal handler to know which page to call MAP_FIXED on?

Re: Use mmap with care

#99
post #92

It would be really nice if there was a POSIX equivalent to Foundation's NSDataReadingMappedIfSafe, which uses mmap() when the file isn't backed by NFS and falls back to read() when unsafe or not worth it.

Is there a way for a process to know what kind of filesystem something lives on, or is this just a developer-provided clue?

Re: Use mmap with care

#100
post #3

Earlier quoted context omitted.

Did you consider emulating mmap yourselves? "Memory mapped files work by mapping the full file into a virtual address space and then using page faults to determine which chunks to load into physical memory. In essence it allows you to access the file as if you had read the whole thing into memory, without actually doing so." I feel like this could be done in c++ directly, by maintaining an internal cache for each fil…

This is essentially how databases like PostgreSQL work, but in essence it only avoids the sys-call overhead. The OS is already caching the file, regardless of mmap, so using pread would have likely been enough for us. It totally would have been simpler overall, but each incremental step we made was significantly less work than the refactoring required for pread.

It totally would have been simpler overall, but each incremental step we made was significantly less work than the refactoring required for pread.

Question.

In 10 years will you be saying this about the next incremental problem that you run into? If you think this likely, then the next incremental problem is an excuse to do it right.

Post reply on HN