Follow up to r15936.

Kernel allocates another page after fork and we have to
keep aspacemgr's point of view consistent.
n-i-bz


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15937
This commit is contained in:
Ivo Raisr 2016-08-15 02:31:27 +00:00
parent 6260274e4e
commit b6224ced96
3 changed files with 72 additions and 1 deletions

View File

@ -4057,6 +4057,51 @@ static void parse_procselfmaps (
(*record_gap)(gap_start, Addr_MAX - gap_start + 1);
}
/* parse_procselfmaps() callbacks do not allow for easy thread safety. */
static Addr found_addr;
static SizeT found_size;
static UInt found_prot;
/* Reports a new mapping into variables above. */
static void new_segment_found_callback(Addr addr, SizeT len, UInt prot,
ULong dev, ULong ino, Off64T offset, const HChar *filename)
{
aspacem_assert(addr <= addr + len - 1);
Int iLo = find_nsegment_idx(addr);
Int iHi = find_nsegment_idx(addr + len - 1);
aspacem_assert(iLo <= iHi);
aspacem_assert(nsegments[iLo].start <= addr);
aspacem_assert(nsegments[iHi].end >= addr + len - 1);
/* Do not perform any sanity checks. That is done in other places.
Just find if a reported mapping is found in aspacemgr's book keeping. */
for (Int i = iLo; i <= iHi; i++) {
if ((nsegments[i].kind == SkFree) || (nsegments[i].kind == SkResvn)) {
found_addr = addr;
found_size = len;
found_prot = prot;
break;
}
}
}
/* Returns True if a new segment was found. */
Bool VG_(am_search_for_new_segment)(Addr *addr, SizeT *size, UInt *prot)
{
found_addr = 0;
parse_procselfmaps(new_segment_found_callback, NULL);
if (found_addr != 0) {
*addr = found_addr;
*size = found_size;
*prot = found_prot;
return True;
} else {
return False;
}
}
#endif // defined(VGO_solaris)
/*------END-procmaps-parser-for-Solaris--------------------------*/

View File

@ -6520,6 +6520,27 @@ PRE(sys_forksys)
/* vfork */
if (ARG1 == 2)
VG_(close)(fds[1]);
# if defined(SOLARIS_PT_SUNDWTRACE_THRP)
/* Kernel can map a new page as a scratch space of the DTrace fasttrap
provider. There is no way we can directly get its address - it's all
private to the kernel. Fish it the slow way. */
Addr addr;
SizeT size;
UInt prot;
Bool found = VG_(am_search_for_new_segment)(&addr, &size, &prot);
if (found) {
VG_(debugLog)(1, "syswrap-solaris", "PRE(forksys), new segment: "
"vaddr=%#lx, size=%#lx, prot=%#x\n", addr, size, prot);
vg_assert(prot == (VKI_PROT_READ | VKI_PROT_EXEC));
vg_assert(size == VKI_PAGE_SIZE);
ML_(notify_core_and_tool_of_mmap)(addr, size, prot, VKI_MAP_ANONYMOUS,
-1, 0);
/* Note: We don't notify the debuginfo reader about this mapping
because there is no debug information stored in this segment. */
}
# endif /* SOLARIS_PT_SUNDWTRACE_THRP */
}
else {
VG_(do_atfork_parent)(tid);
@ -9345,7 +9366,7 @@ POST(sys_door)
-1, 0);
/* Note: We don't notify the debuginfo reader about this
mapping because there are no debug information stored in
mapping because there is no debug information stored in
this segment. */
}

View File

@ -378,6 +378,11 @@ extern Bool VG_(get_changed_segments)(
Int css_size, /*OUT*/Int* css_used);
#endif
#if defined(VGO_solaris)
extern Bool VG_(am_search_for_new_segment)(Addr *start, SizeT *size,
UInt *prot);
#endif
#endif // __PUB_CORE_ASPACEMGR_H
/*--------------------------------------------------------------------*/