java Trace -output log.txt MainClass argsLaunchingConnector connector = Bootstrap.virtualMachineManager()
.allConnectors().stream()
.filter(c -> "com.sun.jdi.CommandLineLaunch".equals(c.name()))
.findFirst().orElseThrow();
Map args = connector.defaultArguments();
args.get("main").setValue(mainClassWithArgs);
VirtualMachine vm = connector.launch(args);
EventRequestManager mgr = vm.eventRequestManager();
// 異常事件
ExceptionRequest er = mgr.createExceptionRequest(null, true, true);
er.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
er.enable();
// 方法進出
mgr.createMethodEntryRequest().setSuspendPolicy(SUSPEND_NONE).enable();
mgr.createMethodExitRequest().setSuspendPolicy(SUSPEND_NONE).enable();
// 線程生命週期
mgr.createThreadStartRequest().setSuspendPolicy(SUSPEND_EVENT_THREAD).enable();
mgr.createThreadDeathRequest().setSuspendPolicy(SUSPEND_EVENT_THREAD).enable();
EventQueue queue = vm.eventQueue();
while (connected) {
EventSet set = queue.remove();
for (Event event : set) {
dispatch(event); // 分發到具體處理器
}
set.resume(); // 恢復被掛起線程
}
方法參數與局部變量:
StackFrame frame = thread.frame(0); // 當前幀
List vars = frame.visibleVariables();
for (LocalVariable v : vars) {
Value value = frame.getValue(v);
log(v.name() + "=" + value);
}
異常時全棧快照:
List frames = thread.frames();
for (StackFrame f : frames) {
if (f.thisObject() != null) {
// 實例字段
for (Field field : f.thisObject().referenceType().allFields()) {
log(field.name() + "=" + f.thisObject().getValue(field));
}
}
// 局部變量
for (LocalVariable v : f.visibleVariables()) {
log(v.name() + "=" + f.getValue(v));
}
}
Trace:入口類,啟動綁定EventThread:消費事件隊列,維護 ThreadReference → ThreadTrace 映射ThreadTrace:單線程追蹤器,緩存該線程所有日誌,最後整體輸出優勢:日誌按線程聚合,還原真實執行邏輯,避免多線程交織干擾。
# ExceptionConfig.properties
ExceptionName=exceptions.UserDefinedException;java.lang.NullPointerException
# ClassExcludeConfig.properties
ExcludedClassPattern=java.*;javax.*;sun.*;com.sun.*;com.ibm.*
目標程序:主線程拋兩類異常 + 兩個計數器線程並發更新。
日誌輸出片段:
====== main ======
Enter Method:main
Enter Method:<init> // MainThread 構造器
a=0 b=0 c=0
Exit Method:<init>
Enter Method:makeABusinessException
a=0 b=1 c=2
// UserDefinedException 異常,捕獲全棧變量
exceptions.UserDefinedException catch: MainThread:30
Frame(MainThread:44) a=0 b=1 c=2 i=0 d=4
Frame(MainThread:23) e=4 g=5 mt=MainThread@... i=0
====== Thread-1 ======
Enter Method:run
name="thread1" index=0
Enter Method:updateIndex // 3 次調用清晰可見
name="thread1" index=0
Exit Method:updateIndex
...
====== Thread-2 ======
...
SUSPEND_ALL 會嚴重影響性能,生產環境慎用--add-modules jdk.jdi 或導出模組