mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-10-13 13:43:00 +00:00
GT-3128: Removing broken dumpGhidraThreads scripts. Users should use
jstack until we can reimplement something better.
This commit is contained in:
parent
9842bbc9a4
commit
4e01601a38
|
@ -1,242 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.Thread.State;
|
||||
import java.lang.management.*;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.remote.*;
|
||||
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.GhidraLaunchable;
|
||||
|
||||
public class DebugThreadDumper implements GhidraLaunchable {
|
||||
|
||||
// target must include the following VM argument on Sun JVM's
|
||||
// -Dcom.sun.management.jmxremote.port=18002
|
||||
// -Dcom.sun.management.jmxremote.authenticate=false
|
||||
// -Dcom.sun.management.jmxremote.ssl=false
|
||||
|
||||
@Override
|
||||
public void launch(GhidraApplicationLayout layout, String[] args) {
|
||||
|
||||
if (args.length != 1) {
|
||||
System.err.println("Invalid usage, expected debug port number");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
int port = -1;
|
||||
try {
|
||||
port = Integer.parseInt(args[0]);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (port <= 0 || port >= (64 * 1024 - 1)) {
|
||||
System.err.println("Invalid debug port number");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
int jmxPort = port + 1;
|
||||
System.out.println("Thread Dump (debug-port=" + port + ", jmx-port=" + jmxPort + ")");
|
||||
|
||||
try {
|
||||
System.out.println("Connecting to VM...");
|
||||
String url = "service:jmx:rmi:///jndi/rmi://localhost:" + jmxPort + "/jmxrmi";
|
||||
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(url));
|
||||
MBeanServerConnection connection = connector.getMBeanServerConnection();
|
||||
|
||||
ThreadMXBean threadBean = ManagementFactory.newPlatformMXBeanProxy(connection,
|
||||
ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class);
|
||||
|
||||
// potential options
|
||||
// Dump Trace
|
||||
System.out.println("Dumping threads...");
|
||||
dumpThreads(threadBean);
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("Error while dumping VM threads: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpThreads(ThreadMXBean threadBean) {
|
||||
|
||||
//TODO: virtualMachine.suspend(); // suspend to get a snapshot of the threads
|
||||
|
||||
for (ThreadInfo threadInfo : threadBean.dumpAllThreads(true, true)) {
|
||||
dumpThreadStack(threadInfo);
|
||||
}
|
||||
|
||||
// TODO: virtualMachine.resume(); // resume for future use
|
||||
}
|
||||
|
||||
private void dumpThreadStack(ThreadInfo threadInfo) {
|
||||
|
||||
dumpThreadInfo(threadInfo);
|
||||
|
||||
for (StackTraceElement stackElement : threadInfo.getStackTrace()) {
|
||||
System.out.println("\t" + buildLocationString(stackElement));
|
||||
}
|
||||
}
|
||||
|
||||
private String buildLocationString(StackTraceElement stackElement) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
String methodName = stackElement.getClassName() + "." + stackElement.getMethodName();
|
||||
buffer.append(methodName);
|
||||
|
||||
String sourceName = stackElement.getFileName();
|
||||
buffer.append(" (").append(sourceName).append(":");
|
||||
|
||||
int lineNumber = stackElement.getLineNumber();
|
||||
buffer.append(lineNumber < 0 ? "<unknown source>" : Integer.toString(lineNumber)).append(
|
||||
")");
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private void dumpThreadInfo(ThreadInfo threadInfo) {
|
||||
|
||||
State threadState = threadInfo.getThreadState();
|
||||
|
||||
System.out.println("\n\"" + threadInfo.getThreadName() + "\"" + " id=" +
|
||||
threadInfo.getThreadId() + " state=" + threadState);
|
||||
String lockOwner = threadInfo.getLockOwnerName();
|
||||
long lockOwnerId = threadInfo.getLockOwnerId();
|
||||
String lockName = threadInfo.getLockName();
|
||||
if (lockOwner != null) {
|
||||
System.out.println("\tWaiting on Monitor:");
|
||||
System.out.println(
|
||||
"\t\t-" + lockName + ", owner: " + lockOwner + "(" + lockOwnerId + ")");
|
||||
}
|
||||
|
||||
MonitorInfo[] monitorInfo = threadInfo.getLockedMonitors();
|
||||
if (monitorInfo != null && monitorInfo.length != 0) {
|
||||
System.out.println("\tOwned Monitors:");
|
||||
for (MonitorInfo monitor : monitorInfo) {
|
||||
System.out.println("\t\t-" + monitor);
|
||||
}
|
||||
}
|
||||
|
||||
LockInfo[] lockedSynchronizers = threadInfo.getLockedSynchronizers();
|
||||
if (lockedSynchronizers != null && lockedSynchronizers.length != 0) {
|
||||
System.out.println("\tOwned Sychronizers:");
|
||||
for (LockInfo lock : lockedSynchronizers) {
|
||||
System.out.println("\t\t-" + lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private void dumpThreadInfo( ThreadReference threadReference ) {
|
||||
// ReferenceType referenceType = threadReference.referenceType();
|
||||
// Field priorityField = referenceType.fieldByName( "priority" );
|
||||
//
|
||||
// System.out.println( "\n\"" + threadReference.name() + "\" " +
|
||||
// "priority=" + threadReference.getValue( priorityField ) +
|
||||
// " status=" + getThreadStatus( threadReference.status() ) +
|
||||
// " ");
|
||||
// }
|
||||
//
|
||||
// private String getThreadStatus( int statusCode ) {
|
||||
// switch( statusCode ) {
|
||||
// case ThreadReference.THREAD_STATUS_NOT_STARTED:
|
||||
// return "not started";
|
||||
// case ThreadReference.THREAD_STATUS_RUNNING:
|
||||
// return "running";
|
||||
// case ThreadReference.THREAD_STATUS_SLEEPING:
|
||||
// return "sleeping";
|
||||
// case ThreadReference.THREAD_STATUS_UNKNOWN:
|
||||
// return "unknown";
|
||||
// case ThreadReference.THREAD_STATUS_WAIT:
|
||||
// return "waiting";
|
||||
// case ThreadReference.THREAD_STATUS_ZOMBIE:
|
||||
// return "zombie";
|
||||
// case ThreadReference.THREAD_STATUS_MONITOR:
|
||||
// return "waiting for monitor";
|
||||
// default:
|
||||
// return "<unknown>";
|
||||
// }
|
||||
// }
|
||||
|
||||
// private AttachingConnector findLaunchingConnector() {
|
||||
// List<?> connectors = Bootstrap.virtualMachineManager().allConnectors();
|
||||
// Iterator<?> iter = connectors.iterator();
|
||||
// while (iter.hasNext()) {
|
||||
// Connector connector = (Connector)iter.next();
|
||||
// if (connector.name().equals("com.sun.jdi.SocketAttach")) {
|
||||
// return (AttachingConnector)connector;
|
||||
// }
|
||||
// }
|
||||
// throw new Error("No launching connector");
|
||||
// }
|
||||
//
|
||||
// private Map<String, Argument> getConnectorArguments( AttachingConnector connector, String[] mainArguments ) {
|
||||
// Map<String, Argument> arguments = connector.defaultArguments();
|
||||
//
|
||||
// // TODO: parse user arguments
|
||||
// // List<StringArgumentPair> argList = parseArguments( mainArguments );
|
||||
//
|
||||
// Argument argument = arguments.get( "port" );
|
||||
// if ( argument == null ) {
|
||||
// // no SocketConnector
|
||||
// throw new RuntimeException( "Unable to locate \"port\" argument" );
|
||||
// }
|
||||
//
|
||||
// setPortArgumentValue( argument, mainArguments );
|
||||
//
|
||||
// return arguments;
|
||||
// }
|
||||
//
|
||||
// private static void setPortArgumentValue( Argument argument, String[] mainArguments ) {
|
||||
// StringBuffer buffer = new StringBuffer();
|
||||
// for ( int i = 0; i < mainArguments.length; i++ ) {
|
||||
// buffer.append( mainArguments[i] );
|
||||
// }
|
||||
//
|
||||
// StringTokenizer tokenizer = new StringTokenizer( buffer.toString(), " ,=" );
|
||||
// List<String> tokenList = new ArrayList<String>();
|
||||
// while ( tokenizer.hasMoreTokens() ) {
|
||||
// tokenList.add( tokenizer.nextToken() );
|
||||
// }
|
||||
//
|
||||
// int portIndex = tokenList.indexOf( "port" );
|
||||
// if ( portIndex < 0 ) {
|
||||
// portIndex = tokenList.indexOf( "-port" );
|
||||
// }
|
||||
//
|
||||
// if ( portIndex < 0 ) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// String portValue = tokenList.get( portIndex + 1 );
|
||||
// String portStringValue = DEFAULT_PORT;
|
||||
// try {
|
||||
// // test to see if the value is a valid int
|
||||
// Integer.parseInt( portValue );
|
||||
// portStringValue = portValue;
|
||||
// }
|
||||
// catch ( NumberFormatException nfe ) {
|
||||
// System.out.println( "Unexpected port value: " + portValue );
|
||||
// }
|
||||
//
|
||||
// System.out.println("Using port: " + portStringValue );
|
||||
// argument.setValue( portStringValue );
|
||||
// }
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#----------------------------------------
|
||||
# Ghidra Debug Thread Dumper launch
|
||||
#----------------------------------------
|
||||
# This script will only work if Ghidra is running in debug mode (i.e., launched from
|
||||
# ghidraDebug shell script).
|
||||
|
||||
# Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
|
||||
# the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed.
|
||||
MAXMEM=64M
|
||||
|
||||
# Resolve symbolic link if present and get the directory this script lives in.
|
||||
# NOTE: "readlink -f" is best but works on Linux only, "readlink" will only work if your PWD
|
||||
# contains the link you are calling (which is the best we can do on macOS), and the "echo" is the
|
||||
# fallback, which doesn't attempt to do anything with links.
|
||||
SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo "$0")"
|
||||
SCRIPT_DIR="${SCRIPT_FILE%/*}"
|
||||
|
||||
# Assumes application is utilizing debug port 18001 (change if needed)
|
||||
# NOTE: By default, ghidraDebug uses debug port 18001 and analyzeHeadless uses 13002
|
||||
|
||||
# Launch Thread Dumper
|
||||
"${SCRIPT_DIR}"/launch.sh fg ThreadDump "${MAXMEM}" "" util.DebugThreadDumper 18001
|
||||
|
||||
read -p "Press Enter to continue..."
|
|
@ -1,18 +0,0 @@
|
|||
:: Ghidra Debug Thread Dumper launch
|
||||
::
|
||||
:: This script will only work if Ghidra is running in debug mode (i.e., launched from
|
||||
:: ghidraDebug batch file or shell script).
|
||||
::
|
||||
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
:: maximum heap memory may be change if inadequate
|
||||
set MAXMEM=64M
|
||||
|
||||
:: Assumes application is utilizing debug port 18001 (change if needed)
|
||||
:: NOTE: By default, ghidraDebug uses debug port 18001 and analyzeHeadless uses 13002
|
||||
|
||||
call "%~dp0launch.bat" fg ThreadDump "%MAXMEM%" "" util.DebugThreadDumper 18001
|
||||
|
||||
pause
|
|
@ -17,7 +17,6 @@ Linux/server/svrUninstall||GHIDRA||||END|
|
|||
Linux/support/analyzeHeadless||GHIDRA||||END|
|
||||
Linux/support/buildGhidraJar||GHIDRA||||END|
|
||||
Linux/support/convertStorage||GHIDRA||||END|
|
||||
Linux/support/dumpGhidraThreads||GHIDRA||||END|
|
||||
Linux/support/ghidraDebug||GHIDRA||||END|
|
||||
Linux/support/launch.sh||GHIDRA||||END|
|
||||
Linux/support/pythonRun||GHIDRA||||END|
|
||||
|
@ -32,7 +31,6 @@ Windows/support/analyzeHeadless.bat||GHIDRA||||END|
|
|||
Windows/support/buildGhidraJar.bat||GHIDRA||||END|
|
||||
Windows/support/convertStorage.bat||GHIDRA||||END|
|
||||
Windows/support/createPdbXmlFiles.bat||GHIDRA||||END|
|
||||
Windows/support/dumpGhidraThreads.bat||GHIDRA||||END|
|
||||
Windows/support/ghidra.ico||GHIDRA||||END|
|
||||
Windows/support/ghidraDebug.bat||GHIDRA||||END|
|
||||
Windows/support/launch.bat||GHIDRA||||END|
|
||||
|
|
Loading…
Reference in a new issue