Fix /proc/<PID>/maps output for PEB and TEBs on W10 1511
* fhandler_process.cc (heap_info::fill_if_match): Return NULL, not 0. (thread_info::fill_if_match): Ditto. (thread_info::fill_if_match): New method to extract TEB info from PEB/TEB region since W10 1511. (format_process_maps): Drop outdated FIXME comment. Add code to handle PEB/TEB region since W10 1511. * mmap.cc (posix_madvise): Align comment to new W10 1511 version. * wincap.h (wincaps::has_new_pebteb_region): New element. * wincap.cc: Implement above element throughout. (wincap_10_1511): New global wincaps to support Windows 10 since 1511. (wincapc::init): Use wincap_10_1511 for W10 builds >= 10586. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
8a14e51901
commit
f1ed5bfa83
@ -1,3 +1,17 @@
|
|||||||
|
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_process.cc (heap_info::fill_if_match): Return NULL, not 0.
|
||||||
|
(thread_info::fill_if_match): Ditto.
|
||||||
|
(thread_info::fill_if_match): New method to extract TEB info from
|
||||||
|
PEB/TEB region since W10 1511.
|
||||||
|
(format_process_maps): Drop outdated FIXME comment. Add code to handle
|
||||||
|
PEB/TEB region since W10 1511.
|
||||||
|
* mmap.cc (posix_madvise): Align comment to new W10 1511 version.
|
||||||
|
* wincap.h (wincaps::has_new_pebteb_region): New element.
|
||||||
|
* wincap.cc: Implement above element throughout.
|
||||||
|
(wincap_10_1511): New global wincaps to support Windows 10 since 1511.
|
||||||
|
(wincapc::init): Use wincap_10_1511 for W10 builds >= 10586.
|
||||||
|
|
||||||
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
x86_64 only:
|
x86_64 only:
|
||||||
|
@ -648,7 +648,7 @@ struct heap_info
|
|||||||
stpcpy (p, "]");
|
stpcpy (p, "]");
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~heap_info ()
|
~heap_info ()
|
||||||
@ -769,7 +769,21 @@ struct thread_info
|
|||||||
stpcpy (p, "]");
|
stpcpy (p, "]");
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
|
}
|
||||||
|
char *fill_if_match (char *start, char *end, ULONG type, char *dest)
|
||||||
|
{
|
||||||
|
for (region *r = regions; r; r = r->next)
|
||||||
|
if (r->teb && start <= r->start && r->end <= end)
|
||||||
|
{
|
||||||
|
char *p = dest + __small_sprintf (dest, "[teb (tid %ld)",
|
||||||
|
r->thread_id);
|
||||||
|
if (type & MEM_MAPPED)
|
||||||
|
p = stpcpy (p, " shared");
|
||||||
|
stpcpy (p, "]");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~thread_info ()
|
~thread_info ()
|
||||||
@ -847,12 +861,7 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
|
|
||||||
/* Iterate over each VM region in the address space, coalescing
|
/* Iterate over each VM region in the address space, coalescing
|
||||||
memory regions with the same permissions. Once we run out, do one
|
memory regions with the same permissions. Once we run out, do one
|
||||||
last_pass to trigger output of the last accumulated region.
|
last_pass to trigger output of the last accumulated region. */
|
||||||
|
|
||||||
FIXME: 32 bit processes can't get address information beyond the
|
|
||||||
32 bit address space from 64 bit processes. We have to run
|
|
||||||
this functionality in the target process, if the target
|
|
||||||
process is 64 bit and our own process is 32 bit. */
|
|
||||||
for (char *i = 0;
|
for (char *i = 0;
|
||||||
VirtualQueryEx (proc, i, &mb, sizeof(mb)) || (1 == ++last_pass);
|
VirtualQueryEx (proc, i, &mb, sizeof(mb)) || (1 == ++last_pass);
|
||||||
i = cur.rend)
|
i = cur.rend)
|
||||||
@ -899,6 +908,33 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
cur.rend = next.rend; /* merge with previous */
|
cur.rend = next.rend; /* merge with previous */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char *peb_teb_end = NULL;
|
||||||
|
peb_teb_rinse_repeat:
|
||||||
|
/* Starting with W10 1511, PEB and TEBs don't get allocated
|
||||||
|
separately. Rather they are created in a single region. Examine
|
||||||
|
the region starting at the PEB address page-wise. */
|
||||||
|
if (wincap.has_new_pebteb_region ())
|
||||||
|
{
|
||||||
|
if (!newbase && cur.rbase == (char *) peb)
|
||||||
|
{
|
||||||
|
strcpy (posix_modname, "[peb]");
|
||||||
|
peb_teb_end = cur.rend;
|
||||||
|
cur.rend = cur.rbase + wincap.page_size ();
|
||||||
|
}
|
||||||
|
else if (peb_teb_end)
|
||||||
|
{
|
||||||
|
posix_modname[0] = '\0';
|
||||||
|
if (!threads.fill_if_match (cur.rbase, cur.rend,
|
||||||
|
mb.Type, posix_modname))
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cur.rend += wincap.page_size ();
|
||||||
|
}
|
||||||
|
while (!threads.fill_if_match (cur.rbase, cur.rend,
|
||||||
|
mb.Type, posix_modname)
|
||||||
|
&& cur.rend < peb_teb_end);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* output the current region if it's "interesting". */
|
/* output the current region if it's "interesting". */
|
||||||
if (cur.a.word)
|
if (cur.a.word)
|
||||||
{
|
{
|
||||||
@ -919,6 +955,14 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
len += written;
|
len += written;
|
||||||
len += __small_sprintf (destbuf + len, "%s\n", posix_modname);
|
len += __small_sprintf (destbuf + len, "%s\n", posix_modname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (peb_teb_end)
|
||||||
|
{
|
||||||
|
cur.rbase = cur.rend;
|
||||||
|
cur.rend += wincap.page_size ();
|
||||||
|
if (cur.rbase < peb_teb_end)
|
||||||
|
goto peb_teb_rinse_repeat;
|
||||||
|
}
|
||||||
/* start of a new region (but possibly still the same allocation). */
|
/* start of a new region (but possibly still the same allocation). */
|
||||||
cur = next;
|
cur = next;
|
||||||
/* if a new allocation, figure out what kind it is. */
|
/* if a new allocation, figure out what kind it is. */
|
||||||
|
@ -1578,7 +1578,7 @@ posix_madvise (void *addr, size_t len, int advice)
|
|||||||
/* FIXME 2015-08-27: On W10 build 10240 under WOW64,
|
/* FIXME 2015-08-27: On W10 build 10240 under WOW64,
|
||||||
PrefetchVirtualMemory always returns ERROR_INVALID_PARAMETER
|
PrefetchVirtualMemory always returns ERROR_INVALID_PARAMETER
|
||||||
for some reason. If we're running on W10 WOW64, ignore this
|
for some reason. If we're running on W10 WOW64, ignore this
|
||||||
error for now. There's an open case at Microsoft for this. */
|
error. This has been fixed in W10 1511. */
|
||||||
if (!wincap.has_broken_prefetchvm ()
|
if (!wincap.has_broken_prefetchvm ()
|
||||||
|| GetLastError () != ERROR_INVALID_PARAMETER)
|
|| GetLastError () != ERROR_INVALID_PARAMETER)
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
|
@ -51,6 +51,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
|
has_new_pebteb_region:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -84,6 +85,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_broken_rtl_query_process_debug_information:true,
|
has_broken_rtl_query_process_debug_information:true,
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
|
has_new_pebteb_region:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -117,6 +119,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
|
has_new_pebteb_region:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -150,6 +153,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
|
has_new_pebteb_region:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -183,6 +187,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
|
has_new_pebteb_region:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
@ -216,6 +221,41 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:true,
|
has_broken_prefetchvm:true,
|
||||||
|
has_new_pebteb_region:false,
|
||||||
|
};
|
||||||
|
|
||||||
|
wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
def_guard_pages:2,
|
||||||
|
max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
|
||||||
|
is_server:false,
|
||||||
|
has_mandatory_integrity_control:true,
|
||||||
|
needs_count_in_si_lpres2:false,
|
||||||
|
has_recycle_dot_bin:true,
|
||||||
|
has_gaa_on_link_prefix:true,
|
||||||
|
has_gaa_largeaddress_bug:false,
|
||||||
|
supports_all_posix_ai_flags:true,
|
||||||
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:true,
|
||||||
|
has_sendmsg:true,
|
||||||
|
has_broken_udf:false,
|
||||||
|
has_broken_alloc_console:true,
|
||||||
|
has_always_all_codepages:true,
|
||||||
|
has_localenames:true,
|
||||||
|
has_fast_cwd:true,
|
||||||
|
has_restricted_raw_disk_access:true,
|
||||||
|
use_dont_resolve_hack:false,
|
||||||
|
has_console_logon_sid:true,
|
||||||
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assistant:true,
|
||||||
|
has_pipe_reject_remote_clients:true,
|
||||||
|
terminate_thread_frees_stack:true,
|
||||||
|
has_precise_system_time:true,
|
||||||
|
has_microsoft_accounts:true,
|
||||||
|
has_set_thread_stack_guarantee:true,
|
||||||
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
|
has_processor_groups:true,
|
||||||
|
has_broken_prefetchvm:false,
|
||||||
|
has_new_pebteb_region:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
@ -263,7 +303,10 @@ wincapc::init ()
|
|||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
default:
|
default:
|
||||||
caps = &wincap_10;
|
if (version.dwBuildNumber >= 10586)
|
||||||
|
caps = &wincap_10_1511;
|
||||||
|
else
|
||||||
|
caps = &wincap_10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ struct wincaps
|
|||||||
unsigned has_broken_rtl_query_process_debug_information : 1;
|
unsigned has_broken_rtl_query_process_debug_information : 1;
|
||||||
unsigned has_processor_groups : 1;
|
unsigned has_processor_groups : 1;
|
||||||
unsigned has_broken_prefetchvm : 1;
|
unsigned has_broken_prefetchvm : 1;
|
||||||
|
unsigned has_new_pebteb_region : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
@ -102,6 +103,7 @@ public:
|
|||||||
bool IMPLEMENT (has_broken_rtl_query_process_debug_information)
|
bool IMPLEMENT (has_broken_rtl_query_process_debug_information)
|
||||||
bool IMPLEMENT (has_processor_groups)
|
bool IMPLEMENT (has_processor_groups)
|
||||||
bool IMPLEMENT (has_broken_prefetchvm)
|
bool IMPLEMENT (has_broken_prefetchvm)
|
||||||
|
bool IMPLEMENT (has_new_pebteb_region)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user