diff --git a/classpath/java/lang/ExceptionHelper.java b/classpath/java/lang/ExceptionHelper.java index 01486133..822ab168 100644 --- a/classpath/java/lang/ExceptionHelper.java +++ b/classpath/java/lang/ExceptionHelper.java @@ -27,7 +27,8 @@ import java.io.*; import java.lang.reflect.*; import gnu.classpath.SystemProperties; -final class ExceptionHelper +@ikvm.lang.Internal +public final class ExceptionHelper { // the contents of the NULL_STRING should be empty (because when the exception propagates to other .NET code // it will return that text as the Message property), but it *must* be a copy, because we need to be @@ -706,4 +707,14 @@ final class ExceptionHelper setStackTrace(r, new ExceptionInfoHelper(t, true).get_StackTrace(t)); return r; } + + // helper for use by java.lang.management.VMThreadInfo + public static StackTraceElement[] getStackTrace(cli.System.Diagnostics.StackTrace st, int maxDepth) + { + cli.System.Collections.ArrayList stackTrace = new cli.System.Collections.ArrayList(); + ExceptionInfoHelper.Append(stackTrace, st, 0); + StackTraceElement[] ste = new StackTraceElement[Math.min(maxDepth, stackTrace.get_Count())]; + stackTrace.CopyTo(0, (cli.System.Array)(Object)ste, 0, ste.length); + return ste; + } } diff --git a/classpath/java/lang/VMThread.java b/classpath/java/lang/VMThread.java index 1273dac6..63d0f8fb 100644 --- a/classpath/java/lang/VMThread.java +++ b/classpath/java/lang/VMThread.java @@ -752,4 +752,14 @@ public final class VMThread } return "TERMINATED"; } + + public static cli.System.Threading.Thread getNativeThread(Thread t) + { + VMThread vmthread = t.vmThread; + if(vmthread != null) + { + return (cli.System.Threading.Thread)vmthread.nativeThreadReference.get_Target(); + } + return null; + } } diff --git a/classpath/java/lang/management/VMThreadInfo.java b/classpath/java/lang/management/VMThreadInfo.java index b111ac99..64125632 100644 --- a/classpath/java/lang/management/VMThreadInfo.java +++ b/classpath/java/lang/management/VMThreadInfo.java @@ -37,6 +37,8 @@ exception statement from your version. */ package java.lang.management; +import java.lang.VMThread; + /** * Provides low-level information about a thread. * @@ -180,6 +182,35 @@ final class VMThreadInfo */ static StackTraceElement[] getStackTrace(Thread thread, int maxDepth) { - throw new UnsupportedOperationException(); + cli.System.Threading.Thread nativeThread = VMThread.getNativeThread(thread); + if(nativeThread == null) + { + return new StackTraceElement[0]; + } + else if(nativeThread == cli.System.Threading.Thread.get_CurrentThread()) + { + return ExceptionHelper.getStackTrace(new cli.System.Diagnostics.StackTrace(2, true), maxDepth); + } + else + { + cli.System.Diagnostics.StackTrace st = null; + try + { + nativeThread.Suspend(); + try + { + st = new cli.System.Diagnostics.StackTrace(nativeThread, true); + } + finally + { + nativeThread.Resume(); + } + } + catch(Throwable _) + { + return new StackTraceElement[0]; + } + return ExceptionHelper.getStackTrace(st, maxDepth); + } } }