General protection fault in 64 bit mode
Posted: Thu Dec 17, 2015 9:57 am
I want to know how to find code address which occurs GPF, and how to use error code.
Currently I am making a x86 custom OS with C++.
Somedays ago, I added interrupt handler and enalbed interrupt.
However, general portection fault occures after interrupt is enabled.
So, I added some debugging code to find where the GPF generates.
When a GPF happens, this assembly code is executed.
The four parameters are passed to kCommonExceptionHandler.
They are the interrupt vector number, the error code, the RIP, and the CS.
The below code show how to print the values.
Then, the reults is
The code address for GPF can be found CS*0x10 + RIP, so 0x80FF150 is the address. However, when I dumped object of my custom OS, the last code address is 0x20367a.
What did I make a mistake? And in this case, how can I get an useful information from error code?
Currently I am making a x86 custom OS with C++.
Somedays ago, I added interrupt handler and enalbed interrupt.
However, general portection fault occures after interrupt is enabled.
So, I added some debugging code to find where the GPF generates.
When a GPF happens, this assembly code is executed.
Code: Select all
; #13, General Protection ISR
_kISRGeneralProtection:
KSAVECONTEXT ; Store the context and change selector to
; kernel data descriptor
; Insert exception number and error code to the hander and call the handler
mov rdi, 13
mov rsi, qword [rbp + 8]
mov rdx, qword [rbp + 16]
mov rcx, qword [rbp + 24]
call _kCommonExceptionHandler
KLOADCONTEXT ; Restore the context
add rsp, 8 ; Remove error code from stack
iretq ; Return the event point after interrupt
; handling
They are the interrupt vector number, the error code, the RIP, and the CS.
The below code show how to print the values.
Code: Select all
void kUtils::kPrintException(const char* pcVectorNumber,
const char* pcErrorCode,
const char* pcRIP,
const char* pcCS)
{
kPrintString(0, 0,
"===========================================================");
kPrintString(0, 1,
" Exception Occur ");
kPrintString(0, 2,
" Vector: ");
kPrintString(0, 3,
" Error Code: 0x ");
kPrintString(0, 4,
" RIP: 0x ");
kPrintString(0, 5,
" CS: 0x ");
kPrintString(0, 6,
"===========================================================");
kPrintString(26, 2, pcVectorNumber);
kPrintString(28, 3, pcErrorCode);
kPrintString(28, 4, pcRIP);
kPrintString(28, 5, pcCS);
return;
}
void kIH::kDecodeError(unsigned long qwCode, char* cMean)
{
unsigned long ulMask = 0xF;
unsigned long ulValue;
char c;
for (int i = 0; i < 16; i++)
{
ulValue = qwCode & ulMask;
if (ulValue > 9)
{
c = 'A' + ulValue - 10;
}
else
{
c = '0' + ulValue;
}
cMean[15 - i] = c;
qwCode = qwCode >> 4;
}
return;
}
// Common exception handler
void kIH::kCommonExceptionHandler(int iVectorNumber, unsigned long qwErrorCode, unsigned long qwRIP, unsigned long qwCS)
{
char cNumber[3] = { 0, };
char cErrorCode[17] = { 0, };
char cRIP[17] = {0, };
char cCS[17] = {0, };
// Print interrupt vector number as 2 digit number
cNumber[0] = '0' + iVectorNumber / 10;
cNumber[1] = '0' + iVectorNumber % 10;
kDecodeError(qwErrorCode, cErrorCode);
kDecodeError(qwRIP, cRIP);
kDecodeError(qwCS, cCS);
g_pclUtils->kPrintException(cNumber, cErrorCode, cRIP, cCS);
while (1);
}
Code: Select all
Vector: 13
Error Code: 0x000000000020139D
RIP: 0x00000000007FFFD0
CS: 0x000000000000FF18
What did I make a mistake? And in this case, how can I get an useful information from error code?