Прерывание работает в кольце 0? - PullRequest
2 голосов
/ 26 августа 2011

В эти дни я обнаружил в блоге упомянутую функцию прерывания в C.

Ниже приведен исходный код функции прерывания: http://cristi.indefero.net/p/uClibc-cristi/source/tree/0_9_14/libc/stdlib/abort.c

Я обнаружил, что она использует hltинструкция (Мой компьютер x86).

Но кажется, что hlt должен работать в кольце 0. (см. вики http://en.wikipedia.org/wiki/HLT)

Кажется, что прерывание выполняется в пространстве пользователяТаким образом, использование инструкции hlt в abort кажется незаконным.

Кстати, я пытаюсь запустить hlt в Linux и Windows. Но я сталкиваюсь с ошибкой.

В Linux:

#include <iostream>
using namespace std;

#define HLT_INST asm("hlt")

int main(){
  cout<<"whill run halt"<<endl;

  HLT_INST; //result in SIGSEGV error
  return 0;
}

В Windows:

cout<<"will run hlg"<<endl;
/*Unhandled exception at 0x0040101d in test_learn.exe: 0xC0000096: Privileged instruction.
*/
__asm{
    hlt;
}

Ответы [ 2 ]

6 голосов
/ 26 августа 2011

Функция abort использует инструкцию hlt только после сбоя при отправке SIGABRT.Если вы читаете исходный код, функция сначала пытается:

raise(SIGABRT);

, а затем вызывает недопустимую инструкцию:

/* Still here?  Try to suicide with an illegal instruction */
if (been_there_done_that == 2) {
    been_there_done_that++;
    ABORT_INSTRUCTION;
}

Итак, вы правы, hlt требует привилегий вызова 0,Это именно то, что делает его неверной инструкцией.Выполнение этого вызовет обработчик неверной инструкции, который в вашем случае (я полагаю) SIGSEGV.

3 голосов
/ 26 августа 2011

Возможно, вы захотите взглянуть на сигнал SIGABRT POSIX

Например,

, если вы нажмете на abort() вызов во время отладки с помощью GDB, вы увидите:

Program received signal SIGABRT, Aborted.
0x0000003c47e352d5 in raise () from /lib64/libc.so.6
(gdb) where
#0  0x0000003c47e352d5 in raise () from /lib64/libc.so.6
#1  0x0000003c47e36beb in abort () from /lib64/libc.so.6
#2  0x0000000000400721 in main (argc=1, argv=0x7fffffffde18) at test.c:27

Как упомянул @kbok, разборка функции abort включает инструкцию hlt:

(gdb)  disassemble abort
Dump of assembler code for function abort:
...
0x0000003c47e36b08 <+152>:  hlt
...

(но это так SEGFAULT indeed)

(gdb) break *0x0000003c47e36b08
Breakpoint 2 at 0x3c47e36b08
(gdb) jump *0x0000003c47e36b08
Breakpoint 2, 0x0000003c47e36b08 in abort () from /lib64/libc.so.6
(gdb) next
Single stepping until exit from function abort,which has no line number information.
Program received signal SIGSEGV, Segmentation fault.
0x0000003c47e36b08 in abort () from /lib64/libc.so.6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...