我目前正在用C/C++編寫一個小型VM。顯然我不能讓整個虛擬機崩潰,如果用戶解引用空指針,所以我必須檢查每個訪問越來越繁瑣,隨着虛擬機增長和更多的系統實現。signal.h是捕獲空指針的可靠方法嗎?
所以我有一個想法:寫SIGSEGV的信號處理程序,並讓OS做它的事,但不要關程序調用VM異常處理程序。
它似乎工作(與我非常簡單的測試用例),但我沒有發現任何保證null-derefs引發的sigsegv,也沒有調用操作系統生成的信號處理程序。
所以我的問題是: 我可以指望現代destkop操作系統上的signal.h(我真的不在乎它是否不符合linux/win以外的標準):這是一個寵物項目) 。是否有任何不平凡的東西,我應該知道的
謝謝(信號(...)或longjmp的(...)?晦澀的限制)!
這裏是僞實現:
/* ... */
jmp_buf env;
/* ... */
void handler(int) {
longjmp(env, VM_NULLPTR);
}
/* ... */
if(setjmp(env)) {
return vm_throw("NullPtrException");
}
switch(opcode) {
/* instructions */
case INVOKE:
*stack_top = vm_call(stack_top->obj); // don't check anything in the case where stack_top or stack_top->obj is null handler() will be called an a "NullPtrException" will be thrown
break;
/* more instructions */
}
/* ... */
注:我只需要檢查空值,垃圾(懸掛)的指針由GC處理,並且不應該發生。
除了取消引用空指針外,代碼還可以解引用垃圾指針或任何其他類型的無效指針。這不一定會產生一個信號。因此,您無法驗證每個指針訪問權限。 –
如果您將指針解引用操作傳遞給主機操作系統,那不是虛擬機。充其量,它是一個模擬包裝(儘管不告訴WINE它就是這樣!)。 –
@Sam Varshavchik:這就是爲什麼最後一個音符在那裏:垃圾不應該發生:永遠。 –