|
|
1
15
最佳实践是让VM在执行之前执行一次检查, 成本与程序的大小成比例,这是非常复杂的,足以保证在执行过程中不会发生任何不稳定的事情。然后在字节码的实际执行过程中,运行时不进行任何检查。 然而,运行前检查的想法可能需要一些非常复杂的分析,即使是最注重性能的vm也常常需要这样做 一些 运行时检查(例如:数组边界)。 对于一个爱好项目,我会保持简单,每次执行指令时都让VM检查是否正常。大多数指令的开销不会太大。 |
|
2
2
同样的问题也出现在Java中,我记得,在这种情况下,VM必须进行一些检查,以确保字节码格式良好。在这种情况下,这实际上是一个严重的问题,因为存在潜在的安全问题:如果有人可以更改Java字节码文件,使其包含编译器永远不会输出的内容(例如访问
现在,在你的情况下,除非你的自制语言开始流行起来,否则安全方面你不必太担心;毕竟,除了你,谁会入侵你的程序?不过,我想说的是,在字节码无效的情况下,确保VM至少有一个合理的失败策略是一个好主意。至少,如果它遇到一些它不理解并且无法处理的东西,它应该检测到这些东西并失败,并显示一条错误消息,这将使您的调试更加容易。 |
|
|
3
2
然而,这听起来像是在实现一个处理器,而且由于它们的级别往往较低,所以要使事物处于可检测的无效状态的方法就更少了——给它一个未定义的操作码是一个明显的方法。真正的处理器将发出信号,表示进程试图执行非法指令,操作系统将对此进行处理(例如,Linux使用SIGILL杀死它) |
|
|
4
1
如果您担心有人编辑了二进制文件,那么您的问题只有一个答案:VM必须进行检查。这是你唯一有机会发现篡改的方法。编译器只是创建二进制文件。它无法检测下游篡改。 |
|
5
0
让编译器做尽可能多的健全性检查是有意义的(因为它只需要做一次),但是总有一些问题是静态分析无法检测到的,比如[cough]堆栈溢出、数组范围错误等等。 |
|
|
6
0
我想说,只要虚拟机实现本身不崩溃,虚拟机让模拟处理器着火是合法的。作为虚拟机实现者,您需要设置规则。但是,如果你想让虚拟硬件公司虚拟地购买你的虚拟芯片,你必须做一些更能原谅错误的事情:好的选择可能是引发异常(更难实现)或重置处理器(更容易实现)。或者,您只需将每个操作码定义为有效的,但有些操作码是“未记录的”——它们执行一些未指定的操作,而不是使实现崩溃。理由:如果(!)您的虚拟机实现是同时运行多个客户机实例,如果一个客户机能够导致其他客户机失败,那将是非常糟糕的。 |