mmap bug on Windows 9x

2004-07-15 Thread Anton Ertl
On Windows 9x/ME different calls to mmap sometimes produce the same
address (without that memory being unmapped in the meantime, at least
not by application code).  Here's a trace of the application calls to
mmap (on WME):

try mmap($0, $400038, ..., MAP_ANON, ...); success, address=$8395
try mmap($8395, $2cfd0, ..., MAP_FIXED|MAP_FILE, imagefile, 0); failed: Not enough 
core
try mmap($83d52000, $400038, ..., MAP_ANON, ...); success, address=$8395
try mmap($83d52000, $4000, ..., MAP_ANON, ...); success, address=$83d51000
try mmap($83d56000, $4000, ..., MAP_ANON, ...); success, address=$83d55000
try mmap($83d5a000, $3c00, ..., MAP_ANON, ...); success, address=$83d59000
try mmap($83d5e000, $3a00, ..., MAP_ANON, ...); success, address=$83466000
try mmap($8346b000, $4, ..., MAP_ANON, ...); success, address=$83d6
try mmap($83da1000, $4, ..., MAP_ANON, ...); success, address=$83d6

Note that the last two calls produce the same address.  This happens
with cygwin1.dll versions 1.5.5-1 and 1.5.10-3 (and probably also with
1.3.22-1).

On Windows 2000 (with cygwin1.dll 1.3.22) the same application
produces the following trace:

try mmap($0, $400038, ..., MAP_ANON, ...); success, address=$65
try mmap($65, $2cfd0, ..., MAP_FIXED|MAP_FILE, imagefile, 0); failed: Value too 
large for defined data type
try mmap($a52000, $400038, ..., MAP_ANON, ...); success, address=$a6
try mmap($e62000, $4000, ..., MAP_ANON, ...); success, address=$a51000
try mmap($a56000, $4000, ..., MAP_ANON, ...); success, address=$a55000
try mmap($a5a000, $3c00, ..., MAP_ANON, ...); success, address=$a59000
try mmap($a5e000, $3a00, ..., MAP_ANON, ...); success, address=$e61000
try mmap($e66000, $4, ..., MAP_ANON, ...); success, address=$e7
try mmap($eb1000, $4, ..., MAP_ANON, ...); success, address=$eb

and everything works fine.

In this posting I just want to check if the bug is already known.  If
not, I will condense the application to something that exhibits the
bug.  Or, if you feel adventurous, you can deal with the full
application:
http://www.complang.tuwien.ac.at/forth/gforth/gforth-0.6.2.tar.gz
(also available from GNU mirrors); you get the trace output above if
you build gforth with gcc-3.3 and call it with --debug.

Thanks for your work on Cygwin.

- anton

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



Re: mmap bug on Windows 9x

2004-07-16 Thread Anton Ertl
Anton Ertl wrote:
> 
> On Windows 9x/ME different calls to mmap sometimes produce the same
> address (without that memory being unmapped in the meantime, at least
> not by application code).

You find a condensed test program below.

On Windows ME with cygwin1.dll 1.5.10 it outputs:

try mmap($0, $4, ..., MAP_ANON, ...); success, address=$833ca000
try mmap($8340b000, $4, ..., MAP_ANON, ...); success, address=$833ca000

Note that the result addresses are the same.

On Windows 2000 with cygwin1.dll 1.3.22 it outputs:

try mmap($0, $4, ..., MAP_ANON, ...); success, address=$64
try mmap($681000, $4, ..., MAP_ANON, ...); success, address=$68

i.e., non-overlapping memory ranges, as it should.

I believe that this is a problem that both cygwin1.dlls have on
Windows ME/9x (and not on NT/2K/XP), not something arising from the
difference between cygwin versions (we see a problem that probably
arises from this bug also with the Gforth-for-Windows package that
includes cygwin1.dll 1.3.22).

- anton

Here's the test program (compile and run with "gcc -O main.c; ./a):
-
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#ifndef STANDALONE
#include 
#endif
#include 
#include 
#include 
#include 
#ifndef STANDALONE
#include 
#endif

int debug=1;
#define HAVE_MMAP
typedef char *Address;
typedef int Cell;
int pagesize=4096;

static Address next_address=0;
void after_alloc(Address r, Cell size)
{
  if (r != (Address)-1) {
if (debug)
  fprintf(stderr, "success, address=$%lx\n", (long) r);
if (pagesize != 1)
  next_address = (Address)(Cell)r)+size-1)&-pagesize)+2*pagesize); /* leave 
one page unmapped */
  } else {
if (debug)
  fprintf(stderr, "failed: %s\n", strerror(errno));
  }
}

#ifndef MAP_FAILED
#define MAP_FAILED ((Address) -1)
#endif
#ifndef MAP_FILE
# define MAP_FILE 0
#endif
#ifndef MAP_PRIVATE
# define MAP_PRIVATE 0
#endif
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
# define MAP_ANON MAP_ANONYMOUS
#endif

#if defined(HAVE_MMAP)
static Address alloc_mmap(Cell size)
{
  Address r;

#if defined(MAP_ANON)
  if (debug)
fprintf(stderr,"try mmap($%lx, $%lx, ..., MAP_ANON, ...); ", (long)next_address, 
(long)size);
  r = mmap(next_address, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 
-1, 0);
#else /* !defined(MAP_ANON) */
  /* Ultrix (at least) does not define MAP_FILE and MAP_PRIVATE (both are
 apparently defaults) */
  static int dev_zero=-1;

  if (dev_zero == -1)
dev_zero = open("/dev/zero", O_RDONLY);
  if (dev_zero == -1) {
r = MAP_FAILED;
if (debug)
  fprintf(stderr, "open(\"/dev/zero\"...) failed (%s), no mmap; ", 
  strerror(errno));
  } else {
if (debug)
  fprintf(stderr,"try mmap($%lx, $%lx, ..., MAP_FILE, dev_zero, ...); ", 
(long)next_address, (long)size);
r=mmap(next_address, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, 
dev_zero, 0);
  }
#endif /* !defined(MAP_ANON) */
  after_alloc(r, size);
  return r;  
}
#endif

int main(int argc, char **argv, char **env)
{
  debug=1;
  alloc_mmap(0x4);
  alloc_mmap(0x4);
  exit(0);
}

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



Re: mmap bug on Windows 9x

2004-07-16 Thread Corinna Vinschen
On Jul 16 09:12, Anton Ertl wrote:
> Anton Ertl wrote:
> > 
> > On Windows 9x/ME different calls to mmap sometimes produce the same
> > address (without that memory being unmapped in the meantime, at least
> > not by application code).
> 
> You find a condensed test program below.
> 
> On Windows ME with cygwin1.dll 1.5.10 it outputs:
> 
> try mmap($0, $4, ..., MAP_ANON, ...); success, address=$833ca000
> try mmap($8340b000, $4, ..., MAP_ANON, ...); success, address=$833ca000
> 
> Note that the result addresses are the same.

Thanks for the testcase!  Wow, I'm impressed.  Three serious bug reports
in two days which all had a simple testcase(tm) attached! 

*Sob*, I'm moved to tears.

Anyway, I found the cause of that problem.  For some reason (moon phase
or so) the mmap code didn't marked pages as used when running under 9x/Me.
This could only be observed under a specific condition of mmapping
anonymous private pages.

I've applied a fix to the repository.  Should be in the next developers
snapshot from http://cygwin.com/snapshots/


Thanks for the report,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Co-Project Leader  mailto:[EMAIL PROTECTED]
Red Hat, Inc.

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