Eclipse调试框架的学习与理解二

三、断点的管理

要支持调试,断点的支持是不可少的。Eclipse里,断点通常是显示在Editor的左边的ruler上。可以通过双击增加和删除。断点类需要自己提供,一般每个断点都会含有一个对应的Marker,用来记录这个断点,这样在Editor下次再打开的时候断点还能存在。

 

断点的追加、删除等等操作,都是通过断点管理器来实现的。可以通过以下方式得到断点管理器:

DebugPlugin.getDefault().getBreakpointManager(); 

四、事件交互

调试时的事件交互一般是通过Socket连接来完成,而且一般有两个连接:一个是发送命令用的Socket;另一个是接收事件用的Socket

 

理解起来就是这样的:由UI端发出的并等待返回的连接都由一个Socket来执行;由后台自动发出的事件由另一个Socket连接来完成。所谓后台自动发出,是指不需要UI端参与的、UI端未知的事件,例如运行到了某处,终止等等。

 

一般来说,所有的调试动作或者是对断点的操作,都是由事件交互来完成的,例如单步跳过,可能需要发送一个“stepOver”,然后由后台执行完这个操作,再把结果返回;

 

这里有一点需要介绍清楚。

 

我们通过发送命令的端口发出命令,并得到返回,这个返回结果只是用来修改我们的模型对象(也就是堆栈中的各个结点对象),事实上此时堆栈本身并不会更改,之前我们说堆栈的形成是Eclipse自动调用那些get**s()方法而产生的。这有点不准确,其实也是事件驱动而产生的,只是这个事件不是由我们从UI上发出的,而是后台自动发出的。例如:

 

我们发出一个“stepOver”命令,然后得到一个返回,这个返回结果然后就更新了模型,不过这个模型现在还没有立即更新树;在后台给我们返回结果的同时,它又通过那个事件端口发出一个事件,例如一个“stepOver”字符串。

 

然后我们得到这个字符串,再发出一个Eclipse事件:DebugEvent.STEP_OVER然后就会驱使堆栈树的更新。

 

也有可能UI端发出“stepOver”命令,从后台返回的事件不是一个“stepOver”事件,例如没有断点的时候应该就是终止了。UI端只是发出命令,它不知道这个命令发出后具体执行情况,这也就为什么需要由后台来决定具体的事情类型的原因。

 

这里出现DebugEvent.STEP_OVER可能有点莫名。不过我们只要理解在Eclipse调试里,要想更改堆栈树的显示、Variable的结果,我们就需要发出一个事件,这些事件已经在DebugEvent对象里定义好了,如下:

static int

BREAKPOINT
          Breakpoint detail.

static int

CHANGE
          Change event kind.

static int

CLIENT_REQUEST
          Client request detail.

static int

CONTENT
          Content change detail.

static int

CREATE
          Create event kind.

static int

EVALUATION
          Evaluation detail.

static int

EVALUATION_IMPLICIT
          Evaluation detail.

static int

MODEL_SPECIFIC
          Model specific event kind.

static int

RESUME
          Resume event kind.

static int

STATE
          State change detail.

static int

STEP_END
          Step end detail.

static int

STEP_INTO
          Step start detail.

static int

STEP_OVER
          Step start detail.

static int

STEP_RETURN
          Step start detail.

static int

SUSPEND
          Suspend event kind.

static int

TERMINATE
          Terminate event kind.

static int

UNSPECIFIED

 

发出事件是由DebugElement里的fire**Event()方法来完成的。它定义了对应于各个事件类型的不同的发出事件方法。

五、源码查看的支持

           

我觉得源码查看和断点支持是所有其他操作的基础,否则使用Eclipse框架就失去了意义了。

 

要支持源码查看,我们需要完成几件。

我们先回到org.eclipse.debug.core.launchConfigurationTypes扩展点。之前launch的实现中有两个属性没有涉及:sourceLocatorIdsourcePathComputerId

 

要支持源码查看,我们就需要把这两个属性填上。sourceLocatorId对应于一个org.eclipse.debug.core.sourceLocators实现的IDsourcePathComputerId对应于一个org.eclipse.debug.core.sourcePathComputers实现的ID

所以显然,我们也应该实现扩展点:org.eclipse.debug.core.sourceLocatorsorg.eclipse.debug.core.sourcePathComputers

分别用来定义查找的文件名,和查找到文件所在的容器。具体到哪一行我们不需要提供。因为我们在StackFrame实现里有一个返回当前行的方法,Eclipse会自动高亮到对应的行。

六、自定义变量的显示方式

Variable视图有两层。所谓的显示方式,是指在Variables视图上,当我们在上层选择一个变量的时候,会在下层也显示这个变量的内容。这里的自定义就是定义下层的显示方式。   

 

要定义上层的显示方式,我们需要扩展一个扩展点:

org.eclipse.debug.core.logicalStructureTypes

 

 

            要定义下层的显示方式,需要扩展:org.eclipse.debug.ui.detailsPaneFactories.

我们要知道下面那个显示面板在Eclipse里被称为detailsPane。所以我们实际上,需要再自己写一个DetailsPane的实现类,用以提供显示。

 

扩展以上两个扩展点,定义自己的实现即可。

 

但是扩展的时候我们就会发现,它需要指一个“modelIdentifier”,这样一个属性,这个属性值需要指定为一个“org.eclipse.debug.ui.debugModelPresentations”扩展点的ID,这个“org.eclipse.debug.ui.debugModelPresentations”扩展点,在上面我们提到过,可以用于自定义堆栈的显示,例如imagelabel等。

 

等等,我们先理清一下思路:

 

1.      我们要实现自己的显示堆栈的方式,我们需要扩展:org.eclipse.debug.ui.debugModelPresentations

 

2.      我们要实现自己的显示Variable的方式,我们需要扩展:org.eclipse.debug.core.logicalStructureTypes和org.eclipse.debug.ui.detailsPaneFactories

  

3.      所有的东西都需要与org.eclipse.debug.ui.debugModelPresentations关联。这里所说的所有的东西包括:

 

      堆栈中的各个层级类型,这个关联是通过它们的父类DebugElementgetModelIdentifier()方法来决定的。我们想想为什么需要这个关联:

因为这样调试的时候,Eclipse才能找到对应的显示方式,要不只能用缺省的了。

      org.eclipse.debug.core.logicalStructureTypes扩展中需要指定“modelIdentifier”的值,这就表示当前的扩展用在这个调试模型上。

 

OK,这样我们就完成了自定义变量的显示方式。

 

七、其他事项

1.      多线程问题

我们要注意多线程的竞争问题,例如发送命令时,应该保证Socket一次只被一个线程使用。等等。

2.      启动和加断点

运行的情况下无所谓,启动即可运行。但是在调试的时候,我们必须有一种保证在运行前能设置社始断点的方法。否则可能在断点追加之前就已经运行完了。

3.      事件顺序

我们可以加多个事件,这些事件在socket中排队发送,因为可能会有顺序的问题,我们应该保证顺序的正确性。

4.      其他问题

再想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值