连接
/**参数:
* mainArgs为目标程序main函数所在的类
**/
VirtualMachine launchTarget(String mainArgs) {
//findLaunchingConnector:获取连接
LaunchingConnector connector = findLaunchingConnector();
//connectorArguments:设置连接参数
Map arguments = connectorArguments(connector, mainArgs);
try {
return connector.launch(arguments);//启动连接
} catch (IOException exc) {
throw new Error("Unable to launch target VM: " + exc);
} catch (IllegalConnectorArgumentsException exc) {
throw new Error("Internal error: " + exc);
} catch (VMStartException exc) {
throw new Error("Target VM failed to initialize: " + exc.getMessage());
}
}
清单 1 和清单 2 分别获取连接实例和启动所需的变量,通过调用 connector.launch(arguments) 启动连接,实现了分析器和目标程序的绑定。
注册事件
分析器和目标程序之间采用基于事件的模式进行通信。分析器向虚拟机实例 注册所关注的事件。事件发生时,虚拟机将相关事件信息放入事件队列中,采用 生产者 - 消费者 的模式与分析器同步。
注册事件
EventRequestManager 管理事件请求,它支持创建、删除和查询事件请求。 EventRequest 支持三种挂起策略:
EventRequest.SUSPEND_ALL : 事件发生时,挂起所有线程
EventRequest.SUSPEND_EVENT_THREAD : 事件发生时,挂起事件源线程
EventRequest.SUSPEND_NONE : 事件发生时,不挂起任何线程
使用Java Debug Interface(JDI)调试多线程应用程序(4)
时间:2010-12-19 IBM 钱毅 蔡小川
JDI 支持多种类型的 EventRequest,如 ExceptionRequest, MethodEntryRequest,MethodExitRequest,ThreadStartRequest 等,可以参考 文档。
清单 4. 注册事件
EventRequestManager mgr = vm.eventRequestManager();
// 注册异常事件
ExceptionRequest excReq = mgr.createExceptionRequest(null, true, true);
excReq.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
excReq.enable();
// 注册进方法事件
MethodEntryRequest menr = mgr.createMethodEntryRequest();
menr.setSuspendPolicy(EventRequest.SUSPEND_NONE);
menr.enable();
// 注册出方法事件
MethodExitRequest mexr = mgr.createMethodExitRequest();
mexr.setSuspendPolicy(EventRequest.SUSPEND_NONE);
mexr.enable();
// 注册线程启动事件
ThreadStartRequest tsr = mgr.createThreadStartRequest();
tsr.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
tsr.enable();
// 注册线程结束事件
ThreadDeathRequest tdr = mgr.createThreadDeathRequest();
tdr.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
tdr.enable();
分析器从事件队列中获取事件
EventQueue 用来管理目标虚拟机实例的事件,事件会被加入 EventQueue 中 。分析器调用 EventQueue.remove(),如果事件队列中存在事件,则返回不可修 改的 EventSet 实例,否则分析器会被挂起直到有新的事件发生。处理完 EventSet 中的事件后,调用其 resume() 方法唤醒 EventSet 中所有事件发生 时可能挂起的线程。
清单 5. 获取事件
public void run() {
EventQueue queue = vm.eventQueue();
while (connected) {
try {
EventSet eventSet = queue.remove();
EventIterator it = eventSet.eventIter
|