2011-08-26 2 views
2

Ces jours-ci j'ai trouvé un blog la fonction abort mentionné dans C.Est-ce que l'abandon est exécuté dans l'anneau 0?

Voici le code source de la fonction abort: http://cristi.indefero.net/p/uClibc-cristi/source/tree/0_9_14/libc/stdlib/abort.c

je trouve qu'il utilise l'instruction hlt (Mon PC est x86).

Mais semble que hlt doit fonctionner dans l'anneau 0. (se référer au wiki http://en.wikipedia.org/wiki/HLT)

Il semble que l'abandon est en cours d'exécution dans l'espace utilisateur. Donc, l'utilisation de l'instruction hlt dans l'abandon semble illégale.

BTW, j'essaie d'exécuter hlt sous Linux et Windows. Mais je rencontre une erreur.

Dans 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; 
} 

Sous Windows:

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

Répondre

6

La fonction abort utilise uniquement l'instruction hlt après l'envoi SIGABRT échoue. Si vous lisez le code source, la fonction essaie d'abord:

raise(SIGABRT); 

Et puis appelle l'instruction non valide:

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

Vous avez raison, hlt nécessite anneau 0 privilèges. C'est précisément ce qui en fait une instruction invalide. L'exécuter appellera un gestionnaire d'instruction invalide, ce qui est dans votre cas (je suppose) SIGSEGV.

3

Vous pouvez jeter un oeil à la si vous frappez un appel abort() pendant le débogage avec GDB signal Posix SIGABRT

par exemple, vous verrez:

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 

Comme @kbok Mentionné , le démontage de la fonction abort comprennent l'instruction hlt:

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

(mais il fait 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 
Questions connexes