8000973: SA on windows thread inspection is broken
Summary: After bug 7161732, On Windows SA could not find correct address of thread_id of OSThread since _thread_id moved to end of the class . The presupposition of the address is following thread handle no longer stands. Fix by adding thread_id field to OSThread and getting the address directly from OSThread.
Reviewed-by: nloodin, sspitsyn
Contributed-by: yumin.qi@oracle.com
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java Mon Jan 28 09:33:55 2013 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java Thu Jan 31 17:43:01 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -34,21 +34,11 @@
private boolean gotID;
private long id;
- /** The address argument must be the address of the HANDLE of the
- desired thread in the target process. */
+ // The address argument must be the address of the OSThread::_thread_id
WindbgAMD64Thread(WindbgDebugger debugger, Address addr) {
this.debugger = debugger;
- // FIXME: size of data fetched here should be configurable.
- // However, making it so would produce a dependency on the "types"
- // package from the debugger package, which is not desired.
-
- // another hack here is that we use sys thread id instead of handle.
- // windbg can't get details based on handles it seems.
- // I assume that osThread_win32 thread struct has _thread_id (which
- // sys thread id) just after handle field.
-
- this.sysId = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
- gotID = false;
+ this.sysId = (long)addr.getCIntegerAt(0, 4, true);
+ gotID = false;
}
WindbgAMD64Thread(WindbgDebugger debugger, long sysId) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java Mon Jan 28 09:33:55 2013 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java Thu Jan 31 17:43:01 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, 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
@@ -34,21 +34,11 @@
private boolean gotID;
private long id;
- /** The address argument must be the address of the HANDLE of the
- desired thread in the target process. */
+ // The address argument must be the address of OSThread::_thread_id
WindbgX86Thread(WindbgDebugger debugger, Address addr) {
this.debugger = debugger;
- // FIXME: size of data fetched here should be configurable.
- // However, making it so would produce a dependency on the "types"
- // package from the debugger package, which is not desired.
-
- // another hack here is that we use sys thread id instead of handle.
- // windbg can't get details based on handles it seems.
- // I assume that osThread_win32 thread struct has _thread_id (which
- // sys thread id) just after handle field.
-
- this.sysId = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
- gotID = false;
+ this.sysId = (long)addr.getCIntegerAt(0, 4, true);
+ gotID = false;
}
WindbgX86Thread(WindbgDebugger debugger, long sysId) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Mon Jan 28 09:33:55 2013 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Thu Jan 31 17:43:01 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -32,6 +32,7 @@
// to the sys_thread_t structure of the classic JVM implementation.
public class OSThread extends VMObject {
private static JIntField interruptedField;
+ private static JIntField threadIdField;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -43,6 +44,7 @@
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("OSThread");
interruptedField = type.getJIntField("_interrupted");
+ threadIdField = type.getJIntField("_thread_id");
}
public OSThread(Address addr) {
@@ -52,4 +54,9 @@
public boolean interrupted() {
return ((int)interruptedField.getValue(addr)) != 0;
}
+
+ public int threadId() {
+ return (int)threadIdField.getValue(addr);
+ }
+
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Mon Jan 28 09:33:55 2013 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Thu Jan 31 17:43:01 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -43,7 +43,7 @@
private static AddressField osThreadField;
// Field from OSThread
- private static Field osThreadThreadHandleField;
+ private static Field osThreadThreadIdField;
// This is currently unneeded but is being kept in case we change
// the currentFrameGuess algorithm
@@ -64,7 +64,7 @@
osThreadField = type.getAddressField("_osthread");
type = db.lookupType("OSThread");
- osThreadThreadHandleField = type.getField("_thread_handle");
+ osThreadThreadIdField = type.getField("_thread_id");
}
public Address getLastJavaFP(Address addr) {
@@ -128,10 +128,10 @@
// Fetch the OSThread (for now and for simplicity, not making a
// separate "OSThread" class in this package)
Address osThreadAddr = osThreadField.getValue(addr);
- // Get the address of the HANDLE within the OSThread
- Address threadHandleAddr =
- osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
+ // Get the address of the thread_id within the OSThread
+ Address threadIdAddr =
+ osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
JVMDebugger debugger = VM.getVM().getDebugger();
- return debugger.getThreadForIdentifierAddress(threadHandleAddr);
+ return debugger.getThreadForIdentifierAddress(threadIdAddr);
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Mon Jan 28 09:33:55 2013 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Thu Jan 31 17:43:01 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, 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
@@ -42,7 +42,7 @@
private static AddressField osThreadField;
// Field from OSThread
- private static Field osThreadThreadHandleField;
+ private static Field osThreadThreadIdField;
// This is currently unneeded but is being kept in case we change
// the currentFrameGuess algorithm
@@ -63,7 +63,7 @@
osThreadField = type.getAddressField("_osthread");
type = db.lookupType("OSThread");
- osThreadThreadHandleField = type.getField("_thread_handle");
+ osThreadThreadIdField = type.getField("_thread_id");
}
public Address getLastJavaFP(Address addr) {
@@ -127,10 +127,10 @@
// Fetch the OSThread (for now and for simplicity, not making a
// separate "OSThread" class in this package)
Address osThreadAddr = osThreadField.getValue(addr);
- // Get the address of the HANDLE within the OSThread
- Address threadHandleAddr =
- osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
+ // Get the address of the thread_id within the OSThread
+ Address threadIdAddr =
+ osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
JVMDebugger debugger = VM.getVM().getDebugger();
- return debugger.getThreadForIdentifierAddress(threadHandleAddr);
+ return debugger.getThreadForIdentifierAddress(threadIdAddr);
}
}