* exceptions.cc (_cygtls::handle_exceptions): Call new
mmap_is_attached_or_noreserve_page function in case of access violation and allow application to retry access on noreserve pages. * mmap.cc (mmap_is_attached_or_noreserve_page): Changed from mmap_is_attached_page. Handle also noreserve pages now. Change comment accordingly. * winsup.h (mmap_is_attached_or_noreserve_page): Declare instead of mmap_is_attached_page.
This commit is contained in:
parent
d44b979536
commit
f6105f89d5
@ -1,3 +1,14 @@
|
|||||||
|
2006-07-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* exceptions.cc (_cygtls::handle_exceptions): Call new
|
||||||
|
mmap_is_attached_or_noreserve_page function in case of access violation
|
||||||
|
and allow application to retry access on noreserve pages.
|
||||||
|
* mmap.cc (mmap_is_attached_or_noreserve_page): Changed from
|
||||||
|
mmap_is_attached_page. Handle also noreserve pages now. Change
|
||||||
|
comment accordingly.
|
||||||
|
* winsup.h (mmap_is_attached_or_noreserve_page): Declare instead of
|
||||||
|
mmap_is_attached_page.
|
||||||
|
|
||||||
2006-07-12 Corinna Vinschen <corinna@vinschen.de>
|
2006-07-12 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* mmap.cc (mmap_record::alloc_page_map): Don't call VirtualProtect
|
* mmap.cc (mmap_record::alloc_page_map): Don't call VirtualProtect
|
||||||
|
@ -526,17 +526,21 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATUS_ACCESS_VIOLATION:
|
case STATUS_ACCESS_VIOLATION:
|
||||||
if (mmap_is_attached_page (e->ExceptionInformation[1]))
|
switch (mmap_is_attached_or_noreserve_page (e->ExceptionInformation[1]))
|
||||||
{
|
{
|
||||||
|
case 2: /* MAP_NORESERVE page, now commited. */
|
||||||
|
return 0;
|
||||||
|
case 1: /* MAP_NORESERVE page, commit failed, or
|
||||||
|
access to mmap page beyond EOF. */
|
||||||
si.si_signo = SIGBUS;
|
si.si_signo = SIGBUS;
|
||||||
si.si_code = BUS_OBJERR;
|
si.si_code = BUS_OBJERR;
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
{
|
|
||||||
MEMORY_BASIC_INFORMATION m;
|
MEMORY_BASIC_INFORMATION m;
|
||||||
VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
|
VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
|
||||||
si.si_signo = SIGSEGV;
|
si.si_signo = SIGSEGV;
|
||||||
si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
|
si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -900,13 +900,25 @@ map::del_list (unsigned i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called from exception_handler when a segmentation
|
/* This function is called from exception_handler when a segmentation
|
||||||
violation has happened. The function should return true, if the
|
violation has happened. We have two cases to check here.
|
||||||
faulting address (the parameter) is within attached pages. In this
|
|
||||||
case the exception_handler raises SIGBUS, as demanded by the memory
|
First, is it an address within "attached" mmap pages (indicated by
|
||||||
protection extension described in SUSv3 (see the mmap man page).
|
the __PROT_ATTACH protection, see there)? In this case the function
|
||||||
If false is returned, a normal SIGSEGV is raised. */
|
returns 1 and the exception_handler raises SIGBUS, as demanded by the
|
||||||
bool
|
memory protection extension described in SUSv3 (see the mmap man
|
||||||
mmap_is_attached_page (ULONG_PTR addr)
|
page).
|
||||||
|
|
||||||
|
Second, check if the address is within "noreserve" mmap pages
|
||||||
|
(indicated by MAP_NORESERVE flag). If so, the function calls
|
||||||
|
VirtualAlloc to commit the page and returns 2. The exception handler
|
||||||
|
then just returns with 0 and the affected application retries the
|
||||||
|
failing memory access. If VirtualAlloc fails, the function returns
|
||||||
|
1, so that the exception handler raises a SIGBUS, as described in the
|
||||||
|
MAP_NORESERVE man pages for Linux and Solaris.
|
||||||
|
|
||||||
|
In any other case 0 is returned and a normal SIGSEGV is raised. */
|
||||||
|
int
|
||||||
|
mmap_is_attached_or_noreserve_page (ULONG_PTR addr)
|
||||||
{
|
{
|
||||||
list *map_list;
|
list *map_list;
|
||||||
long record_idx;
|
long record_idx;
|
||||||
@ -916,13 +928,16 @@ mmap_is_attached_page (ULONG_PTR addr)
|
|||||||
|
|
||||||
addr = rounddown (addr, pagesize);
|
addr = rounddown (addr, pagesize);
|
||||||
if (!(map_list = mmapped_areas.get_list_by_fd (-1)))
|
if (!(map_list = mmapped_areas.get_list_by_fd (-1)))
|
||||||
return false;
|
return 0;
|
||||||
if ((record_idx = map_list->search_record ((caddr_t)addr, pagesize,
|
if ((record_idx = map_list->search_record ((caddr_t)addr, pagesize,
|
||||||
u_addr, u_len, -1)) < 0)
|
u_addr, u_len, -1)) < 0)
|
||||||
return false;
|
return 0;
|
||||||
if (!map_list->get_record (record_idx)->attached ())
|
if (map_list->get_record (record_idx)->attached ())
|
||||||
return false;
|
return 1;
|
||||||
return true;
|
if (!map_list->get_record (record_idx)->noreserve ())
|
||||||
|
return 0;
|
||||||
|
DWORD new_prot = map_list->get_record (record_idx)->gen_protect ();
|
||||||
|
return VirtualAlloc ((void *)addr, pagesize, MEM_COMMIT, new_prot) ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static caddr_t
|
static caddr_t
|
||||||
|
@ -299,7 +299,7 @@ size_t getsystempagesize ();
|
|||||||
|
|
||||||
/* mmap functions. */
|
/* mmap functions. */
|
||||||
void mmap_init ();
|
void mmap_init ();
|
||||||
bool mmap_is_attached_page (ULONG_PTR);
|
int mmap_is_attached_or_noreserve_page (ULONG_PTR addr);
|
||||||
|
|
||||||
int winprio_to_nice (DWORD) __attribute__ ((regparm (1)));
|
int winprio_to_nice (DWORD) __attribute__ ((regparm (1)));
|
||||||
DWORD nice_to_winprio (int &) __attribute__ ((regparm (1)));
|
DWORD nice_to_winprio (int &) __attribute__ ((regparm (1)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user