[newlib-cygwin] Cygwin: dll_list: stat_real_file_once with ntname

Corinna Vinschen corinna@sourceware.org
Mon Jun 3 16:38:00 GMT 2019


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

commit 6c9ad75a4bd40e9d72a109d17cc9fe6cc754af08
Author: Michael Haubenwallner <michael.haubenwallner@ssi-schaefer.com>
Date:   Fri May 3 16:14:14 2019 +0200

    Cygwin: dll_list: stat_real_file_once with ntname
    
    NtQueryVirtualMemory for MemorySectionName may return some old path even
    if the process was just started, for when some directory in between was
    renamed - maybe because the NT file cache is hot for the old path still.
    This was seen during gcc bootstrap, returning a MemorySectionName of
    ".../gcc/xgcc.exe" even if started as ".../prev-gcc/xgcc.exe", where the
    directory rename from "gcc" to "prev-gcc" was done the moment before.
    As we stat the module's real file right after loading now, there is no
    point in using NtQueryVirtualMemory with MemorySectionName any more, and
    we can use what GetModuleFileName returned instead.

Diff:
---
 winsup/cygwin/dll_init.cc |  2 +-
 winsup/cygwin/forkable.cc | 40 +++++++---------------------------------
 2 files changed, 8 insertions(+), 34 deletions(-)

diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 4ba1bd2..6a4ed26 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -381,7 +381,7 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
 	  *d->forkable_ntname = L'\0';
 	}
       if (forkables_supported ())
-	d->stat_real_file_once (); /* uses nt_max_path_buf () */
+	d->stat_real_file_once ();
       append (d);
       if (type == DLL_LOAD)
 	loaded_dlls++;
diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc
index 1dcafe5..4fbc2ab 100644
--- a/winsup/cygwin/forkable.cc
+++ b/winsup/cygwin/forkable.cc
@@ -161,44 +161,18 @@ dll::stat_real_file_once ()
   if (fii.IndexNumber.QuadPart != -1LL)
     return true;
 
-  tmp_pathbuf tp;
-
-  HANDLE fhandle = INVALID_HANDLE_VALUE;
-  NTSTATUS status, fstatus;
-  PMEMORY_SECTION_NAME pmsi1;
-  MEMORY_SECTION_NAME msi2;
-  pmsi1 = (PMEMORY_SECTION_NAME) dll_list::nt_max_path_buf ();
-  RtlInitEmptyUnicodeString (&msi2.SectionFileName, tp.w_get (), 65535);
-
-  /* Retry opening the real file name until that does not change any more. */
-  status = NtQueryVirtualMemory (NtCurrentProcess (), handle,
-				 MemorySectionName, pmsi1, 65536, NULL);
-  while (NT_SUCCESS (status) &&
-	!RtlEqualUnicodeString (&msi2.SectionFileName,
-				&pmsi1->SectionFileName, FALSE))
+  NTSTATUS fstatus;
+  HANDLE fhandle = dll_list::ntopenfile (ntname, &fstatus);
+  if (fhandle == INVALID_HANDLE_VALUE)
     {
-      debug_printf ("for %s at %p got memory section name '%W'",
-	ntname, handle, pmsi1->SectionFileName.Buffer);
-      RtlCopyUnicodeString (&msi2.SectionFileName, &pmsi1->SectionFileName);
-      if (fhandle != INVALID_HANDLE_VALUE)
-	NtClose (fhandle);
-      pmsi1->SectionFileName.Buffer[pmsi1->SectionFileName.Length] = L'\0';
-      fhandle = dll_list::ntopenfile (pmsi1->SectionFileName.Buffer, &fstatus);
-      status = NtQueryVirtualMemory (NtCurrentProcess (), handle,
-				     MemorySectionName, pmsi1, 65536, NULL);
+      system_printf ("WARNING: Unable (ntstatus %y) to open real file %W",
+		     fstatus, ntname);
+      return false;
     }
-  if (!NT_SUCCESS (status))
-    system_printf ("WARNING: Unable (ntstatus %y) to query real file for %W",
-		   status, ntname);
-  else if (fhandle == INVALID_HANDLE_VALUE)
-    system_printf ("WARNING: Unable (ntstatus %y) to open real file for %W",
-		   fstatus, ntname);
-  if (fhandle == INVALID_HANDLE_VALUE)
-    return false;
 
   if (!dll_list::read_fii (fhandle, &fii))
     system_printf ("WARNING: Unable to read real file attributes for %W",
-		   pmsi1->SectionFileName.Buffer);
+		   ntname);
 
   NtClose (fhandle);
   return fii.IndexNumber.QuadPart != -1LL;



More information about the Cygwin-cvs mailing list