Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-12-03 18:54:08 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-12-03 18:54:29 +0300
commit8f4da28eb68d583840cfbca8896755c60d2c8d15 (patch)
tree0b75a1c65728266bf8d20003e560d737364c5abc
parentf1ed5bfa8385a81d72313604e90b9096f8bf2ead (diff)
Fix thinko in /proc/<PID>/maps TEB detection on W10 1511
* fhandler_process.cc (thread_info::thread_info): Accommodate the fact that TEBs take two pages. (thread_info::fill_if_match): Rewrite the method for post W10 1511 TEB detection. (format_process_maps): Add a state member to region. Fix the code to handle PEB/TEB region since W10 1511. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/fhandler_process.cc77
2 files changed, 60 insertions, 26 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0cc944e96..59e8cce60 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,14 @@
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler_process.cc (thread_info::thread_info): Accommodate the fact
+ that TEBs take two pages.
+ (thread_info::fill_if_match): Rewrite the method for post W10 1511 TEB
+ detection.
+ (format_process_maps): Add a state member to region. Fix the code
+ to handle PEB/TEB region since W10 1511.
+
+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
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index ad622c982..4e4c6145c 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -731,7 +731,8 @@ struct thread_info
{
*r = (region) { regions, (ULONG) (ULONG_PTR) thread[i].ClientId.UniqueThread,
(char *) tbi.TebBaseAddress,
- (char *) tbi.TebBaseAddress + wincap.page_size (),
+ (char *) tbi.TebBaseAddress
+ + 2 * wincap.page_size (),
true };
regions = r;
}
@@ -771,17 +772,14 @@ struct thread_info
}
return NULL;
}
- char *fill_if_match (char *start, char *end, ULONG type, char *dest)
+ /* Helper to look for TEBs inside single allocated region since W10 1511. */
+ char *fill_if_match (char *start, char *dest)
{
for (region *r = regions; r; r = r->next)
- if (r->teb && start <= r->start && r->end <= end)
+ if (r->teb && start == r->start)
{
- char *p = dest + __small_sprintf (dest, "[teb (tid %ld)",
- r->thread_id);
- if (type & MEM_MAPPED)
- p = stpcpy (p, " shared");
- stpcpy (p, "]");
- return dest;
+ __small_sprintf (dest, "[teb (tid %ld)]", r->thread_id);
+ return r->end;
}
return NULL;
}
@@ -839,6 +837,7 @@ format_process_maps (void *data, char *&destbuf)
char *abase;
char *rbase;
char *rend;
+ DWORD state;
} cur = {{{'\0'}}, (char *)1, 0, 0};
MEMORY_BASIC_INFORMATION mb;
@@ -852,6 +851,7 @@ format_process_maps (void *data, char *&destbuf)
PMEMORY_SECTION_NAME msi = (PMEMORY_SECTION_NAME) tp.w_get ();
char *posix_modname = tp.c_get ();
size_t maxsize = 0;
+ char *peb_teb_abase = NULL;
if (destbuf)
{
@@ -897,7 +897,8 @@ format_process_maps (void *data, char *&destbuf)
region next = { a,
(char *) mb.AllocationBase,
(char *) mb.BaseAddress,
- (char *) mb.BaseAddress+mb.RegionSize
+ (char *) mb.BaseAddress+mb.RegionSize,
+ mb.State
};
/* Windows permissions are more fine-grained than the unix rwxp,
@@ -915,24 +916,48 @@ peb_teb_rinse_repeat:
the region starting at the PEB address page-wise. */
if (wincap.has_new_pebteb_region ())
{
- if (!newbase && cur.rbase == (char *) peb)
+ if (peb_teb_abase && !peb_teb_end && cur.abase == peb_teb_abase)
{
- strcpy (posix_modname, "[peb]");
+ posix_modname[0] = '\0';
peb_teb_end = cur.rend;
- cur.rend = cur.rbase + wincap.page_size ();
+ if (cur.state == MEM_COMMIT)
+ cur.rend = cur.rbase + wincap.page_size ();
}
- else if (peb_teb_end)
+ if (cur.state == MEM_COMMIT)
{
- 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);
+ if (!peb_teb_abase && cur.rbase == (char *) peb)
+ {
+ peb_teb_abase = cur.abase;
+ peb_teb_end = cur.rend;
+ cur.rend = cur.rbase + wincap.page_size ();
+ strcpy (posix_modname, "[peb]");
+ }
+ else if (peb_teb_end)
+ {
+ char *end;
+ posix_modname[0] = '\0';
+ end = threads.fill_if_match (cur.rbase, posix_modname);
+
+ if (end)
+ cur.rend = end;
+ else
+ {
+ char *base = cur.rbase;
+ do
+ {
+ base += wincap.page_size ();
+ }
+ while (!threads.fill_if_match (base, posix_modname)
+ && base < peb_teb_end);
+ if (posix_modname[0])
+ {
+ posix_modname[0] = '\0';
+ cur.rend = base;
+ }
+ else
+ cur.rend = peb_teb_end;
+ }
+ }
}
}
/* output the current region if it's "interesting". */
@@ -956,7 +981,7 @@ peb_teb_rinse_repeat:
len += __small_sprintf (destbuf + len, "%s\n", posix_modname);
}
- if (peb_teb_end)
+ if (peb_teb_end && cur.state == MEM_COMMIT)
{
cur.rbase = cur.rend;
cur.rend += wincap.page_size ();
@@ -966,7 +991,7 @@ peb_teb_rinse_repeat:
/* start of a new region (but possibly still the same allocation). */
cur = next;
/* if a new allocation, figure out what kind it is. */
- if (newbase && !last_pass && mb.State != MEM_FREE)
+ if (newbase && !last_pass && cur.state != MEM_FREE)
{
/* If the return length pointer is missing, NtQueryVirtualMemory
returns with STATUS_ACCESS_VIOLATION on Windows 2000. */