현재 C/C++에서 작은 VM을 작성 중입니다. 분명히 사용자가 null 포인터를 역 참조하는 경우 전체 VM 충돌을 허용 할 수 없기 때문에 VM이 커지고 더 많은 시스템이 구현됨에 따라 성가신되고있는 모든 액세스를 확인해야합니다.signal.h는 널 포인터를 잡을 수있는 확실한 방법입니까?
그래서 나는 생각했다 : sigsegv에 대한 신호 처리기를 작성하고 운영 체제가 그 일을하지만 프로그램을 종료하는 대신 VM 예외 처리기를 호출하게하십시오.
(내 아주 간단한 테스트 케이스로) 작동하는 것처럼 보이지만, null-derefs에 던져지는 Sigsegv 나 OS 생성 신호에 대해 호출되는 핸들러를 보장하지 못했습니다.
내 질문은 :현대 destkop OSH에서 signal.h를 믿을 수 있습니까 (표준이 아닌 경우 linux/win 이외의 다른 제품에서 작동하지 않아도 상관하지 않음 : pet 프로젝트 임) . 신호 (...) 또는 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에 의해 처리됩니다 널 (null)를 확인해야하고 일이 안된다.
null 포인터를 역 참조하는 것 외에도 코드는 가비지 포인터 또는 다른 종류의 잘못된 포인터를 역 참조 할 수도 있습니다. 반드시 신호를 생성하지는 않습니다. 따라서 모든 포인터 액세스의 유효성을 검증 할 수있는 대안은 없습니다. –
포인터 디 레퍼런스를 호스트 OS에 전달하는 경우 VM이 아닙니다. 기껏해야 에뮬레이션 래퍼입니다 (하지만 와인은 그게 무엇인지 알려주지 않습니다!). –
@Sam Varshavchik : 이것이 바로 마지막 메모가있는 이유입니다. 쓰레기는 절대 일어나지 않아야합니다. –