7028668: 3/4 improve diagnosibility and robustness of sun.tools.attach.WindowsVirtualMachine.openProcess()
authordcubed
Fri, 18 Mar 2011 07:17:24 -0700
changeset 8804 2d69a944f4da
parent 8803 b3f57bfca459
child 8805 1a56a0bf5840
child 8807 60202547e389
7028668: 3/4 improve diagnosibility and robustness of sun.tools.attach.WindowsVirtualMachine.openProcess() Summary: Add more info to OpenProcess default detail error message. Try a different technique when a Java process is attaching to itself. Reviewed-by: zgu, ohair, alanb
jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c
--- a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c	Thu Mar 17 18:50:06 2011 -0700
+++ b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c	Fri Mar 18 07:17:24 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -173,24 +173,45 @@
 JNIEXPORT jlong JNICALL Java_sun_tools_attach_WindowsVirtualMachine_openProcess
   (JNIEnv *env, jclass cls, jint pid)
 {
-    HANDLE hProcess;
+    HANDLE hProcess = NULL;
 
-    /*
-     * Attempt to open process. If it fails then we try to enable the
-     * SE_DEBUG_NAME privilege and retry.
-     */
-    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
-    if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
-        hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
+    if (pid == (jint) GetCurrentProcessId()) {
+        /* process is attaching to itself; get a pseudo handle instead */
+        hProcess = GetCurrentProcess();
+        /* duplicate the pseudo handle so it can be used in more contexts */
+        if (DuplicateHandle(hProcess, hProcess, hProcess, &hProcess,
+                PROCESS_ALL_ACCESS, FALSE, 0) == 0) {
+            /*
+             * Could not duplicate the handle which isn't a good sign,
+             * but we'll try again with OpenProcess() below.
+             */
+            hProcess = NULL;
+        }
     }
 
     if (hProcess == NULL) {
-        if (GetLastError() == ERROR_INVALID_PARAMETER) {
-            JNU_ThrowIOException(env, "no such process");
-        } else {
-            JNU_ThrowIOExceptionWithLastError(env, "OpenProcess failed");
+        /*
+         * Attempt to open process. If it fails then we try to enable the
+         * SE_DEBUG_NAME privilege and retry.
+         */
+        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
+        if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
+            hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE,
+                           (DWORD)pid);
         }
-        return (jlong)0;
+
+        if (hProcess == NULL) {
+            if (GetLastError() == ERROR_INVALID_PARAMETER) {
+                JNU_ThrowIOException(env, "no such process");
+            } else {
+                char err_mesg[255];
+                /* include the last error in the default detail message */
+                sprintf(err_mesg, "OpenProcess(pid=%d) failed; LastError=0x%x",
+                    (int)pid, (int)GetLastError());
+                JNU_ThrowIOExceptionWithLastError(env, err_mesg);
+            }
+            return (jlong)0;
+        }
     }
 
     /*