This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Fix thinko in /proc/<PID>/maps TEB detection on W10 1511


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=8f4da28eb68d583840cfbca8896755c60d2c8d15

commit 8f4da28eb68d583840cfbca8896755c60d2c8d15
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Dec 3 16:54:08 2015 +0100

    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>

Diff:
---
 winsup/cygwin/ChangeLog           |  9 +++++
 winsup/cygwin/fhandler_process.cc | 77 ++++++++++++++++++++++++++-------------
 2 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0cc944e..59e8cce 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 ad622c9..4e4c614 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. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]