最近在编译j2me的开源工程phoneme,编译出来的虚拟机在xp中运行良好,到了win7就出现问题。经过调试发现,虚拟机在开启jit的时候会把动态编译的代码放到堆中执行,而dep开启的情况下是不允许这么做的,这样就引发了access violation异常。xp默认是关闭dep的,这个问题也就一直没有发现。
dep全名就是data execution protection,即数据执行保护。在支持dep的cpu中,内存页表增加了一个NX(not execution)位,NX位置1的情况下这个页面的内容是不能被执行的,否则会发生异常。而jit就是把频繁使用的java代码动态编译成本地代码放在堆上执行,这就是问题的原因。
经过网上搜索,得知windows系统有四种dep配置:alwayson(永远开启),alwaysoff(永远关闭),optin(列表内开启),optout(列表内禁用),这四种配置具体有以下特点:
1.alwayson,无论程序本身有没有设置NX位,所有的程序都开启dep.
2. alwaysoff,无所程序本身有没有设置NX位,所有程序都禁用dep.
3. optin,仅为基本的系统服务和程序开启dep,对于非系统程序,根据程序的NX位来决定开启还是禁用。
4. optout,列表内的程序禁用,表外的开启。根据我的使用经历发现,列表内的程序也只能是没有设置NX位的程序,设置了就加不进来了。
在win7下,我们可以使用 计算机-属性-高级系统设置-性能-数据执行保护 进行optin和optout配置选项的配置,默认是optin配置,而对于alwayson和alwaysoff配置选项就只能用命令来设置了,命令如下:
bcdedit /set nx alwayson或者bcdedit /set nx alwaysoff。
上面提到程序本身的NX位置,查看windows的PE文件格式可以知道,文件头有个IMAGE_DLLCHARACTERISTICS_NX
如果不是自己的程序要修改起来也不难,想简单点就找个PE修改工具改改,要代码实现那就得自己去熟悉PE格式了。