exceptions are not being caught

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Andrew

Re:exceptions are not being caught

Post by Andrew »

at last i made my exceptions work, but still there is a mistake.
if in main code i do this

Code: Select all

  __asm__("int $0");
  Main.S.printf("booom");
then computer catches the exception and draws that string. but if i am doing this :

Code: Select all

  int a;
  int b;
  a = 0;
  b = 1;
  b = 1/a;
  Main.S.printf("booom");
then i get infinity exception handling. ??? why is that
and how could i change this.

exception handling code looks like this:

Code: Select all

[extern _int0]
[global _isr0]
_isr0:
  pusha
  push gs
  push fs
  push ds
  push es
  mov ax, 10h
  mov ds, ax
  mov es, ax
   cld
   call _int0      ;i call the function that prints the info about exception

  pop es
  pop ds
  pop fs
  pop gs
  popa
 iret
thank you in advance.
Adek336

Re:exceptions are not being caught

Post by Adek336 »

That's not a mistake. If your code does not halt the computer after catching an exception, and it doesnot, control is returned to program, to the place stated by EIP in stack.

There is a difference: after an INT, the EIP-on-stack points to the next instruction to be handled. So asm("int $0") is executed once.

After a faulty opcode, like x = x / 0, the EIP-on-stack does not point to the next instruction; it points to the faulty one, so returning to it causes the exception to rehappen.

You could 1) halt comp after exception, 2) try to see if it is caused by INT of a fault, 3) if caused by fault try to understand the opcode and change EIP-on-stack.

Hope this helps,
Adrian.
Andrew

Re:exceptions are not being caught

Post by Andrew »

i see your point. but could you tell me how to obtain operation code of that operation that raised exception in this procedure let's say:

Code: Select all

[extern _int0]
[global _isr0]
_isr0:
  pusha
  push gs
  push fs
  push ds
  push es

   mov eax, cr2
   push eax
   call _int0      ;Divide Error
   pop eax

  pop es
  pop ds
  pop fs
  pop gs
  popa
 iret
Adek336

Re:exceptions are not being caught

Post by Adek336 »

EIP is on top of the stack at the beginning of the ISR.

Code: Select all

ISR:
pop eax   ;now in eax EIP
or

Code: Select all

ISR:
pusha
push gs
push fs
push es
push ds
mov eax, [esp+0x30] ; now in eax EIP
You can push the value so that the C func gets it.

EIP points at the instruction, the EIP-on-stack will point at the faulting instruction:

Code: Select all

void int0(uint32 *_eip)
 {
printf("This is where the fault occurred: %d, this is the faulty opcode: %d", _eip, *_eip);
...
Andrew

Re:exceptions are not being caught

Post by Andrew »

one more question, i hope the last one.
where could i find the information about operation codes and length of the commands.
i have such information about the 8086 commands
for example:
000 trm __ ADD rm8 r8
............
207 trm __ XCHG r16 rm16
and so on ...

P.S.
if someone answered me i am 100 % sure that topic will be closed and i won't bother you with exceptions. :)
at least hope so ;D
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:exceptions are not being caught

Post by Solar »

Volume 2 of the Intel manuals (Instruction Set Reference).
Every good solution is obvious once you've found it.
Andrew

Re:exceptions are not being caught

Post by Andrew »

hm, wierd.
why when i call __asm__("int $1"); or __asm__("int $0");
i get the same value of operation code value : 0x83
and it is not equal to non of the listed in intel documentation : CC, CD(i think that i should get this) or CE.
but when exception is caught here:

Code: Select all

int a; int b; a=0; b=1; b = 1/a;

i get F7, which tells me that operation was DIV.

So, is there smth i should know about detecting if it was __asm__("int #"); ?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:exceptions are not being caught

Post by Pype.Clicker »

hey, hey ... remember that IP value saved on the stack by int n instruction is the value of the *next* instruction, while the IP value saved on the stack because of a fault is the address of the faulty instruction ...

btw, why do you want to generate "int 0" manually ? this makes no sense, and will usually lead to flaws for other exceptions that require an error code (provided by the CPU) ... and you should rather set your IDT descriptors so that user code is not allowed to call exception or hardware interrupts manually.
Andrew

Re:exceptions are not being caught

Post by Andrew »

Pype.Clicker wrote: and you should rather set your IDT descriptors so that user code is not allowed to call exception or hardware interrupts manually.
::) and how it is possible to do that?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:exceptions are not being caught

Post by Pype.Clicker »

run user-level code at DPL3 and set the "DPL" field of the interrupt gates at level 0. Any attempt from user-level code to call an exception handler will result in a GPF exception with the interrupt descriptor as error code.
Andrew

Re:exceptions are not being caught

Post by Andrew »

thanks, i'll try to do that. but i faced another problem

Code: Select all

void Int::initInterrupts(){
   __asm__("cli \t\n"); 
   disableNMI();

   remapPIC(0x20, 0x28);    
   maskIRQ(ALL);

   loadExceptions();
    //our hardware interrupts IRQ
      createInt(32, isr32, 0);
      createInt(38, isr38, 0);

    //--------------
/****** ERROR********/
   unmaskIRQ(0); /// general exception error ???
    unmaskIRQ(6);
    loadIDT();
   enableNMI();
   __asm__("sti \t\n");
}

void Int::maskIRQ(__u8 irq){
   if(irq == 0xff){
      BITMAP2 = BITMAP1 = 0xff;      
      __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP1),"d"(PIC1_DATA));
      __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP2),"d"(PIC2_DATA));
   }else{
          if(irq >= 8){ // slave
             BITMAP2 = BITMAP2 + (1 << (irq-8));            
            __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP2), "d"(PIC2_DATA));
         }else{ // master                 
               BITMAP1 = BITMAP1 + (1 << irq);               
               __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP1), "d"(PIC1_DATA));
             }
       }
}

void Int::unmaskIRQ(__u8 irq){
   if(irq == 0xff){
      BITMAP2 = BITMAP1 = 0x00;      
      __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP1),"d"(PIC1_DATA));
      __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP2),"d"(PIC2_DATA));
   }else{
          if(irq >= 8){ // slave            
               //inverse
               BITMAP2 = BITMAP2 - (1 << (irq-8));
               __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP2), "d"(PIC2_DATA));
            }else{ // master                 
               BITMAP1 = BITMAP1 - (1 << irq);                  
               __asm__("outb %%al, %%dx \t\n"::"a"(BITMAP1), "d"(PIC1_DATA));
             }
       }
}

void Int::loadExceptions(){
   createInt(0, isr0, 0);
                  //..................
   createInt(16, isr16, 0);
}
i can't understand why i get general protection error in that line? maybe it is because my IRQ handlers are with the same settings as exceptions?
i am lost ???
Andrew

Re:exceptions are not being caught

Post by Andrew »

i foound out that i get general exception error only trying to unmask IRQ0. if comment unmaskIRQ(0); and leave unmaskIRQ(6) everything is fine.
i thought that it is maybe because of mine timer initialization procedure but i commented that procedure and got the same general protection exception while trying to unmask IRQ0 :(

Code: Select all

createInt(32, isr32, 0);   //IRQ0
void Int::createInt(int num, void (*proc)(), __u16 set){
   __u32 address = (__u32)proc;
   IDT[num].low_offset = address & 0xFFFF;
   IDT[num].selector = 0x8;
   IDT[num].settings = (set==0x8e00)?set:( (set==0xae00)?set:( (set==0xce00)?set:0x8e00 ) );
   IDT[num].high_offset = (address & 0xFFFF0000) >> 16;
}

// isr.asm
[extern _TimerIRQ] 
[global _isr32]
_isr32:
  pusha
  push gs
  push fs
  push ds
  push es
  push ax
   call _TimerIRQ     ;testing;
  push ax
  pop es
  pop ds
  pop fs
  pop gs
  popa
iret

extern "C" void TimerIRQ(){  
  Floppy::TickCounter++;    // this is for my floppy 
  __asm__("outb %%al, %%dx \t\n"::"a"(EOI), "d"(PIC1));
}
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:exceptions are not being caught

Post by Pype.Clicker »

Code: Select all

push ax
call _timer
push ax
what's that for a weird code ? what are you trying to do with AX ? Why pushing something for a function that takes no parameter ? and why the hell pushing the return value of a void function before popping segments ?

Are you aware that what you'll pop into es,fs,gs, etc. will *not* be what you pushed earlier on the stack, but that there are chances that it will just be garbage or that your handler will invert some values ? ...
Andrew

Re:exceptions are not being caught

Post by Andrew »

Pype.Clicker wrote:

Code: Select all

push ax
call _timer
push ax
what's that for a weird code ? what are you trying to do with AX ? Why pushing something for a function that takes no parameter ? and why the hell pushing the return value of a void function before popping segments ?
i have no idea why i am doing this .... d*amn. now i removed those nasty push ax statements, so now i am pushing segments and poping them back.
and now unmaskIRQ(0); doesn't generate any error.

thank you.

<pype> i moved your other question into a new fresh post as it starts drifting away from the initial problem ...</pype>
Post Reply