]> sourceware.org Git - newlib-cygwin.git/commitdiff
Improve error handling in /proc/[pid]/ virtual files.
authorErik M. Bray <erik.m.bray@gmail.com>
Wed, 10 Apr 2019 15:05:22 +0000 (17:05 +0200)
committerCorinna Vinschen <corinna@vinschen.de>
Wed, 10 Apr 2019 16:17:14 +0000 (18:17 +0200)
* Changes error handling to allow /proc/[pid]/ virtual files to be
  empty in some cases (in this case the file's formatter should return
  -1 upon error, not 0).

* Better error handling of /proc/[pid]/stat for zombie processes:
  previously trying to open this file on zombie processes resulted
  in an EINVAL being returned by open().  Now the file can be read,
  and fields that can no longer be read are just zeroed.

* Similarly for /proc/[pid]/statm for zombie processes.

* Similarly for /proc/[pid]/maps for zombie processes (in this case the
  file can be read but is zero-length, which is consistent with observed
  behavior on Linux.

winsup/cygwin/fhandler_process.cc

index 44410b22330822ab3d090a2f6f55c17a589ae434..5ee129317f6b2108f72ddb9865262f34281118c7 100644 (file)
@@ -355,7 +355,7 @@ fhandler_process::fill_filebuf ()
        }
       else
        filesize = process_tab[fileid].format_func (p, filebuf);
-      return !filesize ? false : true;
+      return filesize < 0 ? false : true;
     }
   return false;
 }
@@ -818,7 +818,22 @@ format_process_maps (void *data, char *&destbuf)
   HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION
                             | PROCESS_VM_READ, FALSE, p->dwProcessId);
   if (!proc)
-    return 0;
+    {
+      if (!(p->process_state & PID_EXITED))
+        {
+          DWORD error = GetLastError ();
+          __seterrno_from_win_error (error);
+          debug_printf ("OpenProcess: ret %u; pid: %d", error, p->dwProcessId);
+          return -1;
+        }
+      else
+        {
+          /* Else it's a zombie process; just return an empty string */
+          destbuf = (char *) crealloc_abort (destbuf, 1);
+          destbuf[0] = '\0';
+          return 0;
+        }
+    }
 
   NTSTATUS status;
   PROCESS_BASIC_INFORMATION pbi;
@@ -1101,9 +1116,14 @@ format_process_stat (void *data, char *&destbuf)
                          FALSE, p->dwProcessId);
   if (hProcess == NULL)
     {
-      DWORD error = GetLastError ();
-      __seterrno_from_win_error (error);
-      debug_printf ("OpenProcess: ret %u", error);
+      if (!(p->process_state & PID_EXITED))
+        {
+          DWORD error = GetLastError ();
+          __seterrno_from_win_error (error);
+          debug_printf ("OpenProcess: ret %u; pid: %d", error, p->dwProcessId);
+          return -1;
+        }
+      /* Else it's a zombie process; just leave each structure zero'd */
     }
   else
     {
@@ -1258,9 +1278,10 @@ format_process_statm (void *data, char *&destbuf)
 {
   _pinfo *p = (_pinfo *) data;
   size_t vmsize = 0, vmrss = 0, vmtext = 0, vmdata = 0, vmlib = 0, vmshare = 0;
+
   if (!get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata,
-                      vmlib, vmshare))
-    return 0;
+                      vmlib, vmshare) && !(p->process_state & PID_EXITED))
+    return -1;  /* Error out unless it's a zombie process */
 
   destbuf = (char *) crealloc_abort (destbuf, 96);
   return __small_sprintf (destbuf, "%lu %lu %lu %lu %lu %lu 0\n",
This page took 0.032308 seconds and 5 git commands to generate.