public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Stanislav Kascak <stanislav.kascak@gmail.com>
To: cygwin@cygwin.com, Stanislav Kascak <stanislav.kascak@gmail.com>
Subject: Re: possible problem with memory allocation using calloc/mmap/munmap
Date: Tue, 04 Jun 2019 13:49:00 -0000	[thread overview]
Message-ID: <CALLhcm4sHGmFwki+RuUOUA-GfnXzmOUX4Tr8Es-=291Bo+A4dg@mail.gmail.com> (raw)
In-Reply-To: <20190604131836.GS3437@calimero.vinschen.de>

> > > > It seems that when mmap() is called with length argument exceeding
> > > > size of file, only memory to fit that file is allocated. munmap()
> > > > however frees the full specified length. Since (at least on my
> > > > computer) big chunk of memory allocated by calloc() is located after
> > > > mmap() allocation, munmap() frees even memory of that calloc().
> > >
> > > Ken's right.  Due to the differences between mapping files on Windows
> > > vs. Unix, Cygwin can't map beyond the file size + the remainder of the
> > > last page.  Cygwin tries to workaround that on 32 bit by allocating
> > > an anonymous mapping following the file mapping to keep the range free
> > > from other mappings.  But on 64 bit this workaround doesn't work anymore
> > > because the OS is missing an (undocumented) flag which allows to
> > > create mappings on 4K boundaries, rather than just on 64K boundaries.
> > >
> > > I know this situation is unsatisfying, but I have no easy workaround
> > > to allow this.  Cygwin could add the anonymous mapping on the next
> > > 64K boundary on 64 bit, but that would result in a hole in the mapping
> > > which seemed like a rather bad idea when porting mmap to 64 bit.
> > >
> > > Ken's also right that munmap is doing the right thing here.  If
> > > anything's wrong, it's mmap's workaround for mappings beyond the file
> > > length.  If only 64 bit would allow 4K-aligned mappings :(
> >
> > Thanks for the answer. It is appreciated.
> > I understand the problem and difficulty to resolve it. Maybe returning
> > an error from mmap (and putting a comment to code for its reason)
> > would be sufficient. mmap caller could just adjust requested
> > allocation size to file size. Without error, caller has no way of
> > knowing memory was not allocated and segfault is then thrown in an
> > unrelated memory segment which makes the root cause hard to track
> > down. But, I do not know all the implication that could result from
> > that, so evaluation of this approach is up to you.
>
> Given that most of the required code already exists for 32 bit systems
> (except under WOW64, suffering the same problem as the 64 bit WIndows
> environment), I hacked a bit on this code this morning and I got your
> testcase running fine.  The idea being that after a successful mmap the
> expectation that a matching munmap does *not* unmap unrelated mappings
> is valid.
>
> In more depth, here's what Cygwin does on 32 bit, assuming a file size
> of 100 bytes and a mapping request of 256K:
>
> First Cygwin mmaps the file.  This results in a 4K mapping in Windows:
>
>  file:    |-- 100b --|
>
>  mapping: |-- 4K --....--|
>
> Next Cygwin adds another mapping to fill up the range up to the next
> 64K allocation granularity boundary:
>
>  |-- file 4K --|-- filler 60K --|
>
> Eventually Cygwin adds another mapping to fullfill the entire mapping
> request:
>
>  |-- file 4K --|-- filler 60K --|-- filler 192K --|
>
> The problem on WOW64 and real 64 bit is that it's impossible to map
> the first filler.  However, this area in the VM will *never* be
> allocated by other application functions due to the allocation
> granularity of 64K!
>
> So my workaround for 64 bit and WOW64 is to just skip allocating the
> first filler:
>
>  |-- file 4K --|-- THE VOID 60K --|-- filler 192K --|
>
> The advantage is now that the following munmap of 256K will only
> unmap the map for the file and the filler, but not the region you
> calloced before, which formerly was accidentally mapped to the
> filler region.  This just can't happen anymore now.
>
> Would that be feasible?  If so I can push my patch and create a
> developer snapshot for testing.

Two questions arise when I'm thinking about workaround solution:
- what happens if caller tries to write to |-- THE VOID 60K --|. Since
this is unallocated, would there be a segfault?
- is it possible that some subsequent mem alloc request would return
region from |-- THE VOID 60K --| which could again cause segfault
after munmap?

Stanislav Kascak

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

  reply	other threads:[~2019-06-04 13:49 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-03 11:33 Stanislav Kascak
2019-05-20 22:26 ` Ken Brown
2019-06-03 11:55 ` Corinna Vinschen
2019-06-04  9:38   ` Stanislav Kascak
2019-06-04 13:18     ` Corinna Vinschen
2019-06-04 13:49       ` Stanislav Kascak [this message]
2019-06-04 14:49         ` Corinna Vinschen
2019-06-04 16:02           ` Stanislav Kascak
2019-06-05 18:23             ` Corinna Vinschen
2019-06-06 13:14               ` Stanislav Kascak
2019-06-07  7:27                 ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CALLhcm4sHGmFwki+RuUOUA-GfnXzmOUX4Tr8Es-=291Bo+A4dg@mail.gmail.com' \
    --to=stanislav.kascak@gmail.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).